Beispiel #1
0
 public RtpUdpReceiver(RtpSession session)
 {
     this.session = session;
 }
Beispiel #2
0
 public RtpTcpSender(RtpSession session)
 {
     this.session = session;
 }
            public List <RtspFrame> ProcessData(byte[] buf, int length, RtpSession session)
            {
                List <RtspFrame> frames = new List <RtspFrame>();
                int offset = 0;
                int pos    = 0;

                while (true)
                {
                    if (offset >= length)
                    {
                        logger.Debug("!!!!!!!!!!!!!!!!!!! " + offset + " >= " + length);

                        break;
                        //return;
                    }

                    if (tcpBufferOffset > 0)
                    {// если остались не обработанные данные
                        int len     = length - offset;
                        int newSize = tcpBufferOffset + len;

                        byte[] newBuf = new byte[newSize];

                        Array.Copy(tcpBuffer, 0, newBuf, 0, tcpBufferOffset);

                        Array.Copy(buf, offset, newBuf, tcpBufferOffset, len);

                        tcpBufferOffset = 0;

                        // Debug.WriteLine("ProcessTcpBuffer newSize " + newSize);

                        buf    = newBuf;
                        length = newSize;
                    }

                    if (streamState == RtspStreamState.WaitDollar ||
                        streamState == RtspStreamState.ReadHeader ||
                        streamState == RtspStreamState.ReadContent)
                    {
                        for (int i = offset; i < length; i++)
                        {
                            char ch = (char)buf[i];
                            if (ch == '$')
                            {
                                //Console.WriteLine("Find dollar at pos: " + i);

                                streamState = RtspStreamState.ReadId;
                                pos         = i + 1; //header
                                rtspFrame   = new RtspFrame();

                                break;
                            }
                        }
                    }

                    if (streamState == RtspStreamState.ReadId)
                    {// идентификатор 1 байт
                        int len = length - pos;
                        if (len > 0)
                        {
                            rtspFrame.Id = buf[pos];
                            //Console.WriteLine("ID: " + rtspFrame.Id + " pos: " + pos);

                            pos++;

                            streamState = RtspStreamState.ReadLen;
                        }
                        else
                        { // буфер закончился выходим
                            break;
                        }
                    }

                    if (streamState == RtspStreamState.ReadLen)
                    {// длина пакета с данными 2 байта
                        int len = length - pos;

                        if (len > 1)
                        {
                            //int frameLength = BitConverter.ToInt16(buf, pos);

                            int frameLength = BigEndian.ReadInt16(buf, pos);

                            if (frameLength <= 0)
                            {
                                logger.Warn("frameLength " + frameLength);
                                //TODO:
                                //...
                            }

                            rtspFrame.Init(frameLength);

                            //Console.WriteLine("frameLength: " + frameLength + " pos: " + pos);

                            pos += 2;

                            streamState = RtspStreamState.ReadPkt;
                        }
                        else
                        {// сохраняем в буффер то что есть и выходим
                         // Debug.WriteLine(len + " < " + 2);

                            Array.Copy(buf, pos, tcpBuffer, tcpBufferOffset, len);

                            tcpBufferOffset += len;
                            //...
                            break;
                        }
                    }

                    if (streamState == RtspStreamState.ReadPkt)
                    {
                        if (rtspFrame != null && rtspFrame.Length > 0)
                        {
                            // сколькоданных в буфере
                            int bufToRead = length - pos;

                            int bytesAdded = rtspFrame.AddData(buf, pos, bufToRead);
                            pos += bytesAdded;

                            if (rtspFrame.BytesToRead == 0)
                            {// все данные прочитаны
                             // client.ProcessRtspFrame(rtspFrame);
                             //Console.WriteLine(rtspFrame.ToString());

                                var       rtpData   = rtspFrame.Data;
                                RtpPacket rtpPacket = RtpPacket.Create(rtpData, rtpData.Length, session);

                                // OnRtpPacketReceived(rtpPacket);

                                frames.Add(rtspFrame);

                                // переходим в режим ожидания доллара
                                streamState = RtspStreamState.WaitDollar;

                                // читаем следующий rtsp frame
                                rtspFrame = null;
                            }

                            if (pos < length)
                            {
                                //ProcessTcpBuffer(buf, pos, length);
                                offset = pos;
                                continue;
                            }

                            break;
                            // return;
                        }
                    }

                    {  // понять что это за данные пока не удалось копируем в буфер
                        int bufToRead = length - offset;

                        Array.Copy(buf, offset, tcpBuffer, tcpBufferOffset, bufToRead);

                        tcpBufferOffset += bufToRead;

                        logger.Debug("Array.Copy tcpBufferOffset " + tcpBufferOffset);

                        break;
                    }
                }

                return(frames);
            }
