Esempio n. 1
0
 /// <summary>
 /// Sets property LastRR value.
 /// </summary>
 /// <param name="rr">RTCP RR report.</param>
 /// <exception cref="ArgumentNullException">Is raised when <b>rr</b> is null reference.</exception>
 internal void SetRR(RTCP_Packet_ReportBlock rr)
 {
     if (rr == null)
     {
         throw new ArgumentNullException("rr");
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Parses receiver report(RR) from byte buffer.
        /// </summary>
        /// <param name="buffer">Buffer wihich contains receiver report.</param>
        /// <param name="offset">Offset in buufer.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        protected override void ParseInternal(byte[] buffer, ref int offset)
        {
            /* RFC 3550 6.4.2 RR: Receiver Report RTCP Packet.
             *      0                   1                   2                   3
             *      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             * header |V=2|P|    RC   |   PT=RR=201   |             length            |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                     SSRC of packet sender                     |
             +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
             | report |                 SSRC_1 (SSRC of first source)                 |
             | block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | 1    | fraction lost |       cumulative number of packets lost       |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |           extended highest sequence number received           |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                      interarrival jitter                      |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                         last SR (LSR)                         |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                   delay since last SR (DLSR)                  |
             +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
             | report |                 SSRC_2 (SSRC of second source)                |
             | block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | 2    :                               ...                             :
             +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
             |                  profile-specific extensions                  |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             */

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentException("Argument 'offset' value must be >= 0.");
            }

            m_Version = buffer[offset] >> 6;
            bool isPadded         = Convert.ToBoolean((buffer[offset] >> 5) & 0x1);
            int  reportBlockCount = buffer[offset++] & 0x1F;
            int  type             = buffer[offset++];
            int  length           = buffer[offset++] << 8 | buffer[offset++];

            if (isPadded)
            {
                this.PaddBytesCount = buffer[offset + length];
            }

            m_SSRC = (uint)(buffer[offset++] << 24 | buffer[offset++] << 16 | buffer[offset++] << 8 | buffer[offset++]);
            for (int i = 0; i < reportBlockCount; i++)
            {
                RTCP_Packet_ReportBlock reportBlock = new RTCP_Packet_ReportBlock();
                reportBlock.Parse(buffer, offset);
                m_pReportBlocks.Add(reportBlock);
                offset += 24;
            }
            // TODO: profile-specific extensions
        }
Esempio n. 3
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="rr">RTCP RR report.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>rr</b> is null reference.</exception>
        internal RTCP_Report_Receiver(RTCP_Packet_ReportBlock rr)
        {
            if (rr == null)
            {
                throw new ArgumentNullException("rr");
            }

            m_FractionLost          = rr.FractionLost;
            m_CumulativePacketsLost = rr.CumulativePacketsLost;
            m_ExtHigestSeqNumber    = rr.ExtendedHighestSeqNo;
            m_Jitter           = rr.Jitter;
            m_LastSR           = rr.LastSR;
            m_DelaySinceLastSR = rr.DelaySinceLastSR;
        }
Esempio n. 4
0
        /// <summary>
        /// Creates receiver report.
        /// </summary>
        /// <returns>Returns created receiver report.</returns>
        internal RTCP_Packet_ReportBlock CreateReceiverReport()
        {
            /* RFC 3550 A.3 Determining Number of Packets Expected and Lost.
             *  In order to compute packet loss rates, the number of RTP packets
             *  expected and actually received from each source needs to be known,
             *  using per-source state information defined in struct source
             *  referenced via pointer s in the code below.  The number of packets
             *  received is simply the count of packets as they arrive, including any
             *  late or duplicate packets.  The number of packets expected can be
             *  computed by the receiver as the difference between the highest
             *  sequence number received (s->max_seq) and the first sequence number
             *  received (s->base_seq).  Since the sequence number is only 16 bits
             *  and will wrap around, it is necessary to extend the highest sequence
             *  number with the (shifted) count of sequence number wraparounds
             *  (s->cycles).  Both the received packet count and the count of cycles
             *  are maintained the RTP header validity check routine in Appendix A.1.
             *
             *      extended_max = s->cycles + s->max_seq;
             *      expected = extended_max - s->base_seq + 1;
             *
             *  The number of packets lost is defined to be the number of packets
             *  expected less the number of packets actually received:
             *
             *      lost = expected - s->received;
             *
             *  Since this signed number is carried in 24 bits, it should be clamped
             *  at 0x7fffff for positive loss or 0x800000 for negative loss rather
             *  than wrapping around.
             *
             *  The fraction of packets lost during the last reporting interval
             *  (since the previous SR or RR packet was sent) is calculated from
             *  differences in the expected and received packet counts across the
             *  interval, where expected_prior and received_prior are the values
             *  saved when the previous reception report was generated:
             *
             *      expected_interval = expected - s->expected_prior;
             *      s->expected_prior = expected;
             *      received_interval = s->received - s->received_prior;
             *      s->received_prior = s->received;
             *      lost_interval = expected_interval - received_interval;
             *      if(expected_interval == 0 || lost_interval <= 0)
             *          fraction = 0;
             *      else
             *          fraction = (lost_interval << 8) / expected_interval;
             *
             *  The resulting fraction is an 8-bit fixed point number with the binary
             *  point at the left edge.
             */

            uint extHighestSeqNo = (uint)(m_SeqNoWrapCount << 16 + m_MaxSeqNo);
            uint expected        = extHighestSeqNo - m_BaseSeq + 1;

            int expected_interval = (int)(expected - m_ExpectedPrior);

            m_ExpectedPrior = expected;
            int received_interval = (int)(m_PacketsReceived - m_ReceivedPrior);

            m_ReceivedPrior = m_PacketsReceived;
            int lost_interval = expected_interval - received_interval;
            int fraction      = 0;

            if (expected_interval == 0 || lost_interval <= 0)
            {
                fraction = 0;
            }
            else
            {
                fraction = (lost_interval << 8) / expected_interval;
            }

            RTCP_Packet_ReportBlock rr = new RTCP_Packet_ReportBlock(this.SSRC.SSRC);

            rr.FractionLost          = (uint)fraction;
            rr.CumulativePacketsLost = (uint)this.PacketsLost;
            rr.ExtendedHighestSeqNo  = extHighestSeqNo;
            rr.Jitter           = (uint)m_Jitter;
            rr.LastSR           = (m_pLastSR == null ? 0 : ((uint)((long)m_pLastSR.NtpTimestamp >> 8) & 0xFFFF));
            rr.DelaySinceLastSR = (uint)Math.Max(0, this.DelaySinceLastSR / 65.536);

            return(rr);
        }