示例#1
0
 public Operation(Packet call, Action<Operation> handler)
 {
     if (call != null)
     {
         Call = call;
         Call.EncodePayload();
         ChunkStreamId = call.ChunkStreamId;
     }
     Handler = handler;
 }
        public Packet Parse()
        {
            var p = new Packet();

            byte header = _socket.ReceiveByte();

            int chunktype = (header & 0xC0) >> 6;
            p.ChunkType = chunktype;

            p.ChunkStreamId = header & 0x3F;

            switch (p.ChunkStreamId)
            {
                case 0:
                    p.ChunkStreamId = 64 + _socket.ReceiveByte();
                    break;
                case 1:
                    p.ChunkStreamId = 64 + _socket.ReceiveByte() + (_socket.ReceiveByte()*256);
                    break;
            }

            switch (p.ChunkType)
            {
                case 3:
                    p.TimeStamp = _previousReadPacket[p.ChunkStreamId].TimeStamp;
                    p.Length = _previousReadPacket[p.ChunkStreamId].Length;
                    p.Type = _previousReadPacket[p.ChunkStreamId].Type;
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 2:
                    p.Length = _previousReadPacket[p.ChunkStreamId].Length;
                    p.Type = _previousReadPacket[p.ChunkStreamId].Type;
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 1:
                    p.MessageStreamId = _previousReadPacket[p.ChunkStreamId].MessageStreamId;
                    break;
                case 0:
                    break;
            }

            _previousReadPacket[p.ChunkStreamId] = p;
            int headersize = HeaderSizes[p.ChunkType];

            if (headersize == MaxHeaderSize)
            {
                p.HasAbsTimestamp = true;
            }

            if (!Operations.ContainsKey(p.ChunkStreamId))
            {
                Operations[p.ChunkStreamId] = new Operation();
            }

            if (Operations[p.ChunkStreamId].Response != null)
            {
                p = Operations[p.ChunkStreamId].Response;
                headersize = 0;
            }
            else
            {
                Operations[p.ChunkStreamId].CreateResponse(p);
            }

            headersize--;
            var headerbytes = new byte[0];
            if (headersize > 0)
            {
                headerbytes = new byte[headersize];
                _socket.Receive(headerbytes, 0, headersize);
            }
            using (var headerstream = new MemoryStream(headerbytes))
            {
                if (headersize >= 3)
                {
                    p.TimeStamp = (int) Utils.GetUInt24(headerstream.ReadBytes(3), 0);
                    if (!p.HasAbsTimestamp)
                    {
                        if (!_streamTimestamps.ContainsKey(p.ChunkStreamId)) _streamTimestamps[p.ChunkStreamId] = 0;
                        p.TimeStamp += _streamTimestamps[p.ChunkStreamId];
                        _streamTimestamps[p.ChunkStreamId] = p.TimeStamp;
                    }
                }
                if (headersize >= 6)
                {
                    p.Length = (int) Utils.GetUInt24(headerstream.ReadBytes(3), 0);
                    p.BytesRead = 0;
                    p.BytePayload = null;
                }
                if (headersize > 6)
                {
                    p.Type = (PayloadType) headerstream.ReadByte();
                }
                if (headersize == 11)
                {
                    p.MessageStreamId = DataConverter.LittleEndian.GetInt32(headerstream.ReadBytes(4), 0);
                }
            }

            int ntoread = p.Length - p.BytesRead;
            int nchunk = ChunkSizeR;

            if (ntoread < nchunk)
            {
                nchunk = ntoread;
            }
            if (p.BytePayload == null)
            {
                p.BytePayload = new byte[0];
            }

            int prevLength = p.BytePayload.Length;
            Array.Resize(ref p.BytePayload, prevLength + nchunk);
            _socket.Receive(p.BytePayload, prevLength, nchunk);

            if (p.BytesRead + nchunk != p.BytePayload.Length)
            {
                throw new Exception(String.Format("Read failed, have read {0} of {1}", p.BytePayload.Length,
                    p.BytesRead + nchunk));
            }

            p.BytesRead += nchunk;

            if (!p.IsReady())
            {
                return null;
            }
            p.DecodePayload();

            //Special cases that affect the packet parser
            switch (p.Type)
            {
                case PayloadType.CHUNK_SIZE:
                    ChunkSizeR = ((ChunkSize) p.Payload).Size;
                    break;
                case PayloadType.VIDEO:
                    var v = (Video) p.Payload;
                    v.FlvTag.TimeStamp = (uint) p.TimeStamp;
                    //v.FlvTag.StreamID = (uint)p.MessageStreamID;
                    break;
                case PayloadType.AUDIO:
                    var a = (Audio) p.Payload;
                    a.FlvTag.TimeStamp = (uint) p.TimeStamp;
                    //v.FlvTag.StreamID = (uint)p.MessageStreamID;
                    break;
            }

            return p;
        }
示例#3
0
 public void CreateResponse(Packet packet)
 {
     Response = packet;
 }