Exemple #1
0
        /// <summary>
        /// Initialises the RTP session state and starts the RTP channel UDP sockets.
        /// </summary>
        /// <param name="addrFamily">Whether the RTP channel should use IPv4 or IPv6.</param>
        /// <param name="isRtcpMultiplexed">If true RTCP reports will be multiplexed with RTP on a single channel.
        /// If false (standard mode) then a separate socket is used to send and receive RTCP reports.</param>
        private void InitialiseRtpChannel(AddressFamily addrFamily, bool isRtcpMultiplexed)
        {
            var channelAddress = (addrFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any;

            RtpChannel = new RTPChannel(channelAddress, !isRtcpMultiplexed);

            RtpChannel.OnRTPDataReceived += RtpPacketReceived;
            RtpChannel.OnClosed          += OnRTPChannelClosed;

            RtcpSession          = new RTCPSession(m_sessionStreams.First().Ssrc, RtpChannel, isRtcpMultiplexed);
            OnRtpPacketReceived += RtcpSession.RtpPacketReceived;
            RtpChannel.OnControlDataReceived += RtcpSession.ControlDataReceived;
            OnRtpPacketSent += RtcpSession.RtpPacketSent;

            // Start the RTP and Control socket receivers and the RTCP session.
            RtpChannel.Start();
            RtcpSession.Start();
        }
Exemple #2
0
        /// <summary>
        /// Initialises the RTP session state and starts the RTP channel UDP sockets.
        /// </summary>
        private void Initialise(AddressFamily addrFamily, ProtectRtpPacket srtcpProtect)
        {
            Ssrc   = Convert.ToUInt32(Crypto.GetRandomInt(0, Int32.MaxValue));
            SeqNum = Convert.ToUInt16(Crypto.GetRandomInt(0, UInt16.MaxValue));

            RtpChannel = new RTPChannel((addrFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, true);

            MediaAnnouncement.Port        = RtpChannel.RTPPort;
            RtpChannel.OnRTPDataReceived += RtpPacketReceived;
            RtpChannel.OnClosed          += OnRTPChannelClosed;

            RtcpSession          = new RTCPSession(Ssrc, RtpChannel, srtcpProtect);
            OnRtpPacketReceived += RtcpSession.RtpPacketReceived;
            RtpChannel.OnControlDataReceived += RtcpSession.ControlDataReceived;
            OnRtpPacketSent += RtcpSession.RtpPacketSent;

            // Start the RTP and Control socket receivers and the RTCP session.
            RtpChannel.Start();
            RtcpSession.Start();
        }
Exemple #3
0
 /// <summary>
 /// Adds an additional RTP stream to this session. The effect of this is to multiplex
 /// two or more RTP sessions on a single socket. Multiplexing is used by WebRTC.
 /// </summary>
 /// <param name="mediaType">The type of media for this stream. When multiplexing streams on an
 /// RTP session there can be only one stream per media type.</param>
 /// <param name="payloadTypeID">The payload type ID for this RTP stream. It's what gets set in the payload
 /// type ID field in the RTP header.</param>
 /// <param name="remotePayloadIDs">A list of the payload IDs the remote party can set in their RTP headers.</param>
 public void AddStream(SDPMediaTypesEnum mediaType, int payloadTypeID, List <int> remotePayloadIDs)
 {
     if (!(mediaType == SDPMediaTypesEnum.audio || mediaType == SDPMediaTypesEnum.video))
     {
         throw new ApplicationException($"The RTPSession does not know how to transmit media type {mediaType}.");
     }
     else if (mediaType == SDPMediaTypesEnum.audio && m_audioStream != null)
     {
         m_audioStream.UpdateRemotePayloadIDs(remotePayloadIDs);
     }
     else if (mediaType == SDPMediaTypesEnum.video && m_videoStream != null)
     {
         m_videoStream.UpdateRemotePayloadIDs(remotePayloadIDs);
     }
     else
     {
         if (mediaType == SDPMediaTypesEnum.audio)
         {
             m_audioStream      = new RTPSessionStream(SDPMediaTypesEnum.audio, payloadTypeID, remotePayloadIDs);
             m_audioRtcpSession = new RTCPSession(SDPMediaTypesEnum.audio, m_audioStream.Ssrc);
             m_audioRtcpSession.OnReportReadyToSend += SendRtcpReport;
             if (!IsSecure)
             {
                 m_audioRtcpSession.Start();
             }
         }
         else if (mediaType == SDPMediaTypesEnum.video)
         {
             m_videoStream      = new RTPSessionStream(SDPMediaTypesEnum.video, payloadTypeID, remotePayloadIDs);
             m_videoRtcpSession = new RTCPSession(SDPMediaTypesEnum.video, m_videoStream.Ssrc);
             m_videoRtcpSession.OnReportReadyToSend += SendRtcpReport;
             if (!IsSecure)
             {
                 m_videoRtcpSession.Start();
             }
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Does the actual sending of an RTP packet using the specified data and header values.
        /// </summary>
        /// <param name="rtpChannel">The RTP channel to send from.</param>
        /// <param name="dstRtpSocket">Destination to send to.</param>
        /// <param name="data">The RTP packet payload.</param>
        /// <param name="timestamp">The RTP header timestamp.</param>
        /// <param name="markerBit">The RTP header marker bit.</param>
        /// <param name="payloadType">The RTP header payload type.</param>
        private void SendRtpPacket(RTPChannel rtpChannel, IPEndPoint dstRtpSocket, byte[] data, uint timestamp, int markerBit, int payloadType, uint ssrc, ushort seqNum, RTCPSession rtcpSession)
        {
            if (IsSecure && !IsSecureContextReady)
            {
                logger.LogWarning("SendRtpPacket cannot be called on a secure session before calling SetSecurityContext.");
            }
            else
            {
                int srtpProtectionLength = (m_srtpProtect != null) ? SRTP_MAX_PREFIX_LENGTH : 0;

                RTPPacket rtpPacket = new RTPPacket(data.Length + srtpProtectionLength);
                rtpPacket.Header.SyncSource     = ssrc;
                rtpPacket.Header.SequenceNumber = seqNum;
                rtpPacket.Header.Timestamp      = timestamp;
                rtpPacket.Header.MarkerBit      = markerBit;
                rtpPacket.Header.PayloadType    = payloadType;

                Buffer.BlockCopy(data, 0, rtpPacket.Payload, 0, data.Length);

                var rtpBuffer = rtpPacket.GetBytes();

                if (m_srtpProtect == null)
                {
                    rtpChannel.SendAsync(RTPChannelSocketsEnum.RTP, dstRtpSocket, rtpBuffer);
                }
                else
                {
                    int outBufLen = 0;
                    int rtperr    = m_srtpProtect(rtpBuffer, rtpBuffer.Length - srtpProtectionLength, out outBufLen);
                    if (rtperr != 0)
                    {
                        logger.LogError("SendRTPPacket protection failed, result " + rtperr + ".");
                    }
                    else
                    {
                        rtpChannel.SendAsync(RTPChannelSocketsEnum.RTP, dstRtpSocket, rtpBuffer.Take(outBufLen).ToArray());
                    }
                }
                m_lastRtpTimestamp = timestamp;

                rtcpSession?.RecordRtpPacketSend(rtpPacket);
            }
        }