Ejemplo n.º 1
0
 protected override void WritingMessage(RtmpPacket packet)
 {
     base.WritingMessage(packet);
     if (packet.Message is VideoData)
     {
         int           streamId = packet.Header.StreamId;
         AtomicInteger integer  = new AtomicInteger();
         AtomicInteger integer2 = null;
         lock (((ICollection)this._pendingVideos).SyncRoot)
         {
             if (!this._pendingVideos.ContainsKey(streamId))
             {
                 this._pendingVideos.Add(streamId, integer);
                 integer2 = integer;
             }
             else
             {
                 integer2 = this._pendingVideos[streamId];
             }
         }
         if (integer2 == null)
         {
             integer2 = integer;
         }
         integer2.Increment();
     }
 }
Ejemplo n.º 2
0
        public static ByteBuffer EncodePacket(RtmpContext context, RtmpPacket packet)
        {
            RtmpHeader header    = packet.Header;
            int        channelId = header.ChannelId;
            IRtmpEvent message   = packet.Message;

            if (message is ChunkSize)
            {
                ChunkSize size = (ChunkSize)message;
                context.SetWriteChunkSize(size.Size);
            }
            ByteBuffer input = EncodeMessage(context, header, message);

            if (input.Position != 0L)
            {
                input.Flip();
            }
            else
            {
                input.Rewind();
            }
            header.Size = input.Limit;
            RtmpHeader lastWriteHeader = context.GetLastWriteHeader(channelId);
            int        num2            = CalculateHeaderSize(header, lastWriteHeader);

            context.SetLastWriteHeader(channelId, header);
            context.SetLastWritePacket(channelId, packet);
            int writeChunkSize = context.GetWriteChunkSize();
            int num4           = 1;

            if (header.ChannelId > 320)
            {
                num4 = 3;
            }
            else if (header.ChannelId > 0x3f)
            {
                num4 = 2;
            }
            int        num5     = (int)Math.Ceiling((double)(((float)header.Size) / ((float)writeChunkSize)));
            int        capacity = (header.Size + num2) + ((num5 > 0) ? ((num5 - 1) * num4) : 0);
            ByteBuffer buffer   = ByteBuffer.Allocate(capacity);

            EncodeHeader(header, lastWriteHeader, buffer);
            if (num5 == 1)
            {
                ByteBuffer.Put(buffer, input, buffer.Remaining);
            }
            else
            {
                for (int i = 0; i < (num5 - 1); i++)
                {
                    ByteBuffer.Put(buffer, input, writeChunkSize);
                    EncodeHeaderByte(buffer, 3, header.ChannelId);
                }
                ByteBuffer.Put(buffer, input, buffer.Remaining);
            }
            buffer.Flip();
            return(buffer);
        }
