Exemple #1
0
        internal static string ToTextualConvention(Rtcp.GoodbyeReport bye)
        {
            string blockString = string.Empty;

            if (bye == null || bye.IsDisposed) return blockString;

            //if HasReasonForLeaving add
            if (bye.HasReasonForLeaving)//reason=
                blockString += string.Format(QuotedFormat, "reason", System.Text.Encoding.ASCII.GetString(bye.ReasonForLeaving.ToArray()));

            //Write each entry in bye.GetSourceList
            using (var sourceList = bye.GetSourceList())
            {
                if (sourceList == null) blockString += "#Incomplete Source List Not Included" + (char)Common.ASCII.LineFeed;
                else foreach (uint partyId in sourceList)//ssrc=
                        blockString += string.Format(HexFormat, "ssrc", HexSpecifier + partyId.ToString("X"), (char)Common.ASCII.LineFeed);
            }

            return blockString;
        }
Exemple #2
0
        /// <summary>
        /// Prepares the text in the stream which corresponds to the RtcpData of a Rtcp.RtcpPacket.
        /// </summary>
        /// <param name="format">The <see cref="FileFormat"/> to output.</param>
        /// <param name="packet">The <see cref="Rtcp.RtcpPacket"/> to describe</param>
        /// <returns>The text describes the packet if the <paramref name="format"/> is a text format, otherwise an empty string</returns>
        public static string ToTextualConvention(FileFormat format, Rtcp.RtcpPacket packet)
        {
            if (packet == null || packet.Payload.Count == 0 || format < FileFormat.Text || format == FileFormat.Short) return string.Empty;

            if(format == FileFormat.Unknown) return UnknownSpecifier;

            //Determine the format to use as well as the `Conventional Abbreviation`
            switch (packet.PayloadType)
            {
                case Rtcp.SourceDescriptionReport.PayloadType:
                    //Use a SourceDescriptionReport to enumerate the SourceDescriptionChunk's and SourceDescriptionItem's contained in the packet.
                    using (var sdes = new Rtcp.SourceDescriptionReport(packet, false)) //Don't dispose the packet when done.
                    {
                        return string.Format(RtcpExpressionFormat,
                            "SDES",
                            packet.SynchronizationSourceIdentifier,
                            packet.Padding ? 1.ToString() : 0.ToString(),
                            packet.BlockCount,
                            packet.Header.LengthInWordsMinusOne, ToTextualConvention(sdes));
                    }
                case Rtcp.SendersReport.PayloadType:
                    using (var sr = new Rtcp.SendersReport(packet, false))
                    {
                        return string.Format(RtcpExpressionFormat,
                            "SR",
                            packet.SynchronizationSourceIdentifier,
                            packet.Padding ? 1.ToString() : 0.ToString(),
                            packet.BlockCount,
                            packet.Header.LengthInWordsMinusOne,
                            (ToTextualConvention(sr) + (char)Common.ASCII.Space + string.Format(RtcpSendersInformationFormat,
                            //0
                                (DateTime.UtcNow - sr.NtpTime).TotalSeconds.ToString("0.000000"), //ts=
                            //1
                                sr.NtpTimestamp, //ntp=
                            //2
                                sr.SendersOctetCount, //osent=
                            //3
                                sr.SendersPacketCount))); //psent=
                    }
                case Rtcp.ReceiversReport.PayloadType:
                    using (var rr = new Rtcp.ReceiversReport(packet, false))
                    {
                        return string.Format(RtcpExpressionFormat,
                            "RR",
                            packet.SynchronizationSourceIdentifier,
                            packet.Padding ? 1.ToString() : 0.ToString(),
                            packet.BlockCount,
                            packet.Header.LengthInWordsMinusOne,
                            ToTextualConvention(rr));
                    }
                case Rtcp.GoodbyeReport.PayloadType:
                    using (var bye = new Rtcp.GoodbyeReport(packet, false))
                    {
                        return string.Format(RtcpExpressionFormat,
                            "BYE",
                            packet.SynchronizationSourceIdentifier, packet.Padding ? 1.ToString() : 0.ToString(),
                            packet.BlockCount,
                            packet.Header.LengthInWordsMinusOne, ToTextualConvention(bye));
                    }
                case Rtcp.ApplicationSpecificReport.PayloadType:
                    return string.Format(RtcpExpressionFormat, "APP", packet.SynchronizationSourceIdentifier, packet.Padding ? 1.ToString() : 0.ToString(), packet.BlockCount, packet.Header.LengthInWordsMinusOne, string.Empty);
                default:
                    //Unknown PayloadType use a Hex Representation of the PayloadType
                    return string.Format(RtcpExpressionFormat, packet.PayloadType.ToString("X"), packet.SynchronizationSourceIdentifier, packet.Padding ? 1.ToString() : 0.ToString(), packet.BlockCount, packet.Header.LengthInWordsMinusOne, string.Empty);
            }
        }
