예제 #1
0
        public virtual int CompleteFrom(System.Net.Sockets.Socket socket, MemorySegment buffer)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Cannot modify a RtcpPacket when IsReadOnly is false.");
            }

            //If the packet is complete then return
            if (IsDisposed || IsComplete)
            {
                return(0);
            }

            //Needs to account for buffer or socket.

            //Calulcate the amount of octets remaining in the RtcpPacket including the header
            int octetsRemaining = ((ushort)(Header.LengthInWordsMinusOne + 1)) * 4 - Length, offset = Payload != null ? Payload.Count : 0;

            if (octetsRemaining > 0)
            {
                //There is not enough room in the array to finish the packet
                if (Payload.Count < octetsRemaining)
                {
                    //Allocte the memory for the required data
                    if (m_OwnedOctets == null)
                    {
                        m_OwnedOctets = new byte[octetsRemaining];
                    }
                    else
                    {
                        m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray();
                    }
                }

                System.Net.Sockets.SocketError error;

                int recieved = 0;

                //Read from the stream, decrementing from octetsRemaining what was read.
                while (octetsRemaining > 0)
                {
                    int rec = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error);
                    offset          += rec;
                    octetsRemaining -= rec;
                    recieved        += rec;
                }

                //Re-allocate the segment around the received data. //length + received
                Payload = new MemorySegment(m_OwnedOctets, 0, m_OwnedOctets.Length);

                return(recieved);
            }

            return(0);
        }
예제 #2
0
        public virtual int CompleteFrom(System.Net.Sockets.Socket socket, MemorySegment buffer)
        {
            if (IsReadOnly)
            {
                throw new InvalidOperationException("Cannot modify a RtpPacket when IsReadOnly is false.");
            }

            //If the packet is complete then return
            if (IsDisposed || IsComplete)
            {
                return(0);
            }

            // Cache the size of the original payload
            int payloadCount     = Payload.Count,
                octetsRemaining  = payloadCount,                                    //Cache how many octets remain in the payload
                offset           = Payload.Offset,                                  //Cache the offset in parsing
                sourceListOctets = ContributingSourceListOctets,                    //Cache the amount of octets required in the ContributingSourceList.
                extensionSize    = Header.Extension ? RtpExtension.MinimumSize : 0, //Cache the amount of octets required to read the ExtensionHeader
                recieved         = 0;

            //If the ContributingSourceList is not complete
            if (payloadCount < sourceListOctets)
            {
                //Calulcate the amount of octets to receive, ABS is weird and not required since paycount is checked to be less
                octetsRemaining = sourceListOctets - payloadCount; //Binary.Abs(payloadCount - sourceListOctets);

                //octetsRemaining = Binary.Min(payloadCount, sourceListOctets);

                //Allocte the memory for the required data
                if (m_OwnedOctets == null)
                {
                    m_OwnedOctets = new byte[octetsRemaining];
                }
                else
                {
                    m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray();
                }

                System.Net.Sockets.SocketError error;

                //Read from the stream, decrementing from octetsRemaining what was read.
                while (octetsRemaining > 0)
                {
                    //Receive octetsRemaining or less
                    int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error);

                    //Move the offset
                    offset += justReceived;

                    //Decrement how many octets were receieved
                    octetsRemaining -= justReceived;

                    recieved += justReceived;
                }
            }

            //At the end of the sourceList
            offset = sourceListOctets;

            //ContribuingSourceList is now Complete

            //If there is a RtpExtension indicated by the RtpHeader
            if (Header.Extension)
            {
                //Determine if the extension header was read
                octetsRemaining = RtpExtension.MinimumSize - (payloadCount - offset);

                //If the extension header is not yet read
                if (octetsRemaining > 0)
                {
                    //Allocte the memory for the extension header
                    if (m_OwnedOctets == null)
                    {
                        m_OwnedOctets = new byte[octetsRemaining];
                    }
                    else
                    {
                        m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray();
                    }

                    System.Net.Sockets.SocketError error;

                    //Read from the socket, decrementing from octetsRemaining what was read.
                    while (octetsRemaining > 0)
                    {
                        //Receive octetsRemaining or less
                        int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error);

                        //Move the offset
                        offset += justReceived;

                        //Decrement how many octets were receieved
                        octetsRemaining -= justReceived;

                        recieved += justReceived;
                    }
                }

                //at least 4 octets are now present in Payload @ Payload.Offset

                //Use a RtpExtension instance to read the Extension Header and data.
                using (RtpExtension extension = GetExtension())
                {
                    if (extension != null && false == extension.IsComplete)
                    {
                        //Cache the size of the RtpExtension (not including the Flags and LengthInWords [The Extension Header])
                        extensionSize = extension.Size - RtpExtension.MinimumSize;

                        //The amount of octets required for for completion are indicated by the Size property of the RtpExtension.
                        //Calulcate the amount of octets to receive
                        octetsRemaining = (payloadCount - offset) - RtpExtension.MinimumSize;

                        if (octetsRemaining > 0 && octetsRemaining < extensionSize)
                        {
                            //Allocte the memory for the required data
                            if (m_OwnedOctets == null)
                            {
                                m_OwnedOctets = new byte[octetsRemaining];
                            }
                            else
                            {
                                m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray();
                            }

                            System.Net.Sockets.SocketError error;

                            //Read from the stream, decrementing from octetsRemaining what was read.
                            while (octetsRemaining > 0)
                            {
                                //Receive octetsRemaining or less
                                int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error);

                                //Move the offset
                                offset += justReceived;

                                //Decrement how many octets were receieved
                                octetsRemaining -= justReceived;

                                recieved += justReceived;
                            }
                        }
                    }
                }
            }

            //RtpExtension is now Complete

            //If the header indicates the payload has padding
            if (Header.Padding)
            {
                //Double check this math
                octetsRemaining = PaddingOctets - payloadCount;

                if (octetsRemaining > 0)
                {
                    //Allocte the memory for the required data
                    if (m_OwnedOctets == null)
                    {
                        m_OwnedOctets = new byte[octetsRemaining];
                    }
                    else
                    {
                        m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray();
                    }

                    offset = payloadCount;

                    //If the amount of bytes read in the padding is NOT equal to the last byte in the segment the RtpPacket is NOT complete
                    while (octetsRemaining > 0)
                    {
                        System.Net.Sockets.SocketError error;

                        //Receive 1 byte
                        //Receive octetsRemaining or less
                        int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error);

                        //Move the offset
                        offset += justReceived;

                        recieved += justReceived;

                        octetsRemaining -= justReceived;
                    }
                }
            }

            //Padding is now complete

            //Re allocate the payload segment to include any completed data
            Payload = new MemorySegment(m_OwnedOctets, Payload.Offset, m_OwnedOctets.Length);

            //RtpPacket is complete

            return(recieved);
        }