Ejemplo n.º 3
0
        public void SetLastWritePacket(int channelId, RtmpPacket packet)
        {
            RtmpPacket packet2 = null;

            if (this._writePackets.ContainsKey(channelId))
            {
                packet2 = this._writePackets[channelId];
            }
            if ((packet2 != null) && (packet2.Data != null))
            {
                packet2.Data = null;
            }
            this._writePackets[channelId] = packet;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Writes packet from event data to the RTMP connection using the specified stream id.
        /// </summary>
        /// <param name="message">Event data.</param>
        /// <param name="streamId">Stream id.</param>
        private void Write(IRtmpEvent message, int streamId)
        {
            RtmpHeader header = new RtmpHeader();
            RtmpPacket packet = new RtmpPacket(header, message);

            header.ChannelId = _channelId;
            header.Timer     = message.Timestamp;
            header.StreamId  = streamId;
            header.DataType  = message.DataType;
            if (message.Header != null)
            {
                header.IsTimerRelative = message.Header.IsTimerRelative;
            }
            _connection.Write(packet);
        }
Ejemplo n.º 5
0
 internal override void MessageSent(RtmpPacket packet)
 {
     if (packet.Message is VideoData)
     {
         int streamId = packet.Header.StreamId;
         lock (((ICollection)this._pendingVideos).SyncRoot)
         {
             if (this._pendingVideos.ContainsKey(streamId))
             {
                 this._pendingVideos[streamId].Decrement();
             }
         }
     }
     base.MessageSent(packet);
 }
Ejemplo n.º 6
0
        public override void MessageSent(RtmpConnection connection, object message)
        {
            base.MessageSent(connection, message);
            RtmpPacket    packet            = message as RtmpPacket;
            int           channelId         = packet.Header.ChannelId;
            IClientStream streamByChannelId = null;

            if (connection is IStreamCapableConnection)
            {
                streamByChannelId = (connection as IStreamCapableConnection).GetStreamByChannelId(channelId);
            }
            if ((streamByChannelId != null) && (streamByChannelId is PlaylistSubscriberStream))
            {
                (streamByChannelId as PlaylistSubscriberStream).Written(packet.Message);
            }
        }
Ejemplo n.º 7
0
        public override void MessageSent(RtmpConnection connection, object message)
        {
            base.MessageSent(connection, message);
            RtmpPacket    sent      = message as RtmpPacket;
            int           channelId = sent.Header.ChannelId;
            IClientStream stream    = null;

            if (connection is IStreamCapableConnection)
            {
                stream = (connection as IStreamCapableConnection).GetStreamByChannelId(channelId);
            }
            // XXX we'd better use new event model for notification
            if (stream != null && (stream is PlaylistSubscriberStream))
            {
                (stream as PlaylistSubscriberStream).Written(sent.Message);
            }
        }
        public override void Write(RtmpPacket packet)
        {
            _lock.AcquireReaderLock();
            try
            {
                if (IsClosed || IsClosing || IsDisconnecting)
                {
                    return; // Already shutting down.
                }
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }
            if (log.IsDebugEnabled)
            {
                log.Debug(__Res.GetString(__Res.Rtmp_WritePacket, _connectionId, packet));
            }

            if (!this.IsTunneled)
            {
                //encode
                WritingMessage(packet);
                ByteBuffer outputStream = null;
                _lock.AcquireWriterLock();
                try
                {
                    outputStream = RtmpProtocolEncoder.Encode(this.Context, packet);
                }
                finally
                {
                    _lock.ReleaseWriterLock();
                }
                Write(outputStream);
                _rtmpServer.RtmpHandler.MessageSent(this, packet);
            }
            else
            {
                //We should never get here
                System.Diagnostics.Debug.Assert(false);
            }
        }
Ejemplo n.º 9
0
 public override void Write(RtmpPacket packet)
 {
     if (!base.IsDisposed && this.IsActive)
     {
         if (log.get_IsDebugEnabled())
         {
             log.Debug("Write " + packet.Header);
         }
         if (!this.IsTunneled)
         {
             this.WritingMessage(packet);
             ByteBuffer buf = RtmpProtocolEncoder.Encode(base.Context, packet);
             this.Send(buf);
             this._rtmpServer.RtmpHandler.MessageSent(this, packet);
         }
         else
         {
             Debug.Assert(false);
         }
     }
 }
Ejemplo n.º 10
0
 internal void SetLastWritePacket(int channelId, RtmpPacket packet)
 {
     try
     {
         ReaderWriterLock.AcquireWriterLock();
         RtmpPacket prevPacket = null;
         if (_writePackets.ContainsKey(channelId))
         {
             prevPacket = _writePackets[channelId] as RtmpPacket;
         }
         if (prevPacket != null && prevPacket.Data != null)
         {
             prevPacket.Data = null;
         }
         _writePackets[channelId] = packet;
     }
     finally
     {
         ReaderWriterLock.ReleaseWriterLock();
     }
 }
Ejemplo n.º 11
0
	    internal virtual void MessageSent(RtmpPacket packet) 
        {
            if (packet.Message is VideoData)
            {
                int streamId = packet.Header.StreamId;
                AtomicInteger pending = null;
                _pendingVideos.TryGetValue(streamId, out pending);
                if (pending != null)
                    pending.Decrement();
            }
		    _writtenMessages.Increment();
	    }
Ejemplo n.º 12
0
 public abstract void Write(RtmpPacket packet);
Ejemplo n.º 13
0
        /// <summary>
        /// Message recieved.
        /// </summary>
        /// <param name="connection">Connection object.</param>
        /// <param name="obj">Message object.</param>
        public void MessageReceived(RtmpConnection connection, object obj)
        {
            //Console.WriteLine("NEW MESSAGE");
            IRtmpEvent    message = null;
            RtmpPacket    packet  = null;
            RtmpHeader    header  = null;
            RtmpChannel   channel = null;
            IClientStream stream  = null;

            try
            {
                packet  = obj as RtmpPacket;
                message = packet.Message;
                header  = packet.Header;
                //Console.WriteLine("DATA TYPE: " + header.DataType);
                channel = connection.GetChannel(header.ChannelId);
                if (connection is IStreamCapableConnection)
                {
                    stream = (connection as IStreamCapableConnection).GetStreamById(header.StreamId);
                }

                // Support stream ids
#if !SILVERLIGHT
                FluorineContext.ValidateContext();
                FluorineContext.Current.Connection.SetAttribute(FluorineContext.FluorineStreamIdKey, header.StreamId);
#endif
                // Increase number of received messages
                connection.MessageReceived();

#if !SILVERLIGHT
                if (log != null && log.IsDebugEnabled)
                {
                    log.Debug("RtmpConnection message received, type = " + header.DataType);
                }
#endif

                if (message != null)
                {
                    message.Source = connection;
                }

                switch (header.DataType)
                {
                case Constants.TypeInvoke:
                    OnInvoke(connection, channel, header, message as Invoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)     //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeFlexInvoke:
                    OnFlexInvoke(connection, channel, header, message as FlexInvoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)     //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeNotify:    // just like invoke, but does not return
                    //Console.WriteLine("NOTIFY MESSAGE");
                    if ((message as Notify).Data != null && stream != null)
                    {
                        // Stream metadata
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    else
                    {
                        OnInvoke(connection, channel, header, message as Notify);
                    }
                    break;

                case Constants.TypePing:
                    OnPing(connection, channel, header, message as Ping);
                    break;

                case Constants.TypeBytesRead:
                    OnStreamBytesRead(connection, channel, header, message as BytesRead);
                    break;

                case Constants.TypeSharedObject:
                case Constants.TypeFlexSharedObject:
                    OnSharedObject(connection, channel, header, message as SharedObjectMessage);
                    break;

                case Constants.TypeFlexStreamEnd:
                    if (stream != null)
                    {
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeChunkSize:
                    OnChunkSize(connection, channel, header, message as ChunkSize);
                    break;

                case Constants.TypeAudioData:
                case Constants.TypeVideoData:
                    // NOTE: If we respond to "publish" with "NetStream.Publish.BadName",
                    // the client sends a few stream packets before stopping. We need to
                    // ignore them.
                    if (stream != null)
                    {
                        ((IEventDispatcher)stream).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeServerBandwidth:
                    OnServerBW(connection, channel, header, message as ServerBW);
                    break;

                case Constants.TypeClientBandwidth:
                    OnClientBW(connection, channel, header, message as ClientBW);
                    break;

                default:
                    //Console.WriteLine("Package not WORKING or SENT");
#if !SILVERLIGHT
                    if (log != null && log.IsDebugEnabled)
                    {
                        log.Debug("RtmpService event not handled: " + header.DataType);
                    }
#endif
                    break;
                }
            }
            catch (Exception ex)
            {
#if !SILVERLIGHT
                if (log.IsErrorEnabled)
                {
                    log.Error(__Res.GetString(__Res.Rtmp_HandlerError), ex);
                    log.Error(__Res.GetString(__Res.Error_ContextDump));
                    //log.Error(Environment.NewLine);
                    log.Error(packet);
                    //Console.WriteLine("PACKET ERROR");
                }
#endif
            }
        }
Ejemplo n.º 14
0
 protected virtual void WritingMessage(RtmpPacket packet)
 {
 }
Ejemplo n.º 15
0
        public override void Write(RtmpPacket packet)
        {
            if (!IsClosed)
            {
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                    log.Debug("Write " + packet.Header);
#endif
                //encode
                WritingMessage(packet);
                ByteBuffer outputStream = RtmpProtocolEncoder.Encode(Context, packet);
                Write(outputStream);
                _handler.MessageSent(this, packet);
            }
        }
Ejemplo n.º 16
0
 internal virtual void MessageSent(RtmpPacket packet)
 {
     base._writtenMessages += 1L;
 }
Ejemplo n.º 17
0
        public static RtmpPacket DecodePacket(RtmpContext context, ByteBuffer stream)
        {
            int num4;
            int num5;
            int remaining = stream.Remaining;

            if (remaining < 1)
            {
                context.SetBufferDecoding(1L);
                return(null);
            }
            int  position = (int)stream.Position;
            byte num3     = stream.Get();

            if ((num3 & 0x3f) == 0)
            {
                if (remaining < 2)
                {
                    stream.Position = position;
                    context.SetBufferDecoding(2L);
                    return(null);
                }
                num4 = ((num3 & 0xff) << 8) | (stream.Get() & 0xff);
                num5 = 2;
            }
            else if ((num3 & 0x3f) == 1)
            {
                if (remaining < 3)
                {
                    stream.Position = position;
                    context.SetBufferDecoding(3L);
                    return(null);
                }
                num4 = (((num3 & 0xff) << 0x10) | ((stream.Get() & 0xff) << 8)) | (stream.Get() & 0xff);
                num5 = 3;
            }
            else
            {
                num4 = num3 & 0xff;
                num5 = 1;
            }
            byte channelId = DecodeChannelId(num4, num5);

            if (channelId < 0)
            {
                throw new ProtocolException("Bad channel id: " + channelId);
            }
            int num8 = GetHeaderLength(DecodeHeaderSize(num4, num5)) + (num5 - 1);

            if (num8 > remaining)
            {
                if (log.get_IsDebugEnabled())
                {
                    log.Debug(__Res.GetString("Rtmp_HeaderBuffering", new object[] { remaining }));
                }
                stream.Position = position;
                context.SetBufferDecoding((long)num8);
                return(null);
            }
            stream.Position = position;
            RtmpHeader header = DecodeHeader(context, context.GetLastReadHeader(channelId), stream);

            log.Debug("Decoded header " + header);
            if (header == null)
            {
                throw new ProtocolException("Header is null, check for error");
            }
            context.SetLastReadHeader(channelId, header);
            RtmpPacket lastReadPacket = context.GetLastReadPacket(channelId);

            if (lastReadPacket == null)
            {
                lastReadPacket = new RtmpPacket(header);
                context.SetLastReadPacket(channelId, lastReadPacket);
            }
            ByteBuffer data          = lastReadPacket.Data;
            int        num9          = 0;
            int        num10         = (header.Size + num9) - ((int)data.Position);
            int        readChunkSize = context.GetReadChunkSize();
            int        numBytesMax   = (num10 > readChunkSize) ? readChunkSize : num10;

            if (stream.Remaining < numBytesMax)
            {
                if (log.get_IsDebugEnabled())
                {
                    log.Debug(__Res.GetString("Rtmp_ChunkSmall", new object[] { stream.Remaining, numBytesMax }));
                }
                stream.Position = position;
                context.SetBufferDecoding((long)(num8 + numBytesMax));
                return(null);
            }
            ByteBuffer.Put(data, stream, numBytesMax);
            if (data.Position < (header.Size + num9))
            {
                context.ContinueDecoding();
                return(null);
            }
            data.Flip();
            IRtmpEvent event2 = DecodeMessage(context, header, data);

            lastReadPacket.Message = event2;
            if (event2 is ChunkSize)
            {
                ChunkSize size = event2 as ChunkSize;
                context.SetReadChunkSize(size.Size);
            }
            context.SetLastReadPacket(channelId, null);
            return(lastReadPacket);
        }
Ejemplo n.º 18
0
 public override void Write(RtmpPacket packet)
 {
     _lock.AcquireReaderLock();
     try
     {
         if (IsClosed || IsClosing)
             return;
     }
     finally
     {
         _lock.ReleaseReaderLock();
     }
     try
     {
         _lock.AcquireWriterLock();
         ByteBuffer data;
         try
         {
             data = RtmpProtocolEncoder.Encode(this.Context, packet);
         }
         catch (Exception ex)
         {
             log.Error("Could not encode message " + packet, ex);
             return;
         }
         // Mark packet as being written
         WritingMessage(packet);
         if (_pendingMessages == null)
             _pendingMessages = new LinkedList();
         _pendingMessages.Add(new PendingData(data, packet));
     }
     finally
     {
         _lock.ReleaseWriterLock();
     }
 }
Ejemplo n.º 19
0
		public static ByteBuffer EncodePacket(RtmpContext context, RtmpPacket packet) 
		{
			RtmpHeader header = packet.Header;
			int channelId = header.ChannelId;
			IRtmpEvent message = packet.Message;
			ByteBuffer data;

			if (message is ChunkSize)
			{
				ChunkSize chunkSizeMsg = (ChunkSize)message;
				context.SetWriteChunkSize(chunkSizeMsg.Size);
			}

			data = EncodeMessage(context, header, message);

			if(data.Position != 0) 
				data.Flip();
			else 
				data.Rewind();
			header.Size = (int)data.Limit;

			RtmpHeader lastHeader = context.GetLastWriteHeader(channelId);
			int headerSize = CalculateHeaderSize(header, lastHeader);
			context.SetLastWriteHeader(channelId, header);
			context.SetLastWritePacket(channelId, packet);

			int chunkSize = context.GetWriteChunkSize();
			int chunkHeaderSize = 1;
			if (header.ChannelId > 320)
				chunkHeaderSize = 3;
			else if (header.ChannelId > 63)
				chunkHeaderSize = 2;
			int numChunks = (int)Math.Ceiling(header.Size / (float)chunkSize);
			int bufSize = (int)header.Size + headerSize + (numChunks > 0 ? (numChunks - 1) * chunkHeaderSize : 0);
			ByteBuffer output = ByteBuffer.Allocate(bufSize);
			
			EncodeHeader(header, lastHeader, output);

			if (numChunks == 1) 
			{
				// we can do it with a single copy
				ByteBuffer.Put(output, data, output.Remaining);
			}
			else 
			{
				for(int i = 0; i < numChunks - 1; i++) 
				{
					ByteBuffer.Put(output, data, chunkSize);
					EncodeHeaderByte(output, (byte)HeaderType.HeaderContinue, header.ChannelId);
				}
				ByteBuffer.Put(output, data, output.Remaining);
			}
			//data.Close();
			output.Flip();
			return output;
		}
Ejemplo n.º 20
0
        public static ByteBuffer EncodePacket(RtmpContext context, RtmpPacket packet)
        {
            RtmpHeader header    = packet.Header;
            int        channelId = header.ChannelId;
            IRtmpEvent message   = packet.Message;
            ByteBuffer data;

            if (message is ChunkSize)
            {
                ChunkSize chunkSizeMsg = (ChunkSize)message;
                context.SetWriteChunkSize(chunkSizeMsg.Size);
            }

            data = EncodeMessage(context, header, message);

            if (data.Position != 0)
            {
                data.Flip();
            }
            else
            {
                data.Rewind();
            }
            header.Size = (int)data.Limit;

            RtmpHeader lastHeader = context.GetLastWriteHeader(channelId);
            int        headerSize = CalculateHeaderSize(header, lastHeader);

            context.SetLastWriteHeader(channelId, header);
            context.SetLastWritePacket(channelId, packet);

            int chunkSize       = context.GetWriteChunkSize();
            int chunkHeaderSize = 1;

            if (header.ChannelId > 320)
            {
                chunkHeaderSize = 3;
            }
            else if (header.ChannelId > 63)
            {
                chunkHeaderSize = 2;
            }
            int        numChunks = (int)Math.Ceiling(header.Size / (float)chunkSize);
            int        bufSize   = (int)header.Size + headerSize + (numChunks > 0 ? (numChunks - 1) * chunkHeaderSize : 0);
            ByteBuffer output    = ByteBuffer.Allocate(bufSize);

            EncodeHeader(header, lastHeader, output);

            if (numChunks == 1)
            {
                // we can do it with a single copy
                ByteBuffer.Put(output, data, output.Remaining);
            }
            else
            {
                for (int i = 0; i < numChunks - 1; i++)
                {
                    ByteBuffer.Put(output, data, chunkSize);
                    EncodeHeaderByte(output, (byte)HeaderType.HeaderContinue, header.ChannelId);
                }
                ByteBuffer.Put(output, data, output.Remaining);
            }
            //data.Close();
            output.Flip();
            return(output);
        }
Ejemplo n.º 21
0
		public override void Write(RtmpPacket packet)
		{
            _lock.AcquireReaderLock();
            try
            {
                if (IsClosed || IsClosing || IsDisconnecting)
                    return; // Already shutting down.
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }
            if (log.IsDebugEnabled)
                log.Debug(__Res.GetString(__Res.Rtmp_WritePacket, _connectionId, packet));

            if (!this.IsTunneled)
            {
                //encode
                WritingMessage(packet);
                ByteBuffer outputStream = null;
                _lock.AcquireWriterLock();
                try
                {
                    outputStream = RtmpProtocolEncoder.Encode(this.Context, packet);
                }
                finally
                {
                    _lock.ReleaseWriterLock();
                }
                Write(outputStream);
                _rtmpServer.RtmpHandler.MessageSent(this, packet);
            }
            else
            {
                //We should never get here
                System.Diagnostics.Debug.Assert(false);
            }
		}
        /// <summary>
        /// Decodes a RTMP packet.
        /// </summary>
        /// <param name="context">RTMP protocol state.</param>
        /// <param name="stream">Buffer to be decoded.</param>
        /// <returns>The decoded RTMP packet.</returns>
        public static RtmpPacket DecodePacket(RtmpContext context, ByteBuffer stream)
        {
            int remaining = stream.Remaining;

            // We need at least one byte
            if (remaining < 1)
            {
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 1));
                }
#endif
                context.SetBufferDecoding(1);
                return(null);
            }
            int  position   = (int)stream.Position;
            byte headerByte = stream.Get();
            int  headerValue;
            int  byteCount;
            if ((headerByte & 0x3f) == 0)
            {
                // Two byte header
                if (remaining < 2)
                {
                    stream.Position = position;
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 2));
                    }
#endif
                    context.SetBufferDecoding(2);
                    return(null);
                }
                headerValue = ((int)headerByte & 0xff) << 8 | ((int)stream.Get() & 0xff);
                byteCount   = 2;
            }
            else if ((headerByte & 0x3f) == 1)
            {
                // Three byte header
                if (remaining < 3)
                {
                    stream.Position = position;
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 3));
                    }
