示例#1
0
        /// <summary>
        /// Writes a RtcpPacket to the dump.
        /// If written in Binary the packet will contain an 8 Byte overhead. If written in Payload or Header the Rtcp Packet is silently ignored.
        /// </summary>
        /// <param name="packet">The packet to write</param>
        /// <param name="timeOffset">The optional time the packet was recieved relative to the beginning of the file. If the packet has a Created time that will be used otherwise DateTime.UtcNow.</param>
        public void WritePacket(Rtcp.RtcpPacket packet, TimeSpan?timeOffset = null, System.Net.IPEndPoint source = null)
        {
            if (timeOffset < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("timeOffset cannot be less than the start of the file which is defined in the header. ");
            }

            //Use the tool entry so it is disposed immediately
            using (var entry = new RtpToolEntry(m_Start, source ?? m_Source, packet))
            {
                //If given a specific timeoffset use it

                /* start of recording (GMT) */
                if (timeOffset.HasValue)
                {
                    entry.Offset = (int)timeOffset.Value.TotalMilliseconds;
                }
                else
                {
                    entry.Offset = (int)(DateTime.UtcNow - m_Start).TotalMilliseconds;  //otherwise calulcate it
                }
                //entry.Offset = /* milliseconds since the start of recording */

                //Write the item
                WriteToolEntry(entry);
            }
        }
示例#2
0
        //WritePackets(RtcpPacket[])

        //WritePackets(RtpFrame frame)

        /// <summary>
        /// Writes a DumpItem to the underlying stream
        /// </summary>
        /// <param name="item">The DumpItem to write</param>
        internal void WriteToolEntry(RtpToolEntry entry)
        {
            //If already written nothing occurs
            WriteFileHeader();

            //Write non text format entry
            if (m_Format < FileFormat.Text)
            {
                //This is a header style
                if (m_Format == FileFormat.Header)
                {
                    if (entry.IsRtcp)
                    {
                        //Indicate only the header is kept
                        entry.Length = (short)(entry.BlobLength = Media.Rtcp.RtcpHeader.Length + +RtpToolEntry.sizeOf_RD_packet_T);

                        //Write the data from the blob
                        using (Rtcp.RtcpPacket rtcp = new Rtcp.RtcpPacket(entry.Blob, entry.Pointer + RtpToolEntry.sizeOf_RD_packet_T)) m_Writer.Write(entry.Blob, 0, entry.BlobLength);
                    }
                    else if (m_Format != FileFormat.Rtcp)
                    {
                        using (Rtp.RtpPacket rtp = new Rtp.RtpPacket(entry.Blob, entry.Pointer + RtpToolEntry.sizeOf_RD_packet_T))
                        {
                            //Indicate only the header is kept
                            entry.Length = (short)(entry.BlobLength = Media.Rtp.RtpHeader.Length + RtpToolEntry.sizeOf_RD_packet_T);

                            //Write the data from the blob
                            m_Writer.Write(entry.Blob, 0, entry.BlobLength);
                        }
                    }
                }
                else if (m_Format == FileFormat.Binary)
                {
                    //Nothing to change
                    m_Writer.Write(entry.Blob);
                }
                else if (m_Format == FileFormat.Payload)
                {
                    if (entry.IsRtcp)
                    {
                        using (Rtcp.RtcpPacket rtcp = new Rtcp.RtcpPacket(entry.Blob, entry.Pointer + RtpToolEntry.sizeOf_RD_packet_T))
                        {
                            entry.Length = (short)(entry.BlobLength = rtcp.Payload.Count() + +RtpToolEntry.sizeOf_RD_packet_T);
                            m_Writer.Write(rtcp.Payload.ToArray());
                        }
                    }
                    else
                    {
                        using (Rtp.RtpPacket rtp = new Rtp.RtpPacket(entry.Blob, entry.Pointer + RtpToolEntry.sizeOf_RD_packet_T))
                        {
                            entry.Length = (short)(entry.BlobLength = rtp.PayloadData.Count() + RtpToolEntry.sizeOf_RD_packet_T);
                            m_Writer.Write(entry.Blob, 0, entry.BlobLength);
                        }
                    }
                }
            }
            else
            {
                //Write the textual version of the entry
                m_Writer.Write(System.Text.Encoding.ASCII.GetBytes(entry.ToString(m_Format)));
            }

            //Increment for the entry written
            ++m_ItemsWritten;
        }
