public VideoBlenderContext(VideoBlenderSetup setup, PayloadPool <Frame> framePool, IStreamerBase streamer, OverloadController overloadController, Action pushPipeline)
        {
            _name               = new NodeName("VE", null, "BL", 1);
            _fps                = setup.Fps;
            _framePool          = framePool;
            _streamer           = streamer;
            _overloadController = overloadController;
            _pushPipeline       = pushPipeline;
            _delayFromRuntime   = ToTime(setup.DelayFromRuntimeFrames);  // 3 frames in client
            _pushPipelineDelay  = ToTime(setup.PushPipelineDelayFrames); // 3 frames

            Reconfigure(setup);

            _timer = _streamer.Subscribe(15, OnTimer);
            if (setup.Dx != null)
            {
                if (setup.BlendingType == BlendingType.Smart)
                {
                    _directXPipeline       = LoadPipline(BlendingType.Linear, setup.Dx);
                    _directXPipelineLowRes = LoadPipline(BlendingType.BilinearLowRes, setup.Dx);
                }
                else
                {
                    _directXPipeline = LoadPipline(setup.BlendingType, setup.Dx);
                }
            }

            _currentFpsTicks = ToTicks(Core.GetCurrentTime() - 600_000); // -60ms
        }
        public int Write(Data <Frame> data, VideoBlenderSetup setup, StatisticDataOfBlenderNode stat)
        {
            if (!ReferenceEquals(_setup, setup))
            {
                if (IsSourceChanged(_setup, setup))
                {
                    Reconfigure(setup);
                }
                _setup = setup;
            }

            if (data != null)
            {
                var sourceId = data.SourceId - _sourceIdOffset;

                if (sourceId >= 0 && sourceId < _inputRuntimes.Count)
                {
                    var queue = _inputRuntimes[sourceId].Frames;
                    queue.AddLast(data);

                    var inputStat = stat.GetInput(sourceId);
                    inputStat.InFrames++;
                    inputStat.QueueSize = queue.Count;
                    inputStat.Delay     = (Core.GetCurrentTime() - data.Payload.GetPts());

                    while (queue.Count > 60)
                    {
                        var first = queue.First.Value;
                        queue.RemoveFirst();
                        _streamer.FramePool.Back(first.Payload);
                        Core.LogWarning($"Removing frame from {sourceId} due to queue > 60", "Removing frame from");
                    }
                }
                else
                {
                    _streamer.FramePool.Back(data.Payload);
                    Core.LogWarning($"Unexpected source Id {sourceId}");
                }
            }
            return(0);
        }