Пример #1
0
 /// <summary>
 /// Constructor for payload feedback reports that do not require any additional feedback control
 /// indication parameters (e.g. Picture Loss Indication reports).
 /// </summary>
 /// <param name="feedbackMessageType">The payload specific feedback type.</param>
 public RTCPFeedback(uint senderSsrc, uint mediaSsrc, PSFBFeedbackTypesEnum feedbackMessageType)
 {
     Header              = new RTCPHeader(feedbackMessageType);
     SenderSSRC          = senderSsrc;
     MediaSSRC           = mediaSsrc;
     SENDER_PAYLOAD_SIZE = 8;
 }
Пример #2
0
        /// <summary>
        /// Create a new RTCP SDES item from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the SDES report.</param>
        public RTCPSDesReport(byte[] packet)
        {
            if (packet.Length < MIN_PACKET_SIZE)
            {
                throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTCP SDES packet.");
            }
            else if (packet[8] != CNAME_ID)
            {
                throw new ApplicationException("The RTCP report packet did not have the requried CNAME type field set correctly.");
            }

            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SSRC = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
            }
            else
            {
                SSRC = BitConverter.ToUInt32(packet, 4);
            }

            int cnameLength = packet[9];

            CNAME = Encoding.UTF8.GetString(packet, 10, cnameLength);
        }
Пример #3
0
        /// <summary>
        /// Create a new RTCP Sender Report from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the serialised sender report.</param>
        public RTCPSenderReport(byte[] packet)
        {
            if (packet.Length < MIN_PACKET_SIZE)
            {
                throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTCPSenderReport packet.");
            }

            Header           = new RTCPHeader(packet);
            ReceptionReports = new List <ReceptionReportSample>();

            if (BitConverter.IsLittleEndian)
            {
                SSRC         = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                NtpTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 8));
                RtpTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
                PacketCount  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
                OctetCount   = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
            }
            else
            {
                SSRC         = BitConverter.ToUInt32(packet, 4);
                NtpTimestamp = BitConverter.ToUInt64(packet, 8);
                RtpTimestamp = BitConverter.ToUInt32(packet, 16);
                PacketCount  = BitConverter.ToUInt32(packet, 20);
                OctetCount   = BitConverter.ToUInt32(packet, 24);
            }

            int rrIndex = 28;

            for (int i = 0; i < Header.ReceptionReportCount; i++)
            {
                var rr = new ReceptionReportSample(packet.Skip(rrIndex + i * ReceptionReportSample.PAYLOAD_SIZE).ToArray());
                ReceptionReports.Add(rr);
            }
        }
Пример #4
0
        /// <summary>
        /// Create a new RTCP Goodbye packet from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the Goodbye packet.</param>
        public RTCPBye(byte[] packet)
        {
            if (packet.Length < MIN_PACKET_SIZE)
            {
                throw new ApplicationException(
                          "The packet did not contain the minimum number of bytes for an RTCP Goodbye packet.");
            }

            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SSRC = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
            }
            else
            {
                SSRC = BitConverter.ToUInt32(packet, 4);
            }

            if (packet.Length > MIN_PACKET_SIZE)
            {
                int reasonLength = packet[8];

                if (packet.Length - MIN_PACKET_SIZE - 1 >= reasonLength)
                {
                    Reason = Encoding.UTF8.GetString(packet, 9, reasonLength);
                }
            }
        }
Пример #5
0
        public uint FCI;        // Feedback Control Information (FCI)

        public RTCPFeedback(uint ssrc, RTCPFeedbackTypesEnum feedbackMessageType, ushort sequenceNo, ushort bitMask)
        {
            Header = new RTCPHeader(feedbackMessageType);
            SENDER_PAYLOAD_SIZE = 12;
            MIN_PACKET_SIZE     = RTCPHeader.HEADER_BYTES_LENGTH + SENDER_PAYLOAD_SIZE;
            SenderSSRC          = ssrc;
            PID = sequenceNo;
            BLP = bitMask;
        }
Пример #6
0
 public RTCPPacket(uint senderSyncSource, ulong ntpTimestamp, uint rtpTimestamp, uint senderPacketCount, uint senderOctetCount)
 {
     Header            = new RTCPHeader();
     SenderSyncSource  = senderSyncSource;
     NTPTimestamp      = ntpTimestamp;
     RTPTimestamp      = rtpTimestamp;
     SenderPacketCount = senderPacketCount;
     SenderOctetCount  = senderOctetCount;
 }