Exemple #3
0
        /// <summary>
        /// Internal use only provides a `rtpsend` compatible text description of a <see cref="SourceDescriptionReport"/>.
        /// </summary>
        /// <param name="sdes">The <see cref="SourceDescriptionReport"/> to describe</param>
        /// <returns>The string</returns>
        internal static string ToTextualConvention(Rtcp.SourceDescriptionReport sdes)
        {
            if (sdes == null || sdes.IsDisposed) return string.Empty;

            StringBuilder blockStringBuilder = new StringBuilder(sdes.BlockCount * Rtcp.SourceDescriptionReport.SourceDescriptionItem.ItemHeaderSize);

            //The blockString is formatted per chunk of the sdes
            foreach (Media.Rtcp.SourceDescriptionReport.SourceDescriptionChunk chunk in sdes)
            {
                //A SDES packet description requires an item sub description in `QuotedFormat`
                StringBuilder itemStringBuilder = new StringBuilder();

                //For each item in the chunk build up the item string
                foreach (Media.Rtcp.SourceDescriptionReport.SourceDescriptionItem item in chunk)
                {

                    string typedName = Enum.GetName(typeof(Rtcp.SourceDescriptionReport.SourceDescriptionItem.SourceDescriptionItemType), item.ItemType);

                    if (string.IsNullOrWhiteSpace(typedName)) typedName = Media.Common.Extensions.String.StringExtensions.UnknownString;

                    itemStringBuilder.AppendFormat(QuotedFormat,
                        //0
                        typedName,
                        //1
                        Encoding.ASCII.GetString(item.ItemData.ToArray()));

                }

                blockStringBuilder.Append((char)Common.ASCII.LineFeed);

                blockStringBuilder.AppendFormat(SourceDescriptionChunkFormat,
                    chunk.ChunkIdentifer,
                    itemStringBuilder.ToString());
            }

            return blockStringBuilder.ToString();
        }
Exemple #4
0
        public void SendReceiverReport(Rtcp.Stats stats)
        {
            // Make sure we have the necessary information to send the report
            if (this.ServerSsrc == 0 && stats.ServerSsrc == 0)
                throw new InvalidOperationException();

            var report = new RtcpReceiverReport();
            report.Header.ItemCount = 1;
            report.Ssrc = this.Ssrc;
            report.SsrcOnly = this.UseShortReportFormat;
            report.ReporteeSsrc = (this.ServerSsrc != 0 ? this.ServerSsrc : stats.ServerSsrc);
            report.CumulativeLoss = stats.ExpectedPacketCount - stats.ActualPacketCount;
            report.LossFraction = (byte)((256 * report.CumulativeLoss) / stats.ExpectedPacketCount);
            report.ExtendedHighestSequenceNumber = stats.HighestSequenceNumber;
            report.InterarrivalJitter = stats.Jitter;
            report.LastSenderReportTimestamp = (uint)this.LastSenderReport.ToFileTimeUtc();
            report.LastSenderReportDelay = (uint)(DateTime.UtcNow.ToFileTimeUtc() - this.LastSenderReport.ToFileTimeUtc());
            this.SendPacket(report);
        }