void ProcessQueue()
        {
            while (_frameQueue.Count > 0)
            {
                var frame = _frameQueue.Peek();

                // Edit mode: Wait for readback completion every frame.
                if (!Application.isPlaying)
                {
                    frame.readback.WaitForCompletion();
                }

                // Skip error frames.
                if (frame.readback.hasError)
                {
                    Debug.LogWarning("GPU readback error was detected.");
                    _frameQueue.Dequeue();
                    continue;
                }

                // Break when found a frame that hasn't been read back yet.
                if (!frame.readback.done)
                {
                    break;
                }

                // Feed the frame data to the sender. It encodes/sends the
                // frame asynchronously.
                if (OnNewFrameEventDelegate != null)
                {
                    OnNewFrameEventDelegate.Invoke(frame);
                }

                // Done. Remove the frame from the queue.
                _frameQueue.Dequeue();
            }

            // Edit mode: We're not sure when the readback buffer will be
            // disposed, so let's synchronize with the sender to prevent it
            // from accessing disposed memory area.
            if (!Application.isPlaying)
            {
                if (OnSyncFrameEventDelegate != null)
                {
                    OnSyncFrameEventDelegate.Invoke();
                }
            }
        }