Пример #7
0
		public RTCPPacket(uint senderSyncSource, ulong ntpTimestamp, uint rtpTimestamp, uint senderPacketCount, uint senderOctetCount)
		{
			Header = new RTCPHeader();
            SenderSyncSource = senderSyncSource;
            NTPTimestamp = ntpTimestamp;
            RTPTimestamp = rtpTimestamp;
            SenderPacketCount = senderPacketCount;
            SenderOctetCount = senderOctetCount;
		}
Пример #8
0
 public RTCPSenderReport(uint ssrc, ulong ntpTimestamp, uint rtpTimestamp, uint packetCount, uint octetCount, List <ReceptionReportSample> receptionReports)
 {
     Header           = new RTCPHeader(RTCPReportTypesEnum.SR, (receptionReports != null) ? receptionReports.Count : 0);
     SSRC             = ssrc;
     NtpTimestamp     = ntpTimestamp;
     RtpTimestamp     = rtpTimestamp;
     PacketCount      = packetCount;
     OctetCount       = octetCount;
     ReceptionReports = receptionReports;
 }
Пример #9
0
        /// <summary>
        /// Creates a new RTCP Reception Report payload.
        /// </summary>
        /// <param name="ssrc">The synchronisation source of the RTP packet being sent. Can be zero
        /// if there are none being sent.</param>
        /// <param name="receptionReports">A list of the reception reports to include. Can be empty.</param>
        public RTCPReceiverReport(uint ssrc, List <ReceptionReportSample> receptionReports)
        {
            if (receptionReports == null || receptionReports.Count == 0)
            {
                throw new ArgumentException("At least one reception report must be included for an RTCP Receiver Report.");
            }

            Header           = new RTCPHeader(RTCPReportTypesEnum.RR, receptionReports.Count);
            SSRC             = ssrc;
            ReceptionReports = receptionReports;
        }
Пример #10
0
        public RTCPSenderReport(uint ssrc, ulong ntpTimestamp, uint rtpTimestamp, uint packetCount, uint octetCount, List <ReceptionReportSample> receptionReports)
        {
            //if(receptionReports == null || receptionReports.Count == 0)
            //{
            //    throw new ArgumentException("At least one reception report must be included for an RTCP Sender Report.");
            //}

            Header           = new RTCPHeader(RTCPReportTypesEnum.SR, (receptionReports != null) ? receptionReports.Count : 0);
            SSRC             = ssrc;
            NtpTimestamp     = ntpTimestamp;
            RtpTimestamp     = rtpTimestamp;
            PacketCount      = packetCount;
            OctetCount       = octetCount;
            ReceptionReports = receptionReports;
        }
Пример #11
0
            public void GetRTCPHeaderTest()
            {
                Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

                RTCPHeader rtcpHeader = new RTCPHeader();

                byte[] headerBuffer = rtcpHeader.GetHeader(0, 0);

                int byteNum = 1;

                foreach (byte headerByte in headerBuffer)
                {
                    Console.WriteLine(byteNum + ": " + headerByte.ToString("x"));
                    byteNum++;
                }
            }
Пример #12
0
        /// <summary>
        /// Creates a new RTCP Bye payload.
        /// </summary>
        /// <param name="ssrc">The synchronisation source of the RTP stream being closed.</param>
        /// <param name="reason">Optional reason for closing. Maximum length is 255 bytes
        /// (note bytes not characters).</param>
        public RTCPBye(uint ssrc, string reason)
        {
            Header = new RTCPHeader(RTCPReportTypesEnum.BYE, 1);
            SSRC   = ssrc;

            if (reason != null)
            {
                Reason = (reason.Length > MAX_REASON_BYTES) ? reason.Substring(0, MAX_REASON_BYTES) : reason;

                // Need to take account of multi-byte characters.
                while (Encoding.UTF8.GetBytes(Reason).Length > MAX_REASON_BYTES)
                {
                    Reason = Reason.Substring(0, Reason.Length - 1);
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Create a new RTCP Report from a serialised byte array.
        /// </summary>
        /// <param name="packet">The byte array holding the serialised feedback report.</param>
        public RTCPFeedback(byte[] packet)
        {
            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SenderSSRC = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                MediaSSRC  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 8));
            }
            else
            {
                SenderSSRC = BitConverter.ToUInt32(packet, 4);
                MediaSSRC  = BitConverter.ToUInt32(packet, 8);
            }

            // TODO: Depending on the report type additional parameters will need to be deserialised.
        }
Пример #14
0
        /// <summary>
        /// Creates a new RTCP SDES payload that can be included in an RTCP packet.
        /// </summary>
        /// <param name="ssrc">The synchronisation source of the SDES.</param>
        /// <param name="cname">Canonical End-Point Identifier SDES item. This should be a
        /// unique string common to all RTP streams in use by the application. Maximum
        /// length is 255 bytes (note bytes not characters).</param>
        public RTCPSDesReport(uint ssrc, string cname)
        {
            if (String.IsNullOrEmpty(cname))
            {
                throw new ArgumentNullException("cname");
            }

            Header = new RTCPHeader(RTCPReportTypesEnum.SDES, 1);
            SSRC   = ssrc;
            CNAME  = (cname.Length > MAX_CNAME_BYTES) ? cname.Substring(0, MAX_CNAME_BYTES) : cname;

            // Need to take account of multi-byte characters.
            while (Encoding.UTF8.GetBytes(CNAME).Length > MAX_CNAME_BYTES)
            {
                CNAME = CNAME.Substring(0, CNAME.Length - 1);
            }
        }
Пример #15
0
            public void RTCPHeaderRoundTripTest()
            {
                Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

                RTCPHeader src = new RTCPHeader();

                byte[]     headerBuffer = src.GetHeader(17, 54443);
                RTCPHeader dst          = new RTCPHeader(headerBuffer);

                Console.WriteLine("Version: " + src.Version + ", " + dst.Version);
                Console.WriteLine("PaddingFlag: " + src.PaddingFlag + ", " + dst.PaddingFlag);
                Console.WriteLine("ReceptionReportCount: " + src.ReceptionReportCount + ", " + dst.ReceptionReportCount);
                Console.WriteLine("PacketType: " + src.PacketType + ", " + dst.PacketType);
                Console.WriteLine("Length: " + src.Length + ", " + dst.Length);

                //Console.WriteLine("Raw Header: " + System.Text.Encoding.ASCII.GetString(headerBuffer, 0, headerBuffer.Length));

                Assert.IsTrue(src.Version == dst.Version, "Version was mismatched.");
                Assert.IsTrue(src.PaddingFlag == dst.PaddingFlag, "PaddingFlag was mismatched.");
                Assert.IsTrue(src.ReceptionReportCount == dst.ReceptionReportCount, "ReceptionReportCount was mismatched.");
                Assert.IsTrue(src.PacketType == dst.PacketType, "PacketType was mismatched.");
                Assert.IsTrue(src.Length == dst.Length, "Length was mismatched.");
            }
Пример #16
0
		public RTCPPacket(byte[] packet)
		{
			Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SenderSyncSource = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                NTPTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 8));
                RTPTimestamp = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
                SenderPacketCount = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
                SenderOctetCount = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
            }
            else
            {
                SenderSyncSource = BitConverter.ToUInt32(packet, 4);
                NTPTimestamp = BitConverter.ToUInt64(packet, 8);
                RTPTimestamp = BitConverter.ToUInt32(packet, 16);
                SenderPacketCount = BitConverter.ToUInt32(packet, 20);
                SenderOctetCount = BitConverter.ToUInt32(packet, 24);
            }

            Reports = new byte[packet.Length - RTCPHeader.HEADER_BYTES_LENGTH - SENDERINFO_BYTES_LENGTH];
            Buffer.BlockCopy(packet, RTCPHeader.HEADER_BYTES_LENGTH + SENDERINFO_BYTES_LENGTH, Reports, 0, Reports.Length);
		}
Пример #17
0
        public RTCPPacket(byte[] packet)
        {
            Header = new RTCPHeader(packet);

            if (BitConverter.IsLittleEndian)
            {
                SenderSyncSource  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 4));
                NTPTimestamp      = NetConvert.DoReverseEndian(BitConverter.ToUInt64(packet, 8));
                RTPTimestamp      = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 16));
                SenderPacketCount = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 20));
                SenderOctetCount  = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 24));
            }
            else
            {
                SenderSyncSource  = BitConverter.ToUInt32(packet, 4);
                NTPTimestamp      = BitConverter.ToUInt64(packet, 8);
                RTPTimestamp      = BitConverter.ToUInt32(packet, 16);
                SenderPacketCount = BitConverter.ToUInt32(packet, 20);
                SenderOctetCount  = BitConverter.ToUInt32(packet, 24);
            }

            Reports = new byte[packet.Length - RTCPHeader.HEADER_BYTES_LENGTH - SENDERINFO_BYTES_LENGTH];
            Buffer.BlockCopy(packet, RTCPHeader.HEADER_BYTES_LENGTH + SENDERINFO_BYTES_LENGTH, Reports, 0, Reports.Length);
        }
