Ejemplo n.º 1
0
 public DataAMF3Message(RTMPMessage x)
     : base(x)
 {
     using (var reader = new AMF0Reader(new MemoryStream(x.Body))) {
         reader.BaseStream.ReadByte();
         this.propertyName = (string)reader.ReadValue();
         var arguments = new List <AMFValue>();
         while (reader.BaseStream.Position < reader.BaseStream.Length)
         {
             arguments.Add(reader.ReadValue());
         }
         this.arguments = arguments;
     }
 }
Ejemplo n.º 2
0
 public void PushDataPacket(string name, AMF0Reader message)
 {
     if (PublisherId == 0)
     {
         Logger.FATAL("Data packet pushed on a publication {0} who is idle", PublisherId);
         return;
     }
     //var pos = message.BaseStream.Position;
     foreach (var listener in Listeners)
     {
         listener.Value.PushDataPacket(name, message);
         //message.BaseStream.Position = pos;
     }
     _publisher.OnDataPacket(this, name, message);
 }
Ejemplo n.º 3
0
        public override void SendStream(Stream stream, int length)
        {
            var marker   = stream.ReadByte() | 0xF0;
            var echoTime = marker == (Target == null ? 0xFE : 0xFD);

            stream.ReadUShort();
            if (echoTime)
            {
                stream.ReadUShort();
            }
            var type = stream.ReadByte();

            if (type == 0x10)
            {
                var sizePos = stream.Position;
                var size    = stream.ReadUShort();
                var flags   = stream.ReadByte();
                var idFlow  = stream.Read7BitLongValue();
                var stage   = stream.Read7BitLongValue();
                if (idFlow == 2 && stage == 1)
                {
                    var deltaNAck = stream.Read7BitLongValue();
                    var len       = (ushort)stream.ReadByte();
                    stream.Position += len;
                    stream.ReadByte();
                    stream.ReadByte(); //type
                    stream.ReadUInt(); //timestamp
                    var amfReader      = new AMF0Reader(stream);
                    var str            = amfReader.ReadShortString(true);
                    var num            = amfReader.ReadAMFDouble(true);
                    var pos            = stream.Position;
                    var connectionInfo = amfReader.ReadVariant();
                    connectionInfo["tcUrl"] = MiddleSession.QueryUrl;
                    connectionInfo["app"]   = MiddleSession.QueryUrl.Split('/').Last();
                    stream.Position         = pos;
                    var amfWriter = new AMF0Writer(stream);
                    amfWriter.WriteObject(connectionInfo, true);
                    length          = (int)stream.Position;
                    len             = (ushort)(stream.Position - sizePos - 2);
                    stream.Position = sizePos;
                    stream.Write(len);
                }
            }
            stream.Position = 6;
            base.SendStream(stream, length);
        }
Ejemplo n.º 4
0
 public CommandAMF0Message(RTMPMessage x)
     : base(x)
 {
     using (var reader = new AMF0Reader(new MemoryStream(x.Body))) {
         this.commandName   = (string)reader.ReadValue();
         this.transactionId = (int)reader.ReadValue();
         this.commandObject = reader.ReadValue();
         if (AMFValue.IsNull(CommandObject))
         {
             this.commandObject = null;
         }
         var args = new List <AMFValue>();
         while (reader.BaseStream.Position < reader.BaseStream.Length)
         {
             args.Add(reader.ReadValue());
         }
         this.arguments = args;
     }
 }
Ejemplo n.º 5
0
 public override void SendStream(Stream stream,int length)
 {
     var marker = stream.ReadByte() | 0xF0;
     var echoTime = marker == (Target == null ? 0xFE : 0xFD);
     stream.ReadUShort();
     if (echoTime) stream.ReadUShort();
     var type = stream.ReadByte();
     if (type == 0x10)
     {
         var sizePos = stream.Position;
         var size = stream.ReadUShort();
         var flags = stream.ReadByte();
         var idFlow = stream.Read7BitLongValue();
         var stage = stream.Read7BitLongValue();
         if (idFlow == 2 && stage == 1)
         {
             var deltaNAck = stream.Read7BitLongValue();
             var len = (ushort) stream.ReadByte();
             stream.Position += len;
             stream.ReadByte();
             stream.ReadByte();//type
             stream.ReadUInt();//timestamp
             var amfReader = new AMF0Reader(stream);
             var str = amfReader.ReadShortString(true);
             var num = amfReader.ReadAMFDouble(true);
             var pos = stream.Position;
             var connectionInfo = amfReader.ReadVariant();
             connectionInfo["tcUrl"] = MiddleSession.QueryUrl;
             connectionInfo["app"] = MiddleSession.QueryUrl.Split('/').Last();
             stream.Position = pos;
             var amfWriter = new AMF0Writer(stream);
             amfWriter.WriteObject(connectionInfo, true);
             length = (int) stream.Position;
             len = (ushort) (stream.Position - sizePos-2);
             stream.Position = sizePos;
             stream.Write(len);
         }
     }
     stream.Position = 6;
     base.SendStream(stream,length);
 }