#endif
                    context.SetBufferDecoding(3);
                    return(null);
                }
                headerValue = ((int)headerByte & 0xff) << 16 | ((int)stream.Get() & 0xff) << 8 | ((int)stream.Get() & 0xff);
                byteCount   = 3;
            }
            else
            {
                // Single byte header
                headerValue = (int)headerByte & 0xff;
                byteCount   = 1;
            }
            byte channelId = DecodeChannelId(headerValue, byteCount);
            if (channelId < 0)
            {
                throw new ProtocolException("Bad channel id: " + channelId);
            }
            byte headerSize   = DecodeHeaderSize(headerValue, byteCount);
            int  headerLength = GetHeaderLength(headerSize);
            headerLength += byteCount - 1;

            //if(headerLength > remaining)
            if (headerLength + byteCount - 1 > remaining)
            {
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(__Res.GetString(__Res.Rtmp_HeaderBuffering, remaining));
                }
#endif
                stream.Position = position;
                //context.SetBufferDecoding(headerLength);
                context.SetBufferDecoding(headerLength + byteCount - 1);
                return(null);
            }
            // Move the position back to the start
            stream.Position = position;

            RtmpHeader header = DecodeHeader(context, context.GetLastReadHeader(channelId), stream);
#if !SILVERLIGHT
            log.Debug("Decoded " + header);