Пример #18
0
            public void GetRTCPHeaderTest()
            {
                Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

                RTCPHeader rtcpHeader = new RTCPHeader();
                byte[] headerBuffer = rtcpHeader.GetHeader(0, 0);

                int byteNum = 1;
                foreach (byte headerByte in headerBuffer)
                {
                    Console.WriteLine(byteNum + ": " + headerByte.ToString("x"));
                    byteNum++;
                }
            }
        /// <summary>
        /// Creates a new RTCP compound packet from a serialised buffer.
        /// </summary>
        /// <param name="packet">The serialised RTCP compound packet to parse.</param>
        public RTCPCompoundPacket(byte[] packet)
        {
            int offset = 0;

            while (offset < packet.Length)
            {
                if (packet.Length - offset < RTCPHeader.HEADER_BYTES_LENGTH)
                {
                    // Not enough bytes left for a RTCP header.
                    break;
                }
                else
                {
                    var buffer = packet.Skip(offset).ToArray();

                    // The payload type field is the second byte in the RTCP header.
                    byte packetTypeID = buffer[1];
                    switch (packetTypeID)
                    {
                    case (byte)RTCPReportTypesEnum.SR:
                        SenderReport = new RTCPSenderReport(buffer);
                        int srLength = (SenderReport != null) ? SenderReport.GetBytes().Length : Int32.MaxValue;
                        offset += srLength;
                        break;

                    case (byte)RTCPReportTypesEnum.RR:
                        ReceiverReport = new RTCPReceiverReport(buffer);
                        int rrLength = (ReceiverReport != null) ? ReceiverReport.GetBytes().Length : Int32.MaxValue;
                        offset += rrLength;
                        break;

                    case (byte)RTCPReportTypesEnum.SDES:
                        SDesReport = new RTCPSDesReport(buffer);
                        int sdesLength = (SDesReport != null) ? SDesReport.GetBytes().Length : Int32.MaxValue;
                        offset += sdesLength;
                        break;

                    case (byte)RTCPReportTypesEnum.BYE:
                        Bye = new RTCPBye(buffer);
                        int byeLength = (Bye != null) ? Bye.GetBytes().Length : Int32.MaxValue;
                        offset += byeLength;
                        break;

                    case (byte)RTCPReportTypesEnum.RTPFB:
                        // TODO: Interpret Generic RTP feedback reports.
                        var rtpfbHeader = new RTCPHeader(buffer);
                        offset += rtpfbHeader.Length * 4 + 4;
                        break;

                    case (byte)RTCPReportTypesEnum.PSFB:
                        // TODO: Interpret Payload specific feedback reports.
                        var psfbHeader = new RTCPHeader(buffer);
                        offset += psfbHeader.Length * 4 + 4;
                        break;

                    default:
                        logger.LogWarning($"RTCPCompoundPacket did not recognise packet type ID {packetTypeID}.");
                        offset = Int32.MaxValue;
                        logger.LogWarning(packet.HexStr());
                        break;
                    }
                }
            }
        }
Пример #20
0
 /// <summary>
 /// Creates a new RTCP Reception Report payload.
 /// </summary>
 /// <param name="ssrc">The synchronisation source of the RTP packet being sent. Can be zero
 /// if there are none being sent.</param>
 /// <param name="receptionReports">A list of the reception reports to include. Can be empty.</param>
 public RTCPReceiverReport(uint ssrc, List <ReceptionReportSample> receptionReports)
 {
     Header           = new RTCPHeader(RTCPReportTypesEnum.RR, receptionReports != null ? receptionReports.Count : 0);
     SSRC             = ssrc;
     ReceptionReports = receptionReports;
 }
Пример #21
0
            public void RTCPHeaderRoundTripTest()
            {
                Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

                RTCPHeader src = new RTCPHeader();
                byte[] headerBuffer = src.GetHeader(17, 54443);
                RTCPHeader dst = new RTCPHeader(headerBuffer);

                Console.WriteLine("Version: " + src.Version + ", " + dst.Version);
                Console.WriteLine("PaddingFlag: " + src.PaddingFlag + ", " + dst.PaddingFlag);
                Console.WriteLine("ReceptionReportCount: " + src.ReceptionReportCount + ", " + dst.ReceptionReportCount);
                Console.WriteLine("PacketType: " + src.PacketType + ", " + dst.PacketType);
                Console.WriteLine("Length: " + src.Length + ", " + dst.Length);

                //Console.WriteLine("Raw Header: " + System.Text.Encoding.ASCII.GetString(headerBuffer, 0, headerBuffer.Length));

                Assert.IsTrue(src.Version == dst.Version, "Version was mismatched.");
                Assert.IsTrue(src.PaddingFlag == dst.PaddingFlag, "PaddingFlag was mismatched.");
                Assert.IsTrue(src.ReceptionReportCount == dst.ReceptionReportCount, "ReceptionReportCount was mismatched.");
                Assert.IsTrue(src.PacketType == dst.PacketType, "PacketType was mismatched.");
                Assert.IsTrue(src.Length == dst.Length, "Length was mismatched.");
            }