示例#3
0
        /// <summary>
        /// O (  )
        /// </summary>
        public static void TestAConstructor_And_Reserialization()
        {
            //Cache a bitValue
            bool bitValue = false;

            unchecked
            {
                //Test every possible bit packed value that can be valid in the first and second octet
                for (int ibitValue = 0; ibitValue < 2; ++ibitValue)
                {
                    //Make a bitValue after the 0th iteration
                    if (ibitValue > 0)
                    {
                        bitValue = Convert.ToBoolean(ibitValue);
                    }

                    //Permute every possible value within the 2 bit Version
                    for (byte VersionCounter = 0; VersionCounter <= Media.Common.Binary.TwoBitMaxValue; ++VersionCounter)
                    {
                        //Permute every possible value in the 7 bit PayloadCounter
                        for (int PayloadCounter = 0; PayloadCounter <= byte.MaxValue; ++PayloadCounter)
                        {
                            //Permute every possible value in the 5 bit BlockCount
                            for (byte ReportBlockCounter = byte.MinValue; ReportBlockCounter <= Media.Common.Binary.FiveBitMaxValue; ++ReportBlockCounter)
                            {
                                //Permute every possible value in the Padding field.
                                for (byte PaddingCounter = byte.MinValue; PaddingCounter <= Media.Common.Binary.FiveBitMaxValue; ++PaddingCounter)
                                {
                                    //Create a RtpPacket instance using the specified options
                                    using (Media.Rtcp.RtcpPacket p = new Rtcp.RtcpPacket(VersionCounter, PayloadCounter, PaddingCounter, 7, 0, ReportBlockCounter))
                                    {
                                        //Check the Version
                                        System.Diagnostics.Debug.Assert(p.Version == VersionCounter, "Unexpected Version");

                                        //Check the Padding
                                        System.Diagnostics.Debug.Assert(p.Padding == PaddingCounter > 0, "Unexpected Padding");

                                        //Check the BlockCount
                                        System.Diagnostics.Debug.Assert(p.BlockCount == ReportBlockCounter, "Unexpected BlockCount");

                                        //Check the SynchronizationSourceIdentifier
                                        System.Diagnostics.Debug.Assert(p.SynchronizationSourceIdentifier == 0, "Unexpected SynchronizationSourceIdentifier");

                                        //Check the LengthInWordsMinusOne
                                        System.Diagnostics.Debug.Assert(p.Header.LengthInWordsMinusOne == 0, "Unexpected LengthInWordsMinusOne");

                                        //Check the Length
                                        System.Diagnostics.Debug.Assert(p.Length == Media.Rtcp.RtcpHeader.Length + PaddingCounter, "Unexpected Length");

                                        //Check the IsComplete
                                        System.Diagnostics.Debug.Assert(p.IsComplete, "Not Complete");

                                        //Check the result of serialization using padding.

                                        //Another test would be to permute every possible value for the LengthInWords field :)
                                        //Set the LengthInWordsMinusOne so the correct amount of bytes are serialzed, we specified 0 in the constructor
                                        //p.SetLengthInWordsMinusOne();

                                        byte[] serialized = p.Prepare().ToArray();

                                        System.Diagnostics.Debug.Assert(serialized.Length == p.Length, "Unexpected Binary Data Serialized");

                                        //Make a managed packet from the serialized data and re-verify
                                        using (Media.Rtcp.RtcpPacket s = new Rtcp.RtcpPacket(serialized, 0))
                                        {
                                            //Check the IsComplete
                                            System.Diagnostics.Debug.Assert(s.IsComplete, "Not Complete");

                                            //Check the Version
                                            System.Diagnostics.Debug.Assert(s.Version == VersionCounter, "Unexpected Version");

                                            //Check the Padding
                                            System.Diagnostics.Debug.Assert(p.PaddingOctets == PaddingCounter && s.Padding == PaddingCounter > 0, "Unexpected Padding");

                                            //Check the BlockCount
                                            System.Diagnostics.Debug.Assert(s.BlockCount == ReportBlockCounter, "Unexpected BlockCount");

                                            //Check the SynchronizationSourceIdentifier
                                            System.Diagnostics.Debug.Assert(s.SynchronizationSourceIdentifier == 0, "Unexpected SynchronizationSourceIdentifier");

                                            //Check the LengthInWordsMinusOne
                                            System.Diagnostics.Debug.Assert(s.Header.LengthInWordsMinusOne == p.Header.LengthInWordsMinusOne, "Unexpected LengthInWordsMinusOne");

                                            //Check the Length
                                            System.Diagnostics.Debug.Assert(s.Length == p.Length, "Unexpected Length");

                                            System.Diagnostics.Debug.Assert(s.Prepare().SequenceEqual(serialized), "Unexpected Binary Data Serialized");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#4
0
        //Move to RtpSendExtensions?
        /// <summary>
        /// Parses the data contained in the given <see cref="System.IO.BinaryReader"/> for data which corresponds to a format compatible with <see href="http://www.cs.columbia.edu/irt/software/rtptools/#rtpsend">rtpsend</see>.
        /// If a Binary format is encoutered (by the presence of the "#!rtpplay1.0" file header then <see cref="RtpTools.RtpDump.RtpDumpExtensions.ReadBinaryToolEntry"/> will be called implicitly with the reader given,
        /// In such a case, unexpected will contain the data which matched the file header.
        /// </summary>
        /// <param name="reader">The <see cref="System.IO.BinaryReader"/> which should be created using <see cref="System.Text.Encoding.ASCII"/></param>
        /// <param name="format">The format found while parsing the description.</param>
        /// <param name="unexpected">Will only contain data if format was unknown, and contains the data encountered in the stream while attempting to parse.</param>
        /// <returns>The item which was created as a result of reading from the stream.</returns>
        internal static RtpToolEntry ParseText(System.IO.BinaryReader reader, System.Net.IPEndPoint source, ref FileFormat format, out byte[] unexpected)
        {
            unexpected = null;

            double timeOffset = 0;

            System.Net.IPEndPoint sourceInfo = source;

            long position = reader.BaseStream.Position;

            Common.IPacket builtPacket = null;

            //Keep track of making a Rtp or Rtcp entry.
            bool rtp = false;

            Rtp.RtpPacket rtpP = null;

            Rtcp.RtcpPacket rtcP = null;

            ///<summary>
            /// each entry starts with a time value, in seconds, relative to the beginning of the trace.
            /// The time value must appear at the beginning of a line, without white space. Within an RTP or RTCP packet description,
            /// parameters may appear in any order, without white space around the equal sign.
            /// Lines are continued with initial white space on the next line.
            /// Comment lines start with #. Strings are enclosed in quotation marks.
            /// <see cref="Tokens"/>
            ///</summary>

            //The amount of tokens consumed from the reader, where a token is defined as above
            int tokensParsed = -1,

            //The amount of bytes read
            lineBytesLength = 0,

            //Used for token parsing, the index of the recognized token in 'Tokens'
            tokenIndex = -1;

            //Indicates if in a comment
            bool parsingCommentOrWhitespace = false;

            //Contains the data read from the stream until '\n' occurs.
            byte[] lineBytes;

            //Indicates if the parsing of the entry is complete
            bool doneParsing = false, formatUnknown = format == FileFormat.Unknown, needAnyToken = true;

            //A string instance which was used to compare to known `Tokens`
            string token;

            //No bytes have actually been consumed from the stream yet, while not done parsing and not at the end of the stream
            while (!doneParsing && reader.BaseStream.Position < reader.BaseStream.Length)
            {
                //Determine the following character (ASCIIEncoding SHOULD have been specified in creation of the reader) [If not could possibly have also found out without consuming a byte here]
                int peek = reader.PeekChar();

                //If no data can be read
                if (peek == -1)
                {
                    //then indiate an unknown format and then return null
                    format = FileFormat.Unknown;
                    return null;
                }
                else if (peek == RtpDump.RtpDumpExtensions.Hash || peek == (char)Common.ASCII.Space)
                {
                    //Comment lines start with # (Hash). Strings are enclosed in quotation marks.
                    parsingCommentOrWhitespace = true;

                    //Could be a binary format however....
                }
                else if (tokensParsed > 0 && peek == 'r' || peek == Common.ASCII.R) //Don't read any further a new entry follows (Could be a malformed entry with rXXX=YYY\n)
                {
                    //doneParsing = true;
                    break;
                }

                //Read until '\n' occurs
                RtpSendExtensions.ReadLineFeed(reader.BaseStream, out lineBytes);

                //Keep track of the amount of bytes read
                lineBytesLength = lineBytes.Length;

                //If nothing was read return
                if (lineBytesLength == 0) return null;

                //If the format is unknown then
                if (formatUnknown)
                {
                    //check for the Binary format at the known ordinal, if found
                    if (lineBytesLength > 2 && lineBytes[0] == RtpDump.RtpDumpExtensions.Hash && lineBytes[1] == RtpDump.RtpDumpExtensions.Bang)
                    {
                        //Indicate a binary format so far
                        format = FileFormat.Binary;

                        //give the `unexpected` data back to the caller, which consisted of the header
                        unexpected = lineBytes;

                        //Remove the reference to the token now
                        token = null;

                        //Return the result of reading the binary entry.
                        return null;
                    }

                    //Check for the short form before parsing a token

                    //Search for '='

                    tokenIndex = Array.IndexOf<byte>(lineBytes, Common.ASCII.EqualsSign);

                    //If not found then this must be a Short entry.
                    if (tokenIndex == -1)
                    {
                        //No longer unknown because,
                        formatUnknown = false;

                        //This seems to be Short format
                        format = FileFormat.Short;
                    }
                    else //There was a '=' sign
                    {
                        //No longer still unknown because,
                        //This seems to be a Text format
                        format = FileFormat.Text;

                        //but we need to consume tokens until data in tokens as they occur to be sure
                    }
                }

                //If not found then this must be a Short entry.
                if (format == FileFormat.Short) return RtpToolEntry.CreateShortEntry(DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(timeOffset)), sourceInfo, lineBytes, 0, position);
                else if (parsingCommentOrWhitespace)//If parsing a whitespace or a comment
                {
                    //Not parsing the comment / whitespace any more
                    parsingCommentOrWhitespace = false;

                    //Perform another iteration
                    continue;
                }
                else if (needAnyToken) //If a token is needed
                {

                    //Extract all tokens from the lineBytes
                    string[] tokens = Encoding.ASCII.GetString(lineBytes).Split((char)Common.ASCII.Space, (char)Common.ASCII.EqualsSign, '(', ')');

                    //Any hex data will need a length, and we start at offset 0.
                    int dataLen = 0, tokenOffset = 0;

                    //If nothing was tokenized then return the unexpected data.
                    if (tokens.Length == 0)
                    {
                        unexpected = lineBytes;
                        return null;
                    }

                    //The first token must be a timeOffset
                    if (timeOffset == 0) timeOffset = double.Parse(tokens[tokenOffset++]);

                    //For each token in the tokens after the timeOffset
                    for (int e = tokens.Length; tokenOffset < e; ++tokenOffset)
                    {
                        //Get the token at the index
                        token = tokens[tokenOffset];

                        //Determine what to do based on if there was a matching token in the Tokens array.
                        tokenIndex = Array.IndexOf<string>(Tokens, token);

                        //The entry must be finished.
                        if (-1 == tokenIndex)
                        {
                            unexpected = lineBytes;
                            break;
                        }

                        //Increment for a token parsed within the entry so far
                        ++tokensParsed;

                        //Switch out logic based on token
                        switch (tokenIndex)
                        {
                            //RTP
                            case 1:
                                {
                                    //The created structure will have a packetLength = 8 + dataLen
                                    rtp = true;

                                    rtpP = new Rtp.RtpPacket(0, false, false, Media.Common.MemorySegment.EmptyBytes);

                                    builtPacket = rtpP;

                                    //Do another iteration
                                    continue;
                                }
                            //RTCP
                            case 17:
                                {

                                    rtcP = new Rtcp.RtcpPacket(0, 0, 0, 0, 0, 0);

                                    //The created structure will have packetLen = 0 to indicate Rtcp.
                                    builtPacket = rtcP;

                                    //Do another iteration

                                    continue;
                                }
                            case 35: //from
                                {

                                    string[] parts = tokens[++tokenOffset].Split((char)Common.ASCII.Colon);

                                    System.Net.IPAddress ip = System.Net.IPAddress.Parse(parts[0]);

                                    int port = int.Parse(parts[1]);

                                    System.Diagnostics.Debug.WriteLine(ip + " " + port);

                                    sourceInfo = new System.Net.IPEndPoint(ip, port);

                                    continue;
                                }
                            case 2:
                                {
                                    //version

                                    int version = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(version);

                                    if (rtp) rtpP.Header.Version = version;
                                    else rtcP.Header.Version = version;

                                    continue;
                                }
                            case 3: //p
                                {
                                    int paddingCount = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(paddingCount);

                                    break;
                                }
                            case 4: //x
                                {
                                    if (rtp)
                                    {
                                        bool hasExtension = int.Parse(tokens[++tokenOffset]) == 1;

                                        System.Diagnostics.Debug.WriteLine(hasExtension);

                                        rtpP.Header.Extension = hasExtension;
                                    }

                                    break;
                                }
                            case 5: //m
                                {
                                    if (rtp)
                                    {
                                        bool hasMarker = int.Parse(tokens[++tokenOffset]) == 1;

                                        System.Diagnostics.Debug.WriteLine(hasMarker);

                                        rtpP.Header.Marker = hasMarker;
                                    }
                                    break;
                                }
                            case 6: //pt
                                {

                                    int payloadType = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(payloadType);

                                    if (rtp) rtpP.Header.PayloadType = payloadType;
                                    else rtcP.Header.PayloadType = payloadType;

                                    break;
                                }
                            case 7: //ts
                                {
                                    if (rtp)
                                    {
                                        int ts = int.Parse(tokens[++tokenOffset]);

                                        System.Diagnostics.Debug.WriteLine(ts);

                                        rtpP.Header.Timestamp = ts;
                                    }

                                    break;
                                }
                            case 8: //seq
                                {
                                    if (rtp)
                                    {
                                        int seq = int.Parse(tokens[++tokenOffset]);

                                        System.Diagnostics.Debug.WriteLine(seq);

                                        rtpP.Header.SequenceNumber = seq;
                                    }
                                    break;
                                }
                            case 9: //ssrc
                                {

                                    token = tokens[++tokenOffset];

                                    token = token.Remove(token.Length - 1).Replace(HexSpecifier, string.Empty);

                                    int ssrc = 0;

                                    if (!int.TryParse(token, out ssrc)) //plain int
                                        ssrc = int.Parse(token, System.Globalization.NumberStyles.HexNumber);//hex

                                    System.Diagnostics.Debug.WriteLine(ssrc);

                                    if (rtp) rtpP.Header.SynchronizationSourceIdentifier = ssrc;
                                    else rtcP.Header.SendersSynchronizationSourceIdentifier = ssrc;

                                    break;
                                }
                            case 10: //cc
                                {

                                    int cc = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(cc);

                                    if (rtp) rtpP.Header.ContributingSourceCount = cc;
                                    else rtcP.Header.BlockCount = cc;

                                    break;
                                }
                            case 11: //csrc
                                {

                                    int csrc = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(csrc);

                                    //Add to a list.

                                    break;
                                }
                            case 12://data
                                {
                                    //Token based reading may not be required anymore
                                    needAnyToken = false;

                                    //Not unknown anymore because,
                                    formatUnknown = false;

                                    //Definitely hex format
                                    format = FileFormat.Hex;

                                    //The next token is the string in hex format of the payload.
                                    ++tokenIndex;

                                    //If it begins with Hash then its NIL

                                    //Done parsing the entry.
                                    doneParsing = true;

                                    continue;
                                }
                            case 13: //ext_type
                                {

                                    int ext_type = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(ext_type);

                                    break;
                                }
                            case 14: //ext_len
                                {

                                    int ext_len = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(ext_len);

                                    break;
                                }
                            case 15: //ext_data
                                {

                                    //The next token is the string in hex format of the payload.

                                    ++tokenIndex;

                                    //If it begins with Hash then its NIL

                                    break;
                                }
                            case 16: //len
                                {
                                    dataLen = int.Parse(tokens[++tokenOffset]);

                                    System.Diagnostics.Debug.WriteLine(dataLen);

                                    continue;
                                }
                            default:
                                {
                                    //If the format was unknown
                                    if (formatUnknown)
                                    {
                                        //It is no longer so because,
                                        formatUnknown = false;

                                        //it is no longer unknown, it is definitely a Text format
                                        format = FileFormat.Text;
                                    }

                                    break;
                                }
                        }//Done determining what to do with a token
                    }//Done with tokens
                }//Don't need to parse any tokens

            }

            //Create the resulting entry with the data contained in memory read from the reader by the writer
            return new RtpToolEntry(DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(timeOffset)), sourceInfo, builtPacket, (int)timeOffset, position);
        }
示例#5
0
        /// <summary>
        /// O (  )
        /// </summary>
        public static void TestAConstructor_And_Reserialization()
        {
            //Cache a bitValue
            bool bitValue = false;

            unchecked
            {
                //Test every possible bit packed value that can be valid in the first and second octet
                for (int ibitValue = 0; ibitValue < 2; ++ibitValue)
                {
                    //Make a bitValue after the 0th iteration
                    if (ibitValue > 0) bitValue = Convert.ToBoolean(ibitValue);

                    //Permute every possible value within the 2 bit Version
                    for (byte VersionCounter = 0; VersionCounter <= Media.Common.Binary.TwoBitMaxValue; ++VersionCounter)
                    {
                        //Permute every possible value in the 7 bit PayloadCounter
                        for (int PayloadCounter = 0; PayloadCounter <= byte.MaxValue; ++PayloadCounter)
                        {
                            //Permute every possible value in the 5 bit BlockCount
                            for (byte ReportBlockCounter = byte.MinValue; ReportBlockCounter <= Media.Common.Binary.FiveBitMaxValue; ++ReportBlockCounter)
                            {
                                //Permute every possible value in the Padding field.
                                for (byte PaddingCounter = byte.MinValue; PaddingCounter <= Media.Common.Binary.FiveBitMaxValue; ++PaddingCounter)
                                {
                                    //Create a RtpPacket instance using the specified options
                                    using (Media.Rtcp.RtcpPacket p = new Rtcp.RtcpPacket(VersionCounter, PayloadCounter, PaddingCounter, 7, 0, ReportBlockCounter))
                                    {
                                        //Check the Version
                                        System.Diagnostics.Debug.Assert(p.Version == VersionCounter, "Unexpected Version");

                                        //Check the Padding
                                        System.Diagnostics.Debug.Assert(p.Padding == PaddingCounter > 0, "Unexpected Padding");

                                        //Check the BlockCount
                                        System.Diagnostics.Debug.Assert(p.BlockCount == ReportBlockCounter, "Unexpected BlockCount");

                                        //Check the SynchronizationSourceIdentifier
                                        System.Diagnostics.Debug.Assert(p.SynchronizationSourceIdentifier == 0, "Unexpected SynchronizationSourceIdentifier");

                                        //Check the LengthInWordsMinusOne
                                        System.Diagnostics.Debug.Assert(p.Header.LengthInWordsMinusOne == 0, "Unexpected LengthInWordsMinusOne");

                                        //Check the Length
                                        System.Diagnostics.Debug.Assert(p.Length == Media.Rtcp.RtcpHeader.Length + PaddingCounter, "Unexpected Length");

                                        //Check the IsComplete
                                        System.Diagnostics.Debug.Assert(p.IsComplete, "Not Complete");

                                        //Check the result of serialization using padding.

                                        //Another test would be to permute every possible value for the LengthInWords field :)
                                        //Set the LengthInWordsMinusOne so the correct amount of bytes are serialzed, we specified 0 in the constructor
                                        //p.SetLengthInWordsMinusOne();

                                        byte[] serialized = p.Prepare().ToArray();

                                        System.Diagnostics.Debug.Assert(serialized.Length == p.Length, "Unexpected Binary Data Serialized");

                                        //Make a managed packet from the serialized data and re-verify
                                        using (Media.Rtcp.RtcpPacket s = new Rtcp.RtcpPacket(serialized, 0))
                                        {
                                            //Check the IsComplete
                                            System.Diagnostics.Debug.Assert(s.IsComplete, "Not Complete");

                                            //Check the Version
                                            System.Diagnostics.Debug.Assert(s.Version == VersionCounter, "Unexpected Version");

                                            //Check the Padding
                                            System.Diagnostics.Debug.Assert(p.PaddingOctets == PaddingCounter && s.Padding == PaddingCounter > 0, "Unexpected Padding");

                                            //Check the BlockCount
                                            System.Diagnostics.Debug.Assert(s.BlockCount == ReportBlockCounter, "Unexpected BlockCount");

                                            //Check the SynchronizationSourceIdentifier
                                            System.Diagnostics.Debug.Assert(s.SynchronizationSourceIdentifier == 0, "Unexpected SynchronizationSourceIdentifier");

                                            //Check the LengthInWordsMinusOne
                                            System.Diagnostics.Debug.Assert(s.Header.LengthInWordsMinusOne == p.Header.LengthInWordsMinusOne, "Unexpected LengthInWordsMinusOne");

                                            //Check the Length
                                            System.Diagnostics.Debug.Assert(s.Length == p.Length, "Unexpected Length");

                                            System.Diagnostics.Debug.Assert(s.Prepare().SequenceEqual(serialized), "Unexpected Binary Data Serialized");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }