Example #1
0
        private FrameBlock GetBlockFromImage(byte[] image, int blockX, int blockY)
        {
            FrameBlock block = frameBlockPool.GetNext();

            block.BlockX = (byte)blockX;
            if (stride <= 0)
            {
                block.BlockY = (byte)(verticalBlocks - blockY - 1);                 // Reverse the y-axis because the image is upside down.
            }
            else
            {
                block.BlockY = (byte)blockY;
            }

            int startingOffset = (blockX * BlockSizeInBytes) + (blockY * horizontalBlocks * TotalBlockSizeInBytes);

            for (int line = 0; line < BlockSize; line++)
            {
                int sampleLine;
                if (stride <= 0)
                {
                    sampleLine = BlockSize - line - 1;                     // Reverse the y axis because the image is upside down.
                }
                else
                {
                    sampleLine = line;
                }
                int sourceStartPos = startingOffset + (sampleLine * widthInBytes);
                int destStartPos   = line * BlockSizeInBytes;
                Buffer.BlockCopy(image, sourceStartPos, block.RgbaRaw, destStartPos, BlockSizeInBytes);
            }
            return(block);
        }
Example #2
0
        public void WriteSamples(Array samples, int start, int dataLength, ushort sequenceNumber, AudioCodecType audioCodecType, bool isSilent)
        {
            // Only write the frame to the queue if it's newer than the most recently played frame.
            // This particular way of checking will miss some out-of-order packets if they occur right when a wrap-around
            // is happening, but not many.

            if (sequenceNumber > _lastSequenceNumberRead ||
                _lastSequenceNumberRead < lowEndWrapAround ||
                _lastSequenceNumberRead > highEndWrapAround ||
                sequenceNumber < lowEndWrapAround ||
                sequenceNumber > highEndWrapAround)
            {
                var entry = _entryPool.GetNext();
                Buffer.BlockCopy(samples, start, entry.Frame, 0, dataLength);
                entry.DataLength     = dataLength / sizeof(short);
                entry.SequenceNumber = sequenceNumber;
                entry.AudioCodecType = audioCodecType;
                entry.IsSilent       = isSilent;
                lock (_queue)
                {
                    _queue.Enqueue(entry);
                }
                _logger.LogWrite();
            }
            else
            {
                _logger.LogWriteOutOfOrder();
            }
        }
Example #3
0
        public FrameBlock[] ParseChunk(ByteStream chunk, ushort remoteSsrcId)
        {
            byte numBlocks = chunk.Data[0];

            // ks 7/18/11 - This seems like an odd place to do it, but I can't think of a better one.
            _videoQualityController.LogReceivedVideoQuality(remoteSsrcId, (VideoQuality)chunk.Data[1], (VideoQuality)chunk.Data[2]);

            byte jpegQuality = chunk.Data[3];

            Debug.Assert(jpegQuality > 0 && jpegQuality <= 100);

            chunk.CurrentOffset = ChunkHeaderLength;
            var blocks = new FrameBlock[numBlocks];

            for (int i = 0; i < numBlocks; i++)
            {
                var block = _frameBlockPool.GetNext();
                block.JpegQuality = jpegQuality;
                block.BlockX      = chunk.ReadByte();
                block.BlockY      = chunk.ReadByte();
                block.BlockType   = (BlockType)chunk.ReadByte();
                short payloadLength = chunk.ReadInt16();
                Debug.Assert(payloadLength > 0, "The payloadLength must be greater than 0");
                block.EncodedStream  = new MemoryStream(chunk.Data, chunk.CurrentOffset, payloadLength);
                chunk.CurrentOffset += payloadLength;
                blocks[i]            = block;
            }
            return(blocks);
        }
Example #4
0
        public static List <RtpPacketData> GetPacketsFromData(ByteStream buffer, IObjectPool <List <RtpPacketData> > rtpPacketDataListPool, IObjectPool <RtpPacketData> rtpPacketDataPool)
        {
            // Retrieve the list from an object pool (rather than creating a new one each time that has to be garbage-collected).
            var packets = rtpPacketDataListPool.GetNext();

            while (buffer.CurrentOffset < buffer.EndOffset)
            {
                RtpPacketData  packet = rtpPacketDataPool.GetNext();
                RtpParseResult result = packet.ParsePacket(buffer);

                switch (result)
                {
                case RtpParseResult.Success:
                    // Add the packet to the list and continue processing.
                    packets.Add(packet);
                    break;

                case RtpParseResult.DataIncomplete:
                    // Tell the calling function that it can reuse the buffer after position <length>.
                    // Move the data to the beginning of the buffer (so that we can get it next time) and stop parsing.
                    Debug.Assert(buffer.CurrentOffset >= 0, "The current offset cannot be negative.");
                    Debug.Assert(buffer.RemainingBytes >= 0, "The remaining bytes cannot be negative.");
                    Buffer.BlockCopy(buffer.Data, buffer.CurrentOffset, buffer.Data, 0, buffer.RemainingBytes);
                    buffer.DataLength    = buffer.RemainingBytes;
                    buffer.DataOffset    = 0;
                    buffer.CurrentOffset = 0;
                    return(packets);

                case RtpParseResult.DataInvalid:
                    // Don't add the current packet to the list, but continue processing at the current position.
                    break;
                }
            }
            // If this is our exit point, tell the calling function that it can reuse the entire buffer.
            buffer.DataLength    = 0;
            buffer.CurrentOffset = 0;
            return(packets);
        }