public override bool SignalInputData(InputStream inputStream, IPEndPoint address)
 {
     inputStream.CopyPartTo(Buffer, (int)inputStream.AvaliableByteCounts);
     Buffer.Position = 0;
     Middle.FarProtocol.IOHandler.SignalOutputData(LocalEndPoint, Buffer);
     return true;
 }
 public override bool SignalInputData(InputStream inputStream, IPEndPoint address)
 {
     inputStream.CopyPartTo(Buffer,(int) inputStream.AvaliableByteCounts);
     if (!Connections.ContainsKey(address))
     {
         Connections[address] = new Middle2ServerRTMFPProtocol
         {
             Application = Application,
             LocalEndPoint = address,
             ServerEndPoint = new IPEndPoint(IPAddress.Parse("202.109.143.196"), 19352)
         };
     }
     Connections[address].EnqueueForOutbound(Buffer);
     return true;
 }
        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;
                }
            }
        }
 public bool FeedData(uint channelId, InputStream buffer,uint length)
 {
     //1. Is the chanel number a valid chanel?
     if (channelId >= 4)
     {
         FATAL("Invalid chanel number: {0}", channelId);
         return false;
     }
     if (!_protocols.ContainsKey(channelId))
     {
         FATAL("Invalid chanel number: {0}", channelId);
         return false;
     }
     _inputBuffer.IgnoreAll();
     buffer.CopyPartTo(_inputBuffer,(int)length);
     _inputBuffer.Published = length;
     _inputBuffer.Position = 0;
     //_protocols[channelId].InputBuffer.WriteBytes(buffer);
     return _protocols[channelId].SignalInputData(_inputBuffer, _dummyAddress);
 }