#endif

            if (header == null)
            {
                throw new ProtocolException("Header is null, check for error");
            }

            // Save the header
            context.SetLastReadHeader(channelId, header);
            // Check to see if this is a new packet or continue decoding an existing one.
            RtmpPacket packet = context.GetLastReadPacket(channelId);
            if (packet == null)
            {
                packet = new RtmpPacket(header);
                context.SetLastReadPacket(channelId, packet);
            }

            ByteBuffer buf     = packet.Data;
            int        addSize = (header.Timer == 0xffffff ? 4 : 0);
            //int addSize = 0;
            int readRemaining = header.Size + addSize - (int)buf.Position;
            int chunkSize     = context.GetReadChunkSize();
            int readAmount    = (readRemaining > chunkSize) ? chunkSize : readRemaining;
            if (stream.Remaining < readAmount)
            {
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(__Res.GetString(__Res.Rtmp_ChunkSmall, stream.Remaining, readAmount));
                }
#endif
                //Skip the position back to the start
                stream.Position = position;
                context.SetBufferDecoding(headerLength + readAmount);

                //string path = FluorineFx.Context.FluorineContext.Current.GetFullPath(@"log\chunk.bin");
                //stream.Dump(path);
                return(null);
            }

            //http://osflash.org/pipermail/free_osflash.org/2005-September/000261.html
            //http://www.acmewebworks.com/Downloads/openCS/091305-initialMeeting.txt
            ByteBuffer.Put(buf, stream, readAmount);
            if (buf.Position < header.Size + addSize)
            {
                context.ContinueDecoding();
                return(null);
            }
            if (buf.Position > header.Size + addSize)
            {
#if !SILVERLIGHT
                log.Warn(string.Format("Packet size expanded from {0} to {1} ({2})", header.Size + addSize, buf.Position, header));
#endif
            }

            buf.Flip();

            try
            {
                IRtmpEvent message = DecodeMessage(context, packet.Header, buf);
                packet.Message = message;

                if (message is ChunkSize)
                {
                    ChunkSize chunkSizeMsg = message as ChunkSize;
                    context.SetReadChunkSize(chunkSizeMsg.Size);
                }
            }
            finally
            {
                context.SetLastReadPacket(channelId, null);
            }
