Пример #1
0
        public void DecodeChunk(ByteStream frame, ushort remoteSsrcId)
        {
            var blocks = _chunkHelper.ParseChunk(frame, remoteSsrcId);

            foreach (var block in blocks)
            {
                _decodedFrame.ProcessBlock(block);
                _frameBlockPool.Recycle(block);
            }
        }
Пример #2
0
        public void DoReset()
        {
            List <AbstractPathNode> tmp = new List <AbstractPathNode>();

            foreach (AbstractPathNode pathNode in Nodes)
            {
                tmp.Add(pathNode);
            }
            foreach (AbstractPathNode node in tmp)
            {
                pool.Recycle(node);
            }
            o   = Vector3.zero;
            way = Way.Forward;
            targetOrigin.SetTransform(target);
            D.Value = 0;
            resetEvent.Invoke();
        }
Пример #3
0
    IEnumerator WaitForRecycle()
    {
        yield return(new WaitForSeconds(duration));

        if (pool != null)
        {
            pool.Recycle(this);
        }
        this.gameObject.SetActive(false);
    }
Пример #4
0
 public void InsertBlock(FrameBlock newBlock, int index)
 {
     frameBlockPool.Recycle(FrameBlocks[index]);
     newBlock.ReferenceCount++;
     FrameBlocks[index] = newBlock;
 }
Пример #5
0
        // private double _doubleReadCounter;
        // private int _doubleReadFloor;

        #endregion

        #region Methods

        /// <returns>Length *in shorts* of the decoded data</returns>
        public int ReadSamples(short[] outputBuffer)
        {
            int  length   = 0;
            bool isSilent = false;

            lock (_queue)
            {
                // If there are too many frames in the queue, pull them out one by one and decode them (so the speex buffer stays OK),
                // but don't bother playing them.  This is a case where downsampling would be helpful, but we'll ignore it for now.
                while (_queue.Count > queuedFramesTargetMax)
                {
                    _logger.LogQueueFull();
                    var entry = _queue.Dequeue();
                    AudioDecoder = _codecFactory.GetAudioDecoder(entry.AudioCodecType);
                    AudioDecoder.Decode(entry.Frame, 0, entry.DataLength, outputBuffer, length, entry.IsSilent);
                    _entryPool.Recycle(entry);
                    _videoQualityController.LogGlitch(1);
                }

                // If we haven't lost any frames since the last check, pull one frame out of the queue to reduce latency.
                // This is a case where downsampling would be helpful, but we'll ignore it for now.
                if (++_framesSinceLastCheck > _framesBetweenChecks && _firstPacketReceived)
                {
                    // Keep a record of the queue size, so that we can know how "bad" it is when we miss a packet.
                    // It's not a big deal to miss a read when the queue size is stable at < 4 frames,
                    // but it's a pretty big deal when the queue size is jumping around between 0 and 50.
                    while (_queueSizes.Count > maxQueueSizeEntries)
                    {
                        _queueSizes.RemoveAt(0);
                    }
                    _queueSizes.Add(_queue.Count);

                    if (_framesLostSinceLastCheck == 0 && _queue.Count > queuedFramesTargetMin)
                    {
                        var entry = _queue.Dequeue();
                        AudioDecoder = _codecFactory.GetAudioDecoder(entry.AudioCodecType);
                        AudioDecoder.Decode(entry.Frame, 0, entry.DataLength, outputBuffer, length, entry.IsSilent);
                        _entryPool.Recycle(entry);

                        if (_framesBetweenChecks > framesBetweenChecksMin)
                        {
                            _framesBetweenChecks -= goodTrafficAdjustment;                             // Speed up (slightly) the rate at which we can decrease the queue size.
                        }
                        _logger.LogQueueReduced();
                    }
                    _framesLostSinceLastCheck = 0;
                    _framesSinceLastCheck     = 0;
                }

                // Calculate the number of packets we should retrieve.
                // Here's the logic. Let's say that we're only reading packets every 23.3 milliseconds instead of every 20 milliseconds.
                // This means that for about 3.3/20 = 16.5% of the reads, we actually need to request *two* packets.
                // So each time we read, we add .165 to a counter, and then take its floor. As soon as the counter floor
                // rolls over to a new integer, we know that we need to read a second packet.
                // Unfortunately, dammit, it doesn't look like this works. We'll need to create a better approach,
                // presumably using a resampler.

                //_doubleReadCounter += _logger.OverageRatio;
                //int packetsToRead = 1;
                //var newDoubleReadFloor = (int)Math.Floor(_doubleReadCounter);
                //if (newDoubleReadFloor > _doubleReadFloor)
                //{
                //    packetsToRead += newDoubleReadFloor - _doubleReadFloor;
                //    _doubleReadFloor = newDoubleReadFloor;
                //    _logger.LogMultipleRead();
                //}

                //for (int i = 0; i < packetsToRead; i++)
                {
                    if (_queue.Count > 0)
                    {
                        // If we have anything in the queue, fulfill the request.
                        var entry = _queue.Dequeue();
                        isSilent = entry.IsSilent;
                        _lastSequenceNumberRead = entry.SequenceNumber;
                        AudioDecoder            = _codecFactory.GetAudioDecoder(entry.AudioCodecType);

                        length += AudioDecoder.Decode(entry.Frame, 0, entry.DataLength, outputBuffer, length, entry.IsSilent);
                        _entryPool.Recycle(entry);
                        _firstPacketReceived = true;
                    }
                    else
                    {
                        // Record the fact that we missed a read, so the rest of the system can adjust.
                        _logger.LogQueueEmpty();
                        if (_firstPacketReceived)
                        {
                            double stdDev = DspHelper.GetStandardDeviation(_queueSizes);
                            _videoQualityController.LogGlitch((int)Math.Floor(stdDev) + 1);
                        }

                        // If the frame hasn't arrived yet, let the last audio codec interpolate the missing packet.
                        // Most likely, the additional frames will arrive in a bunch by the time the next read happens.
                        // We may want to investigate our own upsampling algorithm at some point.
                        length += AudioDecoder.Decode(null, 0, 0, outputBuffer, length, true);
                        if (_framesBetweenChecks < framesBetweenChecksMax && _firstPacketReceived)
                        {
                            _framesBetweenChecks += badTrafficAdjustment;                             // Slow down (substantially) the rate at which we decrease the queue size.
                        }
                    }
                }
            }
            _logger.LogRead(_queue, _framesBetweenChecks, isSilent);
            return(length);
        }
