All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jitsi.impl.neomedia.AbstractRTPConnector Maven / Gradle / Ivy

Go to download

libjitsi is an advanced Java media library for secure real-time audio/video communication

The newest version!
/*
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jitsi.impl.neomedia;

import java.io.*;
import java.net.*;

import javax.media.rtp.*;

import org.jitsi.service.neomedia.*;
import org.jitsi.utils.logging.*;

/**
 * Provides a base/default implementation of RTPConnector which has
 * factory methods for its control and data input and output streams and has an
 * associated StreamConnector.
 *
 * @author Bing SU ([email protected])
 * @author Lyubomir Marinov
 * @author Boris Grozev
 */
public abstract class AbstractRTPConnector
    implements RTPConnector
{
    /**
     * The Logger used by the AbstractRTPConnector 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 StreamConnector.
     */
    protected final StreamConnector connector;

    /**
     * RTCP packet input stream used by RTPManager.
     */
    private RTPConnectorInputStream controlInputStream;

    /**
     * RTCP packet output stream used by RTPManager.
     */
    private RTPConnectorOutputStream controlOutputStream;

    /**
     * RTP packet input stream used by RTPManager.
     */
    private RTPConnectorInputStream dataInputStream;

    /**
     * RTP packet output stream used by RTPManager.
     */
    private RTPConnectorOutputStream dataOutputStream;

    /**
     * Initializes a new AbstractRTPConnector which is to use a given
     * pair of datagram sockets for RTP and RTCP traffic specified in the form
     * of a StreamConnector.
     *
     * @param connector the pair of datagram sockets for RTP and RTCP traffic
     * the new instance is to use
     */
    public AbstractRTPConnector(StreamConnector connector)
    {
        if (connector == null)
            throw new NullPointerException("connector");

        this.connector = connector;
    }

    /**
     * Add a stream target. A stream target is the destination address which
     * this RTP session will send its data to. For a single session, we can add
     * multiple SessionAddresses, and for each address, one copy of data will be
     * sent to.
     *
     * @param target Destination target address
     * @throws IOException if there was a socket-related error while adding the
     * specified target
     */
    public void addTarget(SessionAddress target)
        throws IOException
    {
        InetAddress controlAddress = target.getControlAddress();

        if (controlAddress != null)
        {
            getControlOutputStream().addTarget(
                    controlAddress,
                    target.getControlPort());
        }

        getDataOutputStream().addTarget(
                target.getDataAddress(),
                target.getDataPort());
    }

    /**
     * Closes all sockets, stream, and the StreamConnector that this
     * RTPConnector is using.
     */
    public void close()
    {
        if (dataOutputStream != null)
        {
            dataOutputStream.close();
            dataOutputStream = null;
        }
        if (controlOutputStream != null)
        {
            controlOutputStream.close();
            controlOutputStream = null;
        }
        if (dataInputStream != null)
        {
            dataInputStream.close();
            dataInputStream = null;
        }
        if (controlInputStream != null)
        {
            controlInputStream.close();
            controlInputStream = null;
        }

        connector.close();
    }

    /**
     * Creates the RTCP packet input stream to be used by RTPManager.
     *
     * @return a new RTCP packet input stream to be used by RTPManager
     * @throws IOException if an error occurs during the creation of the RTCP
     * packet input stream
     */
    protected abstract RTPConnectorInputStream createControlInputStream()
        throws IOException;

    /**
     * Creates the RTCP packet output stream to be used by RTPManager.
     *
     * @return a new RTCP packet output stream to be used by RTPManager
     * @throws IOException if an error occurs during the creation of the RTCP
     * packet output stream
     */
    protected abstract RTPConnectorOutputStream createControlOutputStream()
        throws IOException;

    /**
     * Creates the RTP packet input stream to be used by RTPManager.
     *
     * @return a new RTP packet input stream to be used by RTPManager
     * @throws IOException if an error occurs during the creation of the RTP
     * packet input stream
     */
    protected abstract RTPConnectorInputStream createDataInputStream()
        throws IOException;

    /**
     * Creates the RTP packet output stream to be used by RTPManager.
     *
     * @return a new RTP packet output stream to be used by RTPManager
     * @throws IOException if an error occurs during the creation of the RTP
     * packet output stream
     */
    protected abstract RTPConnectorOutputStream createDataOutputStream()
        throws IOException;

    /**
     * Gets the StreamConnector which represents the pair of datagram
     * sockets for RTP and RTCP traffic used by this instance.
     *
     * @return the StreamConnector which represents the pair of
     * datagram sockets for RTP and RTCP traffic used by this instance
     */
    public final StreamConnector getConnector()
    {
        return connector;
    }

    /**
     * Returns the input stream that is handling incoming RTCP packets.
     *
     * @return the input stream that is handling incoming RTCP packets.
     *
     * @throws IOException if an error occurs during the creation of the RTCP
     * packet input stream
     */
    public RTPConnectorInputStream getControlInputStream()
        throws IOException
    {
        return getControlInputStream(true);
    }

    /**
     * Gets the PushSourceStream which gives access to the RTCP data
     * received from the remote targets and optionally creates it if it does not
     * exist yet.
     *
     * @param create true to create the PushSourceStream which
     * gives access to the RTCP data received from the remote targets if it does
     * not exist yet; otherwise, false
     * @return the PushBufferStream which gives access to the RTCP data
     * received from the remote targets; null if it does not exist yet
     * and create is false
     * @throws IOException if creating the PushSourceStream fails
     */
    protected RTPConnectorInputStream getControlInputStream(boolean create)
        throws IOException
    {
        if ((controlInputStream == null) && create)
            controlInputStream = createControlInputStream();
        return controlInputStream;
    }

    /**
     * Returns the input stream that is handling outgoing RTCP packets.
     *
     * @return the input stream that is handling outgoing RTCP packets.
     *
     * @throws IOException if an error occurs during the creation of the RTCP
     * packet output stream
     */
    public RTPConnectorOutputStream getControlOutputStream()
        throws IOException
    {
        return getControlOutputStream(true);
    }

    /**
     * Gets the OutputDataStream which is used to write RTCP data to be
     * sent to from the remote targets and optionally creates it if it does not
     * exist yet.
     *
     * @param create true to create the OutputDataStream which
     * is to be used to write RTCP data to be sent to the remote targets if it
     * does not exist yet; otherwise, false
     * @return the OutputDataStream which is used to write RTCP data to
     * be sent to the remote targets; null if it does not exist yet and
     * create is false
     * @throws IOException if creating the OutputDataStream fails
     */
    protected RTPConnectorOutputStream getControlOutputStream(boolean create)
        throws IOException
    {
        if ((controlOutputStream == null) && create)
            controlOutputStream = createControlOutputStream();
        return controlOutputStream;
    }

    /**
     * Returns the input stream that is handling incoming RTP packets.
     *
     * @return the input stream that is handling incoming RTP packets.
     *
     * @throws IOException if an error occurs during the creation of the RTP
     * packet input stream
     */
    public RTPConnectorInputStream getDataInputStream()
        throws IOException
    {
        return getDataInputStream(true);
    }

    /**
     * Gets the PushSourceStream which gives access to the RTP data
     * received from the remote targets and optionally creates it if it does not
     * exist yet.
     *
     * @param create true to create the PushSourceStream which
     * gives access to the RTP data received from the remote targets if it does
     * not exist yet; otherwise, false
     * @return the PushBufferStream which gives access to the RTP data
     * received from the remote targets; null if it does not exist yet
     * and create is false
     * @throws IOException if creating the PushSourceStream fails
     */
    protected RTPConnectorInputStream getDataInputStream(boolean create)
        throws IOException
    {
        if ((dataInputStream == null) && create)
            dataInputStream = createDataInputStream();
        return dataInputStream;
    }

    /**
     * Returns the input stream that is handling outgoing RTP packets.
     *
     * @return the input stream that is handling outgoing RTP packets.
     *
     * @throws IOException if an error occurs during the creation of the RTP
     */
    public RTPConnectorOutputStream getDataOutputStream()
        throws IOException
    {
        return getDataOutputStream(true);
    }

    /**
     * Gets the OutputDataStream which is used to write RTP data to be
     * sent to from the remote targets and optionally creates it if it does not
     * exist yet.
     *
     * @param create true to create the OutputDataStream which
     * is to be used to write RTP data to be sent to the remote targets if it
     * does not exist yet; otherwise, false
     * @return the OutputDataStream which is used to write RTP data to
     * be sent to the remote targets; null if it does not exist yet and
     * create is false
     * @throws IOException if creating the OutputDataStream fails
     */
    public RTPConnectorOutputStream getDataOutputStream(boolean create)
        throws IOException
    {
        if ((dataOutputStream == null) && create)
            dataOutputStream = createDataOutputStream();
        return dataOutputStream;
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#getReceiveBufferSize()} that always returns -1.
     */
    public int getReceiveBufferSize()
    {
        // Not applicable
        return -1;
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#getRTCPBandwidthFraction()} that always returns -1.
     */
    public double getRTCPBandwidthFraction()
    {
        // Not applicable
        return -1;
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#getRTCPSenderBandwidthFraction()} that always returns
     * -1.
     */
    public double getRTCPSenderBandwidthFraction()
    {
        // Not applicable
        return -1;
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#getSendBufferSize()} that always returns -1.
     */
    public int getSendBufferSize()
    {
        // Not applicable
        return -1;
    }

    /**
     * Removes a target from our session. If a target is removed, there will be
     * no data sent to that address.
     *
     * @param target Destination target to be removed
     */
    public void removeTarget(SessionAddress target)
    {
        if (controlOutputStream != null)
            controlOutputStream
                .removeTarget(
                    target.getControlAddress(),
                    target.getControlPort());

        if (dataOutputStream != null)
            dataOutputStream
                .removeTarget(
                    target.getDataAddress(),
                    target.getDataPort());
    }

    /**
     * Remove all stream targets. After this operation is done. There will be
     * no targets receiving data, so no data will be sent.
     */
    public void removeTargets()
    {
        if (controlOutputStream != null)
            controlOutputStream.removeTargets();

        if (dataOutputStream != null)
            dataOutputStream.removeTargets();
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#setReceiveBufferSize(int)}.
     *
     * @param size ignored.
     */
    public void setReceiveBufferSize(int size)
        throws IOException
    {
        // Nothing should be done here :-)
    }

    /**
     * Provides a dummy implementation to {@link
     * RTPConnector#setSendBufferSize(int)}.
     *
     * @param size ignored.
     */
    public void setSendBufferSize(int size)
        throws IOException
    {
        // Nothing should be done here :-)
    }

    /**
     * Configures this AbstractRTPConnector to allow RTP in the
     * specified direction. That is, enables/disables the input and output data
     * streams according to direction.
     *
     * 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
     * AbstractRTPConnector. The input stream will be enabled or
     * disabled depending on whether direction allows receiving. The
     * output stream will be enabled or disabled depending on whether
     * direction 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.");

        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy