Deserialize() public method

public Deserialize ( int msgType, AMF0Reader _amf0 ) : Variant
msgType int
_amf0 AMF0Reader
return Variant
Example #1
0
        private bool ProcessBytes(InputStream buffer)
        {
            while (true)
            {
                var availableBytesCount = buffer.AvaliableByteCounts;
                if (_selectedChannel < 0)
                {
                    if (availableBytesCount < 1)
                    {
                        return(true);
                    }
                    var temp = buffer.ReadByte();
                    switch (temp & 0x3f)
                    {
                    case 0:
                        if (availableBytesCount < 2)
                        {
                            FINEST("Not enough data");
                            return(true);
                        }
                        _selectedChannel = 64 + buffer.ReadByte();
                        GetChannel((uint)_selectedChannel).lastInHeaderType = (byte)(temp >> 6);
                        availableBytesCount -= 2;
                        break;

                    case 1:
                        FATAL("The server doesn't support channel ids bigger than 319");
                        return(false);

                    default:
                        _selectedChannel = temp & 0x3f;
                        GetChannel((uint)_selectedChannel).lastInHeaderType = (byte)(temp >> 6);
                        availableBytesCount -= 1;
                        break;
                    }
                }
                if (_selectedChannel >= MAX_CHANNELS_COUNT)
                {
                    FATAL("Bogus connection. Drop it like is hot");
                    return(false);
                }
                var channel = GetChannel((uint)_selectedChannel);
                switch (channel.state)
                {
                case Channel.CS_HEADER:
                    if (!channel.lastInHeader.Read((uint)_selectedChannel, channel.lastInHeaderType, buffer, availableBytesCount))
                    {
                        FATAL("Unable to read header");
                        return(false);
                    }
                    if (!channel.lastInHeader.ReadCompleted)
                    {
                        return(true);
                    }

                    var ts = channel.lastInHeader.TimeStramp;
                    switch (channel.lastInHeaderType)
                    {
                    case HT_FULL:
                        channel.lastInAbsTs = ts;
                        break;

                    case HT_SAME_STREAM:
                    case HT_SAME_LENGTH_AND_STREAM:
                        channel.lastInAbsTs += ts;
                        break;

                    case HT_CONTINUATION:
                        if (channel.lastInProcBytes == 0)
                        {
                            channel.lastInAbsTs += ts;
                        }
                        break;
                    }
                    channel.state = Channel.CS_PAYLOAD;
                    goto case Channel.CS_PAYLOAD;

                case Channel.CS_PAYLOAD:
                    var ml       = channel.lastInHeader.MessageLength;
                    var si       = channel.lastInHeader.StreamId;
                    var tempSize = ml - channel.lastInProcBytes;
                    tempSize = tempSize >= _inboundChunkSize ? _inboundChunkSize : tempSize;
                    if (tempSize > buffer.AvaliableByteCounts)
                    {
                        return(true);
                    }
                    channel.state    = Channel.CS_HEADER;
                    _selectedChannel = -1;
                    var msgType = channel.lastInHeader.MessageType;
                    switch (msgType)
                    {
                    case RM_HEADER_MESSAGETYPE_VIDEODATA:
                        if (si >= MAX_STREAMS_COUNT)
                        {
                            FATAL("The server doesn't support stream ids bigger than {0}", MAX_STREAMS_COUNT);
                            return(false);
                        }
                        if (_streams[si]?.Type == ST_IN_NET_RTMP)
                        {
                            if (!_streams[si].FeedData(buffer,
                                                       tempSize, channel.lastInProcBytes, ml, channel.lastInAbsTs, false))
                            {
                                FATAL("Unable to feed video");
                                return(false);
                            }
                        }
                        channel.lastInProcBytes += tempSize;
                        if (ml == channel.lastInProcBytes)
                        {
                            channel.lastInProcBytes = 0;
                        }
                        buffer.Ignore(tempSize);
                        break;

                    case RM_HEADER_MESSAGETYPE_AUDIODATA:
                        if (si >= MAX_STREAMS_COUNT)
                        {
                            FATAL("The server doesn't support stream ids bigger than {0}", MAX_STREAMS_COUNT);
                            return(false);
                        }

                        if (_streams[si]?.Type == ST_IN_NET_RTMP)
                        {
                            if (!_streams[si].FeedData(buffer,
                                                       tempSize, channel.lastInProcBytes, ml, channel.lastInAbsTs, true))
                            {
                                FATAL("Unable to feed video");
                                return(false);
                            }
                        }
                        channel.lastInProcBytes += tempSize;
                        if (ml == channel.lastInProcBytes)
                        {
                            channel.lastInProcBytes = 0;
                        }
                        buffer.Ignore(tempSize);
                        break;

                    default:
                        buffer.CopyPartTo(channel.inputData.BaseStream, (int)tempSize);
                        buffer.Recycle();
                        channel.lastInProcBytes += tempSize;

                        if (ml == channel.lastInProcBytes)
                        {
                            channel.lastInProcBytes = 0;
                            if (_pProtocolHandler == null)
                            {
                                FATAL("RTMP connection no longer associated with an application");
                                return(false);
                            }
                            channel.inputData.BaseStream.Position = 0;

                            if (msgType != 0)
                            {
                                var  messageBody = _rtmpProtocolSerializer.Deserialize(msgType, channel.inputData);
                                bool recycleBody;
                                if (!_pProtocolHandler.InboundMessageAvailable(this, messageBody, channel, out recycleBody))
                                {
                                    if (recycleBody)
                                    {
                                        messageBody.Recycle();
                                    }
                                    FATAL("Unable to send rtmp message to application");
                                    return(false);
                                }

                                if (recycleBody)
                                {
                                    messageBody.Recycle();
                                }
                                _rxInvokes++;
                                if (channel.inputData.BaseStream.Position < channel.inputData.BaseStream.Length)
                                {
                                    FATAL("Invalid message!!! We have leftovers:{0} bytes",
                                          channel.inputData.BaseStream.Position < channel.inputData.BaseStream.Length);
                                    return(false);
                                }
                            }
                            channel.inputData.BaseStream.Recycle();
                        }
                        break;
                    }
                    break;
                }
            }
        }