Beispiel #4
0
        //public static RtpPacket Create(byte[] data)
        //{
        //    return Create(data, data.Length);
        //}

        public static RtpPacket Create(byte[] data, int len, RtpSession session)
        {
            if (len < RtpConst.MinRtpLength)
            {
                throw new InvalidOperationException("Invalid RTP packet. Packet size < " + RtpConst.MinRtpLength);
            }

            RtpPacket packet = new RtpPacket();

            packet.packetBytes = data;

            int  dataLength = len;//data.Length;
            int  offset     = 0;
            byte firstByte  = data[offset++];

            packet.Version = (byte)(firstByte >> 6);

            if (packet.Version != RtpConst.Version)
            {
                throw new InvalidOperationException("Invalid RTP packet. Unsupported version " + packet.Version);
            }

            /*
             * If the padding bit is set, the packet contains one or more
             * additional padding octets at the end which are not part of the
             * payload.  The last octet of the padding contains a count of how
             * many padding octets should be ignored, including itself.  Padding
             * may be needed by some encryption algorithms with fixed block sizes
             * or for carrying several RTP packets in a lower-layer protocol data
             * unit.
             */
            packet.Padding = ((firstByte & 0x20) == 0x20);

            if (packet.Padding)
            {// последний байт в пакете длинна области заполнения
                byte padding = data.Last();
                dataLength -= padding;
            }

            packet.Extension = (firstByte & 0x10) == 0x10;
            packet.CSRCCount = (byte)(firstByte & 0x0F);

            byte secondByte = data[offset++];

            packet.Marker = (secondByte & 0x80) == 0x80;

            packet.PayloadType = (secondByte & 0x7F);

            packet.Sequence = BigEndian.ReadUInt16(data, offset);
            offset         += 2;

            packet.Timestamp = BigEndian.ReadUInt32(data, offset);
            offset          += 4;

            packet.SSRC = BigEndian.ReadUInt32(data, offset);
            offset     += 4;

            if (packet.SSRC != session.SSRC)
            {// Invalid session id
                return(null);
            }

            offset += packet.CSRCCount * 4;

            if (packet.Extension)
            {   /*
                 *   An extension mechanism is provided to allow individual
                 * implementations to experiment with new payload-format-independent
                 * functions that require additional information to be carried in the
                 * RTP data packet header.  This mechanism is designed so that the
                 * header extension may be ignored by other interoperating
                 * implementations that have not been extended.
                 */
                packet.HeaderExtensionProfile = BigEndian.ReadUInt16(data, offset);
                offset += 2;

                var headerExtensionLength = BigEndian.ReadUInt16(data, offset);
                offset += 2;

                packet.HeaderExtension = new ArraySegment <byte>(data, offset, headerExtensionLength);
                offset += headerExtensionLength;
            }
            else
            {
                packet.HeaderExtensionProfile = 0;
            }

            int payloadLength = (dataLength - offset);

            packet.Payload = new ArraySegment <byte>(data, offset, payloadLength);


            return(packet);
        }