Ejemplo n.º 6
0
        private void HandlerMessage(Stream message, bool needDispose = true)
        {
            var        type = message.ReadByte();
            AMF0Reader amf  = new AMF0Reader(message);

            switch (type)
            {
            case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
            case Defines.RM_HEADER_MESSAGETYPE_FLEX:
            case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
                amf._ReadUInt32();    //skip timestamp
                goto default;

            case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA:
                VideoHandler(message);
                break;

            case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA:
                AudioHandler(message);
                break;

            case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE:
                RawHandler(1, message);
                break;

            case Defines.RM_HEADER_MESSAGETYPE_USRCTRL:
                amf._ReadUInt32();    //skip timestamp
                var usrCtrlType = amf.ReadUInt16();
                switch (usrCtrlType)
                {
                case 0x29:
                    var keepAliveServer = amf.ReadUInt32();
                    var keepAlivePeer   = amf.ReadUInt32();
                    Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer);
                    Band.KeepAliveServer = keepAliveServer;
                    break;

                case 0x22:
                    var syncID = amf.ReadUInt32();
                    var count  = amf.ReadUInt32();
                    if (Band.FlowSynchronization.ContainsKey(syncID))
                    {
                        if (Band.FlowSynchronization[syncID].Count + 1 == count)
                        {
                            foreach (var flow in Band.FlowSynchronization[syncID])
                            {
                                flow.SyncDone();
                            }
                            Band.FlowSynchronization[syncID].Clear();
                        }
                        else
                        {
                            Band.FlowSynchronization[syncID].Add(this);
                            IsWaitingSync = true;
                        }
                    }
                    else
                    {
                        Band.FlowSynchronization[syncID] = new HashSet <Flow> {
                            this
                        };
                        IsWaitingSync = true;
                    }
                    //Logger.Debug("syncID:{0},count:{1}", syncID, count);
                    break;
                }
                break;

            default:
                try
                {
                    var messageBody = RtmpProtocolSerializer.Deserialize(type, amf);
                    switch (type)
                    {
                    case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
                    case Defines.RM_HEADER_MESSAGETYPE_FLEX:
                        string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION];
                        Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID];
                        MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]);
                        break;

                    case Defines.RM_HEADER_MESSAGETYPE_NOTIFY:
                    case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
                        break;

                    default:
                        Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString());
                        break;
                    }
                }
                catch (Exception)
                {
                    //do nothing
                }
                break;
            }
            Writer.CallbackHandle = 0;
            if (needDispose)
            {
                message.Dispose();
            }
        }
