From faf387ce0c01040fa92f568d9fff484b655ee554 Mon Sep 17 00:00:00 2001 From: Boris Grozev <boris@jitsi.org> Date: Thu, 13 Mar 2014 19:21:23 +0100 Subject: [PATCH] Filters RTP packets in accord with the MediaStream direction. Fixes problems with new ReceiveStream-s being created while on hold. --- .../impl/neomedia/AbstractRTPConnector.java | 60 +++++++++++++++++++ .../jitsi/impl/neomedia/MediaStreamImpl.java | 7 +++ .../neomedia/RTPConnectorInputStream.java | 24 +++++++- .../neomedia/RTPConnectorOutputStream.java | 27 +++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/src/org/jitsi/impl/neomedia/AbstractRTPConnector.java b/src/org/jitsi/impl/neomedia/AbstractRTPConnector.java index 86b254eb..b2dc565c 100755 --- a/src/org/jitsi/impl/neomedia/AbstractRTPConnector.java +++ b/src/org/jitsi/impl/neomedia/AbstractRTPConnector.java @@ -12,6 +12,7 @@ import javax.media.rtp.*; import org.jitsi.service.neomedia.*; +import org.jitsi.util.*; /** * Provides a base/default implementation of <tt>RTPConnector</tt> which has @@ -20,10 +21,18 @@ * * @author Bing SU (nova.su@gmail.com) * @author Lyubomir Marinov + * @author Boris Grozev */ public abstract class AbstractRTPConnector implements RTPConnector { + /** + * The <tt>Logger</tt> used by the <tt>AbstractRTPConnector</tt> class + * and its instances to print debug information. + */ + private static final Logger logger + = Logger.getLogger(AbstractRTPConnector.class); + /** * The pair of datagram sockets for RTP and RTCP traffic that this instance * uses in the form of a <tt>StreamConnector</tt>. @@ -412,4 +421,55 @@ public void setSendBufferSize(int size) { // Nothing should be done here :-) } + + /** + * Configures this <tt>AbstractRTPConnector</tt> to allow RTP in the + * specified direction. That is, enables/disables the input and output data + * streams according to <tt>direction</tt>. + * + * Note that the control (RTCP) streams are not affected (they are always + * kept enabled). + * + * @param direction Specifies how to configure the data streams of this + * <tt>AbstractRTPConnector</tt>. The input stream will be enabled or + * disabled depending on whether <tt>direction</tt> allows receiving. The + * output stream will be enabled or disabled depending on whether + * <tt>direction</tt> allows sending. + */ + public void setDirection(MediaDirection direction) + { + boolean receive = direction.allowsReceiving(); + boolean send = direction.allowsSending(); + + if (logger.isDebugEnabled()) + logger.debug("setDirection " + direction); + + try + { + // forcing the stream to be created causes problems + RTPConnectorInputStream dataInputStream = getDataInputStream(false); + if(dataInputStream != null) + dataInputStream.setEnabled(receive); + } + catch (IOException ioe) + { + logger.error("Failed to " + (receive ? "enable" : "disable") + + " data input stream."); + } + + try + { + // forcing the stream to be created causes problems + RTPConnectorOutputStream dataOutputStream + = getDataOutputStream(false); + if (dataOutputStream != null) + dataOutputStream.setEnabled(send); + } + catch (IOException ioe) + { + logger.error("Failed to " + (send ? "enable" : "disable") + + " data output stream."); + + } + } } diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java index ddb4dbff..0329dd8d 100644 --- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java +++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java @@ -1806,6 +1806,13 @@ public void setDirection(MediaDirection direction) } if (started) start(this.direction); + + // make sure that RTP is filtered in accord with the direction of this + // MediaStream, so that we don't have to worry about, for example, + // new ReceiveStream-s being created while in sendonly/inactive. + AbstractRTPConnector connector = getRTPConnector(); + if (connector != null) + connector.setDirection(direction); } /** diff --git a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java index 501162f6..1a6d19a6 100755 --- a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java +++ b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java @@ -114,6 +114,12 @@ public abstract class RTPConnectorInputStream */ private SourceTransferHandler transferHandler; + /** + * Whether this <tt>RTPConnectorInputStream</tt> is enabled or disabled. + * While disabled, the stream does not accept any packets. + */ + private boolean enabled = true; + /** * Initializes a new <tt>RTPConnectorInputStream</tt> which is to receive * packet data from a specific UDP socket. @@ -476,7 +482,9 @@ public void run() = getDatagramPacketFilters(); boolean accept; - if (datagramPacketFilters == null) + if (!enabled) + accept = false; + else if (datagramPacketFilters == null) accept = true; else { @@ -648,4 +656,18 @@ public synchronized void addDatagramPacketFilter( datagramPacketFilters = newDatagramPacketFilters; } } + + /** + * Enables or disables this <tt>RTPConnectorInputStream</tt>. + * While the stream is disabled, it does not accept any packets. + * + * @param enabled <tt>true</tt> to enable, <tt>false</tt> to disable. + */ + public void setEnabled(boolean enabled) + { + if (logger.isDebugEnabled()) + logger.debug("setEnabled: " + enabled); + + this.enabled = enabled; + } } diff --git a/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java b/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java index 24ca5dea..6ed59026 100755 --- a/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java +++ b/src/org/jitsi/impl/neomedia/RTPConnectorOutputStream.java @@ -80,6 +80,13 @@ public abstract class RTPConnectorOutputStream */ private long numberOfPackets = 0; + /** + * Whether this <tt>RTPConnectorOutputStream</tt> is enabled or disabled. + * While the stream is disabled, it suppresses actually sending any packets + * via {@link #send(RawPacket)}. + */ + private boolean enabled = true; + /** * Initializes a new <tt>RTPConnectorOutputStream</tt> which is to send * packet data out through a specific socket. @@ -363,6 +370,11 @@ public int write(byte[] buffer, int offset, int length) if (logger.isDebugEnabled() && targets.isEmpty()) logger.debug("Write called without targets!", new Throwable()); + // no need to handle the buffer at all, if we are disabled, but simulate + // a successful operation. + if (!enabled) + return length; + // get the array of RawPackets we need to send RawPacket[] pkts = createRawPacket(buffer, offset, length); boolean fail = false; @@ -630,4 +642,19 @@ public void write(RawPacket packet) while (true); } } + + /** + * Enables or disables this <tt>RTPConnectorOutputStream</tt>. + * While the stream is disabled, it suppresses actually sending any packets + * via {@link #send(RawPacket)}. + * + * @param enabled <tt>true</tt> to enable, <tt>false</tt> to disable. + */ + public void setEnabled(boolean enabled) + { + if (logger.isDebugEnabled()) + logger.debug("setEnabled: " + enabled); + + this.enabled = enabled; + } } -- GitLab