Beispiel #1
0
 /// <summary>
 /// Raises <b>PacketReceived</b> event.
 /// </summary>
 /// <param name="packet">RTP packet.</param>
 private void OnPacketReceived(RTP_Packet packet)
 {
     if (PacketReceived != null)
     {
         PacketReceived(this, new RTP_PacketEventArgs(packet));
     }
 }
        /// <summary>
        /// Sends specified packet to the RTP session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <remarks>Properties <b>packet.SSRC</b>,<b>packet.SeqNo</b>,<b>packet.PayloadType</b> filled by this method automatically.</remarks>
        public void Send(RTP_Packet packet)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            // RTP was designed around the concept of Application Level Framing (ALF),
            // because of it we only allow to send packets and don't deal with breaking frames into packets.

            packet.SSRC        = Source.SSRC;
            packet.SeqNo       = NextSeqNo();
            packet.PayloadType = Session.Payload;

            // Send RTP packet.
            m_RtpBytesSent += m_pSource.SendRtpPacket(packet);

            m_RtpPacketsSent++;
            m_RtpDataBytesSent      += packet.Data.Length;
            m_LastPacketTime         = DateTime.Now;
            m_LastPacketRtpTimestamp = packet.Timestamp;
            m_RtcpCyclesSinceWeSent  = 0;
        }
Beispiel #3
0
        /// <summary>
        /// Parses RTP packet.
        /// </summary>
        /// <param name="buffer">Buffer containing RTP packet.</param>
        /// <param name="size">Number of bytes used in buffer.</param>
        /// <returns>Returns parsed RTP packet.</returns>
        public static RTP_Packet Parse(byte[] buffer, int size)
        {
            RTP_Packet packet = new RTP_Packet();

            packet.ParseInternal(buffer, size);

            return(packet);
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        public RTP_PacketEventArgs(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_pPacket = packet;
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        public RTP_PacketEventArgs(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_pPacket = packet;
        }
Beispiel #6
0
        /// <summary>
        /// Processes specified RTP packet thorugh this stream.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">RTP packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void Process(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_BytesReceived += size;

            if (UpdateSeq(packet.SeqNo))
            {
                OnPacketReceived(packet);

                /* RFC 3550 A.8 Estimating the Interarrival Jitter.
                 *  The code fragments below implement the algorithm given in Section
                 *  6.4.1 for calculating an estimate of the statistical variance of the
                 *  RTP data interarrival time to be inserted in the interarrival jitter
                 *  field of reception reports.  The inputs are r->ts, the timestamp from
                 *  the incoming packet, and arrival, the current time in the same units.
                 *  Here s points to state for the source; s->transit holds the relative
                 *  transit time for the previous packet, and s->jitter holds the
                 *  estimated jitter.  The jitter field of the reception report is
                 *  measured in timestamp units and expressed as an unsigned integer, but
                 *  the jitter estimate is kept in a floating point.  As each data packet
                 *  arrives, the jitter estimate is updated:
                 *
                 *      int transit = arrival - r->ts;
                 *      int d = transit - s->transit;
                 *      s->transit = transit;
                 *      if (d < 0) d = -d;
                 *      s->jitter += (1./16.) * ((double)d - s->jitter);
                 *
                 *  When a reception report block (to which rr points) is generated for
                 *  this member, the current jitter estimate is returned:
                 *
                 *      rr->jitter = (u_int32) s->jitter;
                 *
                 */
                uint arrival = RTP_Utils.DateTimeToNTP32(DateTime.Now);
                int  transit = (int)(arrival - packet.Timestamp);
                int  d       = transit - m_Transit;
                m_Transit = transit;
                if (d < 0)
                {
                    d = -d;
                }
                m_Jitter += (1.0 / 16.0) * (d - m_Jitter);
            }
            // else Packet not valid, skip it.
        }
Beispiel #7
0
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <exception cref="InvalidOperationException">Is raised when <b>CreateStream</b> method has been not called.</exception>
        internal int SendRtpPacket(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }
            if (m_pStream == null)
            {
                throw new InvalidOperationException("RTP stream is not created by CreateStream method.");
            }

            SetLastRtpPacket(DateTime.Now);
            SetState(RTP_SourceState.Active);

            return(Session.SendRtpPacket(m_pStream, packet));
        }
        /// <summary>
        /// Is called when RTP session receives new RTP packet.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">Packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void OnRtpPacketReceived(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            SetLastRtpPacket(DateTime.Now);

            // Passive source and first RTP packet.
            if (m_pStream == null)
            {
                m_pStream = new RTP_ReceiveStream(Session, this, packet.SeqNo);

                SetState(RTP_SourceState.Active);
            }

            m_pStream.Process(packet, size);
        }
        /// <summary>
        /// Processes specified RTP packet thorugh this stream.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">RTP packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void Process(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            m_BytesReceived += size;

            if (UpdateSeq(packet.SeqNo))
            {
                OnPacketReceived(packet);

                /* RFC 3550 A.8 Estimating the Interarrival Jitter.
                    The code fragments below implement the algorithm given in Section
                    6.4.1 for calculating an estimate of the statistical variance of the
                    RTP data interarrival time to be inserted in the interarrival jitter
                    field of reception reports.  The inputs are r->ts, the timestamp from
                    the incoming packet, and arrival, the current time in the same units.
                    Here s points to state for the source; s->transit holds the relative
                    transit time for the previous packet, and s->jitter holds the
                    estimated jitter.  The jitter field of the reception report is
                    measured in timestamp units and expressed as an unsigned integer, but
                    the jitter estimate is kept in a floating point.  As each data packet
                    arrives, the jitter estimate is updated:

                        int transit = arrival - r->ts;
                        int d = transit - s->transit;
                        s->transit = transit;
                        if (d < 0) d = -d;
                        s->jitter += (1./16.) * ((double)d - s->jitter);

                    When a reception report block (to which rr points) is generated for
                    this member, the current jitter estimate is returned:

                        rr->jitter = (u_int32) s->jitter;

                */
                uint arrival = RTP_Utils.DateTimeToNTP32(DateTime.Now);
                int transit = (int) (arrival - packet.Timestamp);
                int d = transit - m_Transit;
                m_Transit = transit;
                if (d < 0)
                {
                    d = -d;
                }
                m_Jitter += (1.0/16.0)*(d - m_Jitter);
            }
            // else Packet not valid, skip it.
        }
 /// <summary>
 /// Raises <b>PacketReceived</b> event.
 /// </summary>
 /// <param name="packet">RTP packet.</param>
 private void OnPacketReceived(RTP_Packet packet)
 {
     if (PacketReceived != null)
     {
         PacketReceived(this, new RTP_PacketEventArgs(packet));
     }
 }
        /// <summary>
        /// Is called when RTP session receives new RTP packet.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <param name="size">Packet size in bytes.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        internal void OnRtpPacketReceived(RTP_Packet packet, int size)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            SetLastRtpPacket(DateTime.Now);

            // Passive source and first RTP packet.
            if (m_pStream == null)
            {
                m_pStream = new RTP_ReceiveStream(Session, this, packet.SeqNo);

                SetState(RTP_SourceState.Active);
            }

            m_pStream.Process(packet, size);
        }