#if !SILVERLIGHT
            if (log.IsDebugEnabled)
            {
                log.Debug("Decoded " + packet.ToString());
            }
#endif
            return(packet);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Write a RTMP packet.
        /// </summary>
        /// <param name="packet">The RTMP packet.</param>
		public abstract void Write(RtmpPacket packet);
Ejemplo n.º 24
0
 public PendingData(object buffer, RtmpPacket packet)
 {
     _buffer = buffer;
     _packet = packet;
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Mark message as being written.
 /// </summary>
 /// <param name="packet">The RTMP packet</param>
 protected virtual void WritingMessage(RtmpPacket packet)
 {
     if (packet.Message is VideoData)
     {
         int streamId = packet.Header.StreamId;
         AtomicInteger value = new AtomicInteger();
         AtomicInteger old = _pendingVideos.AddIfAbsent(streamId, value) as AtomicInteger;
         if (old == null)
             old = value;
         old.Increment();
     }
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Writes packet from event data to the RTMP connection using the specified stream id.
        /// </summary>
        /// <param name="message">Event data.</param>
        /// <param name="streamId">Stream id.</param>
        private void Write(IRtmpEvent message, int streamId) 
		{
			RtmpHeader header = new RtmpHeader();
			RtmpPacket packet = new RtmpPacket(header, message);

			header.ChannelId = _channelId;
			header.Timer = message.Timestamp;
			header.StreamId = streamId;
			header.DataType = message.DataType;
            if( message.Header != null )
			    header.IsTimerRelative =  message.Header.IsTimerRelative;
			_connection.Write(packet);
		}
Ejemplo n.º 27
0
        /// <summary>
        /// Decodes a RTMP packet.
        /// </summary>
        /// <param name="context">RTMP protocol state.</param>
        /// <param name="stream">Buffer to be decoded.</param>
        /// <returns>The decoded RTMP packet.</returns>
		public static RtmpPacket DecodePacket(RtmpContext context, ByteBuffer stream)
		{
			int remaining = stream.Remaining;
			// We need at least one byte
			if(remaining < 1) 
            {
#if !SILVERLIGHT
                if( log.IsDebugEnabled )
                    log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 1));
#endif
				context.SetBufferDecoding(1);
				return null;
			}
			int position = (int)stream.Position;
			byte headerByte = stream.Get();
			int headerValue;
			int byteCount;
			if((headerByte & 0x3f) == 0) 
			{
				// Two byte header
				if (remaining < 2) 
				{
					stream.Position = position;
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                        log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 2));
#endif
					context.SetBufferDecoding(2);
					return null;
				}
				headerValue = ((int) headerByte & 0xff) << 8 | ((int) stream.Get() & 0xff); 
				byteCount = 2;
			} else if ((headerByte & 0x3f) == 1) {
				// Three byte header
				if (remaining < 3)
				{
					stream.Position = position;
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                        log.Debug(__Res.GetString(__Res.Rtmp_DataBuffering, remaining, 3));
#endif
                    context.SetBufferDecoding(3);
					return null;
				}
				headerValue = ((int) headerByte & 0xff) << 16 | ((int) stream.Get() & 0xff) << 8 | ((int) stream.Get() & 0xff); 
				byteCount = 3;
			} else {
				// Single byte header
				headerValue = (int) headerByte & 0xff;
				byteCount = 1;
			}
			byte channelId = DecodeChannelId(headerValue, byteCount);
			if (channelId < 0) 
				throw new ProtocolException("Bad channel id: " + channelId);
			byte headerSize = DecodeHeaderSize(headerValue, byteCount);
			int headerLength = GetHeaderLength(headerSize);
			headerLength += byteCount - 1;

			//if(headerLength > remaining) 
            if (headerLength + byteCount - 1 > remaining)
            {
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                    log.Debug(__Res.GetString(__Res.Rtmp_HeaderBuffering, remaining));
#endif
                stream.Position = position;
                //context.SetBufferDecoding(headerLength);
                context.SetBufferDecoding(headerLength + byteCount - 1);
                return null;
            }
			// Move the position back to the start
			stream.Position = position;

			RtmpHeader header = DecodeHeader(context, context.GetLastReadHeader(channelId), stream);