Пример #6
0
        public bool GetNextChunkFromQueue(Queue <FrameBlock> queue, ByteStream buffer)
        {
            byte blocks = 0;

            buffer.CurrentOffset = ChunkHeaderLength;
            short jpegQuality = 0;

            // Pull blocks from the queue and insert them into the buffer until the buffer is full or the block queue is empty.
            FrameBlock block = null;

            while (buffer.CurrentOffset < _maxChunkSize)
            {
                // See if there's room left in the current chunk for the next block.
                lock (queue)
                {
                    // Stop pulling blocks from the queue if there are no more blocks.
                    if (queue.Count == 0)
                    {
                        break;
                    }

                    // Stop pulling blocks from the queue if there's no more room in the chunk.
                    var peek = queue.Peek();
                    if ((buffer.CurrentOffset + BlockHeaderLength + peek.EncodedStream.Length) > _maxChunkSize && buffer.CurrentOffset > ChunkHeaderLength)
                    {
                        break;
                    }

                    // Stop pulling blocks from the queue if the jpegQuality has changed.
                    if ((jpegQuality > 0 && peek.JpegQuality != jpegQuality))
                    {
                        break;
                    }

                    block = queue.Dequeue();
                }
                blocks++;
                jpegQuality = block.JpegQuality;

                // Set the x,y position of the block.
                buffer.WriteByte(block.BlockX);
                buffer.WriteByte(block.BlockY);

                // Set the type of the block.
                buffer.WriteByte((byte)block.BlockType);

                // Set the size of the block.
                var streamLength = (short)block.EncodedStream.Length;
                Debug.Assert(streamLength > 0, "The length of the encoded stream must be greater than 0");
                buffer.WriteInt16(streamLength);

                // Set the actual block data.
                block.EncodedStream.Position = 0;
                block.EncodedStream.Read(buffer.Data, buffer.CurrentOffset, streamLength);
                buffer.CurrentOffset += streamLength;

                _frameBlockPool.Recycle(block);
            }

            // If we've retrieved at least one block, go back to the beginning of the buffer
            // and set the chunk header information
            if (block != null)
            {
                buffer.Data[0]    = blocks;
                buffer.Data[1]    = (byte)_videoQualityController.CommandedVideoQuality;
                buffer.Data[2]    = (byte)_videoQualityController.ProposedVideoQuality;
                buffer.Data[3]    = (byte)jpegQuality;
                buffer.DataLength = buffer.CurrentOffset;
                buffer.ResetCurrentOffset();
                return(true);
            }
            return(false);
        }