private bool AssembleMessage(RtmpMessageEntry messageEntry, RtmpChunk chunk, out RtmpMessage message)
        {
            message = null;
            var currentMessage = messageEntry.Message;

            if (currentMessage == null)
            {
                var payload = _memoryPool.Rent(chunk.Message.Length);
                currentMessage       = new RtmpMessage(chunk.Header, chunk.Message, payload);
                messageEntry.Message = currentMessage;
            }

            var memory = currentMessage.Payload.Slice(messageEntry.BytesRead, chunk.PayloadLength);
            var reader = new SequenceReader <byte>(chunk.Payload);

            reader.TryCopyTo(memory.Span);
            messageEntry.BytesRead += chunk.PayloadLength;
            // if message is complete .. return it.
            if (messageEntry.BytesRemaining == 0)
            {
                message = messageEntry.Message;
                _logger.LogInformation($"Parsed message :{message.Header}: Message: {message.Message}");
                messageEntry.BytesRead = 0;
                messageEntry.Message   = null;
                return(true);
            }
            return(false);
        }
        private bool TryParseChunk(ref SequenceReader <byte> reader, out RtmpChunk chunk, out RtmpMessageEntry messageEntry)
        {
            messageEntry = null;
            chunk        = null;
            _logger.LogDebug($"Before parsing chunk: Sequence Reader Length:{reader.Length}: Consumed:{reader.Consumed}  Remaining:{reader.Remaining}");
            var header = new RtmpChunkHeader();

            if (!header.TryParse(ref reader))
            {
                return(false);
            }

            if (!_messageCache.TryGetValue(header.StreamId, out messageEntry))
            {
                messageEntry = new RtmpMessageEntry();
                _messageCache.Add(header.StreamId, messageEntry);
            }

            var message = new RtmpMessageHeader();

            if (!message.TryParse(ref reader, header.HeaderType, messageEntry.LastChunk?.Message))
            {
                return(false);
            }

            chunk = new RtmpChunk(header, message);
            if (header.HeaderType != RtmpChunkHeaderType.Type3)
            {
                messageEntry.Length    = chunk.Message.Length;
                messageEntry.BytesRead = 0;
            }
            else
            {
            }

            var chunkLength = Math.Min(messageEntry.BytesRemaining, _session.IncomingChunkLength);

            if (!chunk.TryParseBody(ref reader, chunkLength))
            {
                return(false);
            }
            _logger.LogDebug($"After parsing chunk: Sequence Reader Length:{reader.Length}: Consumed:{reader.Consumed}  Remaining:{reader.Remaining}");
            _logger.LogDebug($"Parsed chunk Header :{chunk.Header}: Message: {chunk.Message}");
            messageEntry.LastChunk = chunk;
            return(true);
        }
Example #3
0
        public IEnumerable <RtmpChunk> ChunkMessage(RtmpMessage message)
        {
            var length = message.Message.Length;
            var memory = message.Payload;
            var offset = 0;

            while (length != 0)
            {
                var chunkHeader = new RtmpChunkHeader(
                    offset == 0 ? RtmpChunkHeaderType.Type0 : RtmpChunkHeaderType.Type2,
                    message.Header.StreamId);
                var chunkLength = Math.Min(_session.OutgoingChunkLength, length);
                var chunk       = new RtmpChunk(chunkHeader, message.Message, memory.Slice(offset, chunkLength));
                yield return(chunk);

                length -= chunkLength;
                offset += chunkLength;
            }
        }
Example #4
0
        public static bool TryParseHeader(ref SequenceReader <byte> reader, out RtmpChunk chunk)
        {
            chunk = null;
            var header = new RtmpChunkHeader();

            if (!header.TryParse(ref reader))
            {
                return(false);
            }

            var message = new RtmpMessageHeader();

            if (!message.TryParse(ref reader, header.HeaderType, previous: null))
            {
                return(false);
            }

            chunk = new RtmpChunk(header, message);
            return(true);
        }
        /// <summary>
        /// Try and parse the next RTMP chunk and advance the reader.
        /// </summary>
        /// <returns>true if chunk is available else false.</returns>
        private SequencePosition?TryParseChunk(PipeReader reader, ReadOnlySequence <byte> buffer, out RtmpChunk chunk, out RtmpMessageEntry messageEntry)
        {
            var sequenceReader = new SequenceReader <byte>(buffer);

            if (!TryParseChunk(ref sequenceReader, out chunk, out messageEntry))
            {
                return(null);
            }
            return(sequenceReader.Position);
        }