#if !SILVERLIGHT
            log.Debug("Decoded " + header);
#endif

			if (header == null) 
				throw new ProtocolException("Header is null, check for error");

			// Save the header
			context.SetLastReadHeader(channelId, header);
			// Check to see if this is a new packet or continue decoding an existing one.
			RtmpPacket packet = context.GetLastReadPacket(channelId);
			if(packet == null) 
			{
				packet = new RtmpPacket(header);
				context.SetLastReadPacket(channelId, packet);
			}

			ByteBuffer buf = packet.Data;
			int addSize = (header.Timer == 0xffffff ? 4 : 0);
            //int addSize = 0;
			int readRemaining = header.Size + addSize - (int)buf.Position;
			int chunkSize = context.GetReadChunkSize();
			int readAmount = (readRemaining > chunkSize) ? chunkSize : readRemaining;
			if(stream.Remaining < readAmount) 
			{
#if !SILVERLIGHT
                if( log.IsDebugEnabled )
					log.Debug(__Res.GetString(__Res.Rtmp_ChunkSmall, stream.Remaining, readAmount));
#endif
				//Skip the position back to the start
				stream.Position = position;
				context.SetBufferDecoding(headerLength + readAmount);
				
				//string path = FluorineFx.Context.FluorineContext.Current.GetFullPath(@"log\chunk.bin");
				//stream.Dump(path);
				return null;
			}
			
			//http://osflash.org/pipermail/free_osflash.org/2005-September/000261.html
			//http://www.acmewebworks.com/Downloads/openCS/091305-initialMeeting.txt
			ByteBuffer.Put(buf, stream, readAmount);
			if(buf.Position < header.Size + addSize) 
			{
				context.ContinueDecoding();
				return null;
			}
            if (buf.Position > header.Size + addSize)
            {
#if !SILVERLIGHT
                log.Warn(string.Format("Packet size expanded from {0} to {1} ({2})", header.Size + addSize, buf.Position, header));
#endif
            }

			buf.Flip();

            try
            {
                IRtmpEvent message = DecodeMessage(context, packet.Header, buf);
                packet.Message = message;

                if (message is ChunkSize)
                {
                    ChunkSize chunkSizeMsg = message as ChunkSize;
                    context.SetReadChunkSize(chunkSizeMsg.Size);
                }
            }
            finally
            {
                context.SetLastReadPacket(channelId, null);
            }