Ejemplo n.º 7
0
        public override bool Initialize(int clientSideBufferLength)
        {
            if (!base.Initialize(clientSideBufferLength))
            {
                FATAL("Unable to initialize stream");
                return(false);
            }
            //2. Get stream capabilities
            StreamCapabilities pCapabilities = Capabilities;

            if (pCapabilities == null)
            {
                FATAL("Invalid stream capabilities");
                return(false);
            }
            //3. Create the video builder

            switch (pCapabilities.VideoCodecId)
            {
            case VideoCodec.H264:
                _pVideoBuilder = new AVCBuilder();
                break;

            case VideoCodec.PassThrough:
                _pVideoBuilder = new BaseBuilder();
                break;

            case VideoCodec.Unknown:
                WARN("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId);
                break;

            default:
                FATAL("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId);
                return(false);
            }

            //4. Create the audio builder

            switch (pCapabilities.AudioCodecId)
            {
            case AudioCodec.Aac:
                _pAudioBuilder = new AACBuilder();
                break;

            case AudioCodec.Mp3:
                _pAudioBuilder = new MP3Builder();
                break;

            case AudioCodec.PassThrough:
                _pAudioBuilder = new BaseBuilder();
                break;

            case AudioCodec.Unknown:
                WARN("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId);
                break;

            default:
                FATAL("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId);
                return(false);
            }
            _amf0Reader = new AMF0Reader(_pFile.DataStream);
            _pFile.Br   = _amf0Reader;
            return(true);
        }
Ejemplo n.º 8
0
 public void PushDataPacket(string name, AMF0Reader message)
 {
     if (PublisherId == 0)
     {
         Logger.FATAL("Data packet pushed on a publication {0} who is idle", PublisherId);
         return;
     }
     //var pos = message.BaseStream.Position;
     foreach (var listener in Listeners)
     {
         listener.Value.PushDataPacket(name,message);
         //message.BaseStream.Position = pos;
     }
     _publisher.OnDataPacket(this,name,message);
 }
Ejemplo n.º 9
0
        public override bool Initialize(int clientSideBufferLength)
        {
            if (! base.Initialize(clientSideBufferLength))
            {
                FATAL("Unable to initialize stream");
		        return false;
            }
            //2. Get stream capabilities
	        StreamCapabilities pCapabilities = Capabilities;
	        if (pCapabilities == null) {
		        FATAL("Invalid stream capabilities");
		        return false;
	        }
                    //3. Create the video builder
	      
	        switch (pCapabilities.VideoCodecId)
	        {
	            case VideoCodec.H264:
	                _pVideoBuilder = new AVCBuilder();
	                break;
	            case VideoCodec.PassThrough:
	                _pVideoBuilder = new BaseBuilder();
	                break;
	            case VideoCodec.Unknown:
	                WARN("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId);
	                break;
	            default:
	                FATAL("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId);
	                return false;
	        }

            //4. Create the audio builder
	        
	        switch (pCapabilities.AudioCodecId)
	        {
	            case AudioCodec.Aac:
	                _pAudioBuilder = new AACBuilder();
	                break;
	            case AudioCodec.Mp3:
	                _pAudioBuilder = new MP3Builder();
	                break;
	            case AudioCodec.PassThrough:
	                _pAudioBuilder = new BaseBuilder();
	                break;
                case AudioCodec.Unknown:
	                WARN("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId);
	                break;
	            default:
	                FATAL("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId);
	                return false;
	        }
            _amf0Reader = new AMF0Reader(_pFile.DataStream);
            _pFile.Br = _amf0Reader;
            return true;
        }
Ejemplo n.º 10
0
        public virtual void SendStream(Stream stream, int len)
        {
            var marker   = stream.ReadByte() | 0xF0;
            var echoTime = marker == (Target == null ? 0xFE : 0xFD);

            stream.ReadUShort();
            if (echoTime)
            {
                stream.ReadUShort();
            }
            var type = stream.ReadByte();
            var size = stream.ReadUShort();

            switch (type)
            {
            case 0x51:
                var idFlow      = stream.Read7BitLongValue();
                var bufferSize  = stream.Read7BitLongValue();
                var stageReaden = stream.Read7BitLongValue();
                var tail        = "";
                while (stream.GetAvaliableByteCounts() > 0)
                {
                    tail += " " + stream.Read7BitLongValue();
                }
                Debug.WriteLine("from {1}:{0:X} ack {2} on flow {3} {4}", type, Target == null ? "server" : "client", stageReaden, idFlow, tail);
                break;

            case 0x10:
                var flags = stream.ReadByte();
                idFlow = stream.Read7BitLongValue();
                var stage     = stream.Read7BitLongValue();
                var deltaNAck = stream.Read7BitLongValue();
                Debug.WriteLine("from {1}:{0:X} stage {2} deltaNAck {4} on flow {3}", type, Target == null ? "server" : "client", stage, idFlow, deltaNAck);
                if ((flags & FlowWriter.MESSAGE_HEADER) != 0)
                {
                    var signturelen = stream.ReadByte();
                    stream.Position += signturelen;
                    if (stream.ReadByte() > 0)
                    {
                        if (stream.ReadByte() != 0x0A)
                        {
                            Logger.WARN("Unknown fullduplex header part for the flow {0}", idFlow);
                        }
                        else
                        {
                            var assocFlowId = stream.Read7BitLongValue();
                        }
                        var length = stream.ReadByte();
                        while (length > 0 && stream.GetAvaliableByteCounts() > 0)
                        {
                            Logger.WARN("Unknown message part on flow {0}", idFlow);
                            stream.Position += length;
                            length           = stream.ReadByte();
                        }
                        if (length > 0)
                        {
                            Logger.FATAL("Bad header message part, finished before scheduled");
                        }
                    }
                    var stype = stream.ReadByte();//type
                    //var timestamp = stream.ReadUInt();//timestamp
                    switch (stype)
                    {
                    case 0x08:
                    case 0x09:
                        break;

                    case Defines.RM_HEADER_MESSAGETYPE_FLEX:
                        stream.ReadByte();
                        goto case Defines.RM_HEADER_MESSAGETYPE_INVOKE;

                    case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
                        var timestamp = stream.ReadUInt();    //timestamp
                        var amfReader = new AMF0Reader(stream);
                        var str       = amfReader.ReadShortString(true);
                        Logger.Debug("from {1}:{0:X} to {2:X} on flow {3}", type, Target == null ? "server" : "client", str, idFlow);
                        break;

                    default:
                        Logger.Debug("from {1}:{0:X} to {2:X} on flow {3}", type, Target == null ? "server" : "client", stype, idFlow);
                        break;
                    }
                }
                break;

            default:
                Logger.Debug("from {1}:{0:X}", type, Target == null ? "server" : "client");
                break;
            }


            stream.Position        = 0;
            _outputBuffer.Position = 0;
            stream.CopyPartTo(_outputBuffer, len);
            RtmfpUtils.EncodeAndPack(AesEncrypt.Next(PrevAesType), Writer, FarId);
            EnqueueForOutbound(_outputBuffer);
        }
Ejemplo n.º 11
0
 private void HandlerMessage(Stream message,bool needDispose = true)
 {
     var type = message.ReadByte();
     AMF0Reader amf = new AMF0Reader(message);
     switch (type)
     {
         case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
         case Defines.RM_HEADER_MESSAGETYPE_FLEX:
         case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
             amf._ReadUInt32();//skip timestamp
             goto default;
         case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA:
             VideoHandler(message);
             break;
         case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA:
             AudioHandler(message);
             break;
         case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE:
             RawHandler(1, message);
             break;
         case Defines.RM_HEADER_MESSAGETYPE_USRCTRL:
             amf._ReadUInt32();//skip timestamp
             var usrCtrlType = amf.ReadUInt16();
             switch (usrCtrlType)
             {
                 case 0x29:
                     var keepAliveServer = amf.ReadUInt32();
                     var keepAlivePeer = amf.ReadUInt32();
                     Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer);
                     Band.KeepAliveServer = keepAliveServer;
                     break;
                 case 0x22:
                     var syncID = amf.ReadUInt32();
                     var count = amf.ReadUInt32();
                     if (Band.FlowSynchronization.ContainsKey(syncID))
                     {
                         if (Band.FlowSynchronization[syncID].Count + 1 == count)
                         {
                             foreach (var flow in Band.FlowSynchronization[syncID])
                                 flow.SyncDone();
                             Band.FlowSynchronization[syncID].Clear();
                         }
                         else
                         {
                             Band.FlowSynchronization[syncID].Add(this);
                             IsWaitingSync = true;
                         }
                     }
                     else
                     {
                         Band.FlowSynchronization[syncID] = new HashSet<Flow> {this};
                         IsWaitingSync = true;
                     }
                     //Logger.Debug("syncID:{0},count:{1}", syncID, count);
                     break;
             }
             break;
         default:
             try
             {
                 var messageBody = RtmpProtocolSerializer.Deserialize(type, amf);
                 switch (type)
                 {
                     case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
                     case Defines.RM_HEADER_MESSAGETYPE_FLEX:
                         string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION];
                         Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID];
                         MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]);
                         break;
                     case Defines.RM_HEADER_MESSAGETYPE_NOTIFY:
                     case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
                         break;
                     default:
                         Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString());
                         break;
                 }
             }
             catch (Exception)
             {
                 //do nothing
             }
             break;
     }
     Writer.CallbackHandle = 0;
    if(needDispose) message.Dispose();
 }
Ejemplo n.º 12
0
 public bool OnMessage(string name, AMF0Reader message)
 {
     return(true);
 }
Ejemplo n.º 13
0
        public Variant Deserialize(int msgType, AMF0Reader _amf0)
        {

            var messageBody = Variant.Get();
            var stream = _amf0.BaseStream;
            //messageBody[Defines.RM_HEADER] = header.GetVariant();
            switch (msgType)
            {
                case Defines.RM_HEADER_MESSAGETYPE_NOTIFY:
                    messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS] = Variant.Get();
                    while (_amf0.Available)
                        messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS].Add(_amf0.ReadVariant());
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
                    messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_UNKNOWNBYTE] = stream.ReadByte();
                    messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS] = Variant.Get();
                    while (_amf0.Available)
                        messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS].Add(_amf0.ReadVariant());
                    break;
               
                case Defines.RM_HEADER_MESSAGETYPE_FLEX:
                    messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_IS_FLEX] = true;
                    stream.ReadByte();
                    goto case Defines.RM_HEADER_MESSAGETYPE_INVOKE;
                case Defines.RM_HEADER_MESSAGETYPE_INVOKE:
                    messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION] = _amf0.ReadShortString(true);
                    messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID] = _amf0.ReadAMFDouble(true);
                    messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS] = Variant.Get();
                    while (_amf0.Available)
                        messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS].Add(_amf0.ReadVariant());
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_FLEXSHAREDOBJECT:
                    if (stream.ReadByte() != 0) throw new NotSupportedException();
                    goto case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT;
                case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT:
                    messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_NAME] = _amf0.ReadShortString();
                    messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_VERSION] = _amf0.ReadUInt32();
                    messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PERSISTENCE] = _amf0.ReadUInt32()==2;
                    stream.Position += 4;
                    messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES] = Variant.Get();
                    while (_amf0.Available)
                    {
                        var primitive = Variant.Get();
                        primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE] = _amf0.ReadByte();
                        primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_STRTYPE] =
                             GetSOPrimitiveString(primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE]);
                        uint rawLength = 0;
                        primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_RAWLENGTH] = rawLength = _amf0.ReadUInt32();
                        long read;
                        switch ((byte)primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE])
                        {
                            case Defines.SOT_CS_CONNECT:
                            case Defines.SOT_CS_DISCONNECT:
                                break;
                            case Defines.SOT_CS_SET_ATTRIBUTE:
                                read = 0;
                                while (read < rawLength)
                                {
                                    var afterRead = stream.Position;
                                    var key = _amf0.ReadShortString();
                                    primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD, key] = _amf0.ReadVariant();
                                    read += stream.Position - afterRead;
                                }
                                break;
                            case Defines.SOT_CSC_DELETE_DATA:
                                primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = _amf0.ReadShortString();
                                //read = 0;
                                //while (read < rawLength)
                                //{
                                //    var afterRead = stream.Position;
                                //    var key = _amf0.ReadShortString();
                                //    read += stream.Position - afterRead;
                                //    primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(key);
                                //}
                                break;
                            case Defines.SOT_BW_SEND_MESSAGE:
                                primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = Variant.Get();
                                while (_amf0.Available)
                                    primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(_amf0.ReadVariant());
                                break;
                            default:
                                Logger.FATAL("Invalid SO primitive type. Partial result:{0}",messageBody.ToString());
                                break;
                        }
                        messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES].Add(primitive);
                    }
                    
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_USRCTRL:
                    messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE] = _amf0.ReadUInt16();
                    messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE_STRING] =
                        GetUserCtrlTypeString(messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE]);
                    switch ((ushort)messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE])
                    {
                        case Defines.RM_USRCTRL_TYPE_STREAM_BEGIN:
                        case Defines.RM_USRCTRL_TYPE_STREAM_EOF:
                        case Defines.RM_USRCTRL_TYPE_STREAM_DRY:
                        case Defines.RM_USRCTRL_TYPE_STREAM_IS_RECORDED:
                            messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32();
                            break;
                        case Defines.RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH:
                            messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32();
                            messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_BUFFLEN] = _amf0.ReadUInt32();
                            break;
                        case Defines.RM_USRCTRL_TYPE_PING_REQUEST:
                            messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PING] = _amf0.ReadUInt32();
                            break;
                        case Defines.RM_USRCTRL_TYPE_PING_RESPONSE:
                            messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PONG] = _amf0.ReadUInt32();
                            break;
                        case Defines.RM_USRCTRL_TYPE_UNKNOWN1:
                        case Defines.RM_USRCTRL_TYPE_UNKNOWN2:
                            messageBody[Defines.RM_USRCTRL_UNKNOWN_U32] = _amf0.ReadUInt32();
                            break;
                        
                        default:
                            throw new InvalidDataException("Invalid user control message:"+messageBody);
                    }
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE:
                    messageBody[Defines.RM_CHUNKSIZE] = _amf0.ReadUInt32();
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_ACK:
                    messageBody[Defines.RM_ACK] = _amf0.ReadUInt32();
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_WINACKSIZE:
                    messageBody[Defines.RM_WINACKSIZE] = _amf0.ReadUInt32();
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_PEERBW:
                    messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_VALUE] = _amf0.ReadUInt32();
                    messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_TYPE] = stream.ReadByte();
                    break;
                case Defines.RM_HEADER_MESSAGETYPE_ABORTMESSAGE:
                    messageBody[Defines.RM_ABORTMESSAGE] = _amf0.ReadUInt32();
                    break;
                case 0:
                    break;
                default:
                    Logger.FATAL("Invalid message type");
                    break;
            }
            return messageBody;
        }