Beispiel #12
0
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="stream">RTP packet sending stream.</param>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>packet</b> is null reference.</exception>
        internal int SendRtpPacket(RTP_SendStream stream, RTP_Packet packet)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            // Check that we are in members table (because SSRC has timed out), add itself to senders table.
            lock (m_pMembers)
            {
                if (!m_pMembers.ContainsKey(stream.Source.SSRC))
                {
                    m_pMembers.Add(stream.Source.SSRC, stream.Source);
                }
            }

            // If we are not in sender table (because SSRC has timed out), add itself to senders table.
            lock (m_pSenders)
            {
                if (!m_pSenders.ContainsKey(stream.Source.SSRC))
                {
                    m_pSenders.Add(stream.Source.SSRC, stream.Source);
                }
            }

            byte[] packetBytes = new byte[m_MTU];
            int count = 0;
            packet.ToByte(packetBytes, ref count);

            // Send packet to each remote target.
            foreach (RTP_Address target in Targets)
            {
                try
                {
                    m_pRtpSocket.SendTo(packetBytes, count, SocketFlags.None, target.RtpEP);

                    m_RtpPacketsSent++;
                    m_RtpBytesSent += packetBytes.Length;
                }
                catch
                {
                    m_RtpFailedTransmissions++;
                }
            }

            return count;
        }
        /// <summary>
        /// Sends specified RTP packet to the session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <returns>Returns packet size in bytes.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <exception cref="InvalidOperationException">Is raised when <b>CreateStream</b> method has been not called.</exception>
        internal int SendRtpPacket(RTP_Packet packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }
            if (m_pStream == null)
            {
                throw new InvalidOperationException("RTP stream is not created by CreateStream method.");
            }

            SetLastRtpPacket(DateTime.Now);
            SetState(RTP_SourceState.Active);

            return Session.SendRtpPacket(m_pStream, packet);
        }
Beispiel #14
0
        /// <summary>
        /// Parses RTP packet.
        /// </summary>
        /// <param name="buffer">Buffer containing RTP packet.</param>
        /// <param name="size">Number of bytes used in buffer.</param>
        /// <returns>Returns parsed RTP packet.</returns>
        public static RTP_Packet Parse(byte[] buffer, int size)
        {
            RTP_Packet packet = new RTP_Packet();
            packet.ParseInternal(buffer, size);

            return packet;
        }
        /// <summary>
        /// Sends specified packet to the RTP session remote party.
        /// </summary>
        /// <param name="packet">RTP packet.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>packet</b> is null reference.</exception>
        /// <remarks>Properties <b>packet.SSRC</b>,<b>packet.SeqNo</b>,<b>packet.PayloadType</b> filled by this method automatically.</remarks>
        public void Send(RTP_Packet packet)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            // RTP was designed around the concept of Application Level Framing (ALF), 
            // because of it we only allow to send packets and don't deal with breaking frames into packets.

            packet.SSRC = Source.SSRC;
            packet.SeqNo = NextSeqNo();
            packet.PayloadType = Session.Payload;

            // Send RTP packet.
            m_RtpBytesSent += m_pSource.SendRtpPacket(packet);

            m_RtpPacketsSent++;
            m_RtpDataBytesSent += packet.Data.Length;
            m_LastPacketTime = DateTime.Now;
            m_LastPacketRtpTimestamp = packet.Timestamp;
            m_RtcpCyclesSinceWeSent = 0;
        }