#if !SILVERLIGHT
            if (log.IsDebugEnabled)
            {
                log.Debug("Decoded " + packet.ToString());
            }
#endif
			return packet;
		}
Ejemplo n.º 28
0
 internal void SetLastWritePacket(int channelId, RtmpPacket packet)
 {
     try
     {
         ReaderWriterLock.AcquireWriterLock();
         RtmpPacket prevPacket = null;
         if (_writePackets.ContainsKey(channelId))
             prevPacket = _writePackets[channelId] as RtmpPacket;
         if (prevPacket != null && prevPacket.Data != null)
         {
             prevPacket.Data = null;
         }
         _writePackets[channelId] = packet;
     }
     finally
     {
         ReaderWriterLock.ReleaseWriterLock();
     }
 }
Ejemplo n.º 29
0
        public void MessageReceived(RtmpConnection connection, object obj)
        {
            IRtmpEvent evt = null;

            try
            {
                RtmpPacket packet = obj as RtmpPacket;
                evt = packet.Message;
                RtmpHeader    source     = packet.Header;
                RtmpChannel   channel    = connection.GetChannel(source.ChannelId);
                IClientStream streamById = null;
                if (connection is IStreamCapableConnection)
                {
                    streamById = (connection as IStreamCapableConnection).GetStreamById(source.StreamId);
                }
                FluorineContext.Current.Connection.SetAttribute("__@fluorinestreamid", source.StreamId);
                connection.MessageReceived();
                if ((log != null) && log.get_IsDebugEnabled())
                {
                    log.Debug("RtmpConnection message received, type = " + source.DataType);
                }
                if (evt != null)
                {
                    evt.Source = connection;
                }
                switch (source.DataType)
                {
                case 1:
                    this.OnChunkSize(connection, channel, source, evt as ChunkSize);
                    return;

                case 3:
                    this.OnStreamBytesRead(connection, channel, source, evt as BytesRead);
                    return;

                case 4:
                    this.OnPing(connection, channel, source, evt as Ping);
                    return;

                case 5:
                    this.OnServerBW(connection, channel, source, evt as ServerBW);
                    return;

                case 6:
                    this.OnClientBW(connection, channel, source, evt as ClientBW);
                    return;

                case 8:
                case 9:
                    if (streamById != null)
                    {
                        ((IEventDispatcher)streamById).DispatchEvent(evt);
                    }
                    return;

                case 15:
                    if (streamById != null)
                    {
                        (streamById as IEventDispatcher).DispatchEvent(evt);
                    }
                    return;

                case 0x10:
                case 0x13:
                    this.OnSharedObject(connection, channel, source, evt as SharedObjectMessage);
                    return;

                case 0x11:
                    this.OnFlexInvoke(connection, channel, source, evt as FlexInvoke);
                    if ((((evt.Header.StreamId != 0) && ((evt as Invoke).ServiceCall.ServiceName == null)) && ((evt as Invoke).ServiceCall.ServiceMethodName == "publish")) && (streamById != null))
                    {
                        (streamById as IEventDispatcher).DispatchEvent(evt);
                    }
                    return;

                case 0x12:
                    if (((evt as Notify).Data == null) || (streamById == null))
                    {
                        break;
                    }
                    (streamById as IEventDispatcher).DispatchEvent(evt);
                    return;

                case 20:
                    this.OnInvoke(connection, channel, source, evt as Invoke);
                    if ((((evt.Header.StreamId != 0) && ((evt as Invoke).ServiceCall.ServiceName == null)) && ((evt as Invoke).ServiceCall.ServiceMethodName == "publish")) && (streamById != null))
                    {
                        (streamById as IEventDispatcher).DispatchEvent(evt);
                    }
                    return;

                default:
                    goto Label_0304;
                }
                this.OnInvoke(connection, channel, source, evt as Notify);
                return;

Label_0304:
                if ((log != null) && log.get_IsDebugEnabled())
                {
                    log.Debug("RtmpService event not handled: " + source.DataType);
                }
            }
            catch (Exception exception)
            {
                log.Error("Runtime error", exception);
            }
        }