コード例 #1
0
        public TContext PrepareVersion(UpdateVersionContext update, ISourceQueue <TInput> inputQueue, ITargetQueue <TOutput> outputQueue, TContextConfig setup, Action <TContext, bool> prepareContext = null, int uniqueVersionsLimit = int.MaxValue)
        {
            update.RuntimeConfig.Add(this, setup);

            var  last          = _versions.Last?.Value;// no need to sync as it is changed from the same thread
            bool sameConfig    = last != null && last.ContextSetup.Equals(setup);
            int  uniqueVersion = last?.UniqueContextVersion ?? 0;

            if (!sameConfig)
            {
                uniqueVersion++;
                if (last != null)
                {
                    Core.LogInfo($"Change {Name}: {last.ContextSetup} >> {setup}");
                }
                else
                {
                    Core.LogInfo($"Change {Name}:  >> {setup}");
                }
            }

            var ctx = sameConfig ? last.Context.AddRef() : CreateAndOpenContextRef(setup);
            ContextVersion <TContext, TContextConfig, TOutput> pending = new ContextVersion <TContext, TContextConfig, TOutput>
            {
                Version              = update.Version,
                Context              = ctx,
                ContextSetup         = setup,
                OutputQueue          = outputQueue,
                UniqueContextVersion = uniqueVersion
            };

            update.AddDeploy(() =>
            {
                lock (this)
                {
                    if (_versions.Last != null)
                    {
                        _versions.Last.Value.TimeWhenOutdated = DateTime.UtcNow;
                    }
                    _versions.AddLast(pending);

                    InputQueue = inputQueue;
                    if (inputQueue != null)
                    {
                        InputQueue.OnChanged = Activate;
                    }

                    prepareContext?.Invoke(pending.Context.Instance, sameConfig);
                    _uniqueVersionsLimit = uniqueVersionsLimit;
                    TryRemoveOldVersions();
                }
            });
            return(pending.Context.Instance);
        }
コード例 #2
0
        public TContext PrepareVersion(UpdateVersionContext version, int instances, ISourceQueue <TInput> inputQueue, Func <UpdateVersionContext, Node <TContext, TContextConfig, TInput, TOutput>, TContext> prepareContext)
        {
            version.RuntimeConfig.Add(this, null);

            var pendingNodesToAdd = new List <Node <TContext, TContextConfig, TInput, TOutput> >();

            if (_nodes.Count != instances)
            {
                Core.LogInfo($"Changing number of pooled nodes for {Name} from {_nodes.Count} to {instances}");
            }

            while (_nodes.Count + pendingNodesToAdd.Count < instances)
            {
                var newNode = _creator(_nodes.Count + pendingNodesToAdd.Count);
                pendingNodesToAdd.Add(newNode);
            }

            TContext result = default;

            foreach (var item in _nodes)
            {
                result = prepareContext(version, item);
            }

            foreach (var item in pendingNodesToAdd)
            {
                result = prepareContext(version, item);
            }

            version.AddDeploy(() =>
            {
                lock (this)
                {
                    InputQueue           = inputQueue;
                    InputQueue.OnChanged = ActivateFromPool;

                    pendingNodesToAdd.ForEach(s => _runtimeNodes.Push(s));
                    _nodes.AddRange(pendingNodesToAdd);
                    while (_nodes.Count > instances)
                    {
                        _nodesToRemove.Add(_nodes[0]);
                        _nodes.RemoveAt(0);
                    }
                }
            });

            return(result);
        }
コード例 #3
0
        public bool PrepareVersion(UpdateVersionContext update, OutputSetup setup, IBitrateController bitrateController)
        {
            if (bitrateController != null && _bitrateController == null)
            {
                bitrateController.InitOutput(_reader);
            }
            _bitrateController = bitrateController;

            update.RuntimeConfig.Add(this, setup);
            var last = _currentContext;

            bool sameConfig = last != null && last.ContextSetup.Equals(setup);

            if (!sameConfig)
            {
                Core.LogInfo($"Change {Name}: {last?.ContextSetup} >> {setup}");
            }

            int version = update.Version;

            update.AddDeploy(() =>
            {
                lock (this)
                {
                    if (sameConfig)
                    {
                        _pendingContext = new OutputContextVersion
                        {
                            Version      = last.Version,
                            MaxVersion   = version,
                            ContextSetup = setup,
                            Context      = last.Context.AddRef()
                        };
                    }
                    else
                    {
                        _pendingContext = new OutputContextVersion
                        {
                            Version       = last == null ? version - 1 : version, // we assume that this output is just added - so accept previous version from the output queue
                            MaxVersion    = version,
                            ContextSetup  = setup,
                            Context       = new RefCounted <OutputContext>(new OutputContext()),
                            WaitForIFrame = 125 // in case fps=60 -> gop = 120. we add 5.
                        };

                        if (_currentContext != null && _currentContext.Context != null)
                        {
                            _currentContext.Context.Instance.Interrupt();
                        }
                    }
                }

                if (!_continueProcessing)
                {
                    _continueProcessing = true;
                    _thread.Start();
                }
            });

            return(!sameConfig);
        }
コード例 #4
0
        public IInputContext PrepareVersion(UpdateVersionContext update, ITargetQueue <Packet> outputQueue, InputSetup setup)
        {
            update.RuntimeConfig.Add(this, setup);
            update.AddDeploy(() =>
            {
                bool startOpenThread = false;
                lock (this)
                {
                    var last        = _inputThreadCurrentContext;
                    bool sameConfig = last != null && last.ContextSetup.Equals(setup);
                    bool sameDevice = last != null && last.ContextSetup.Input.Equals(setup.Input);
                    if (!sameConfig)
                    {
                        Core.LogInfo($"Change {_name}: {last?.ContextSetup} >> {setup}");
                    }

                    int version = update.Version;
                    var ver     = new ContextVersion <IInputContext, InputSetup, Packet>
                    {
                        Version      = version,
                        ContextSetup = setup,
                        OutputQueue  = outputQueue,
                    };

                    if (sameConfig)
                    {
                        ver.Context = last.Context.AddRef();

                        _inputThreadPendingContext?.Dispose();
                        _inputThreadPendingContext = ver;
                    }
                    else
                    {
                        if (sameDevice || last == null || _openThreadDenied)
                        {
                            _inputThreadPendingContext?.Dispose();
                            _inputThreadPendingContext = ver;

                            if (_inputThreadCurrentContext != null && _inputThreadCurrentContext.Context != null)
                            {
                                _inputThreadCurrentContext.Context.Instance.Interrupt();
                            }
                        }
                        else
                        {
                            _openThreadPendingContext?.Dispose();
                            _openThreadPendingContext = ver;

                            if (_openThreadRunningContext != null && _openThreadRunningContext.Context != null)
                            {
                                _openThreadRunningContext.Context.Instance.Interrupt();
                            }

                            if (!_openThreadIsRunning)
                            {
                                _openThreadIsRunning = true;
                                startOpenThread      = true;
                            }
                        }
                    }
                }

                if (!_inputThreadIsRunning)
                {
                    _inputThreadIsRunning = true;
                    _inputThread.Start();
                }
                if (startOpenThread)
                {
                    _openThread      = new Thread(() => OnOpenThread());
                    _openThread.Name = $"Streamer:{Name} input-open thread";
                    _openThread.Start();
                }
            });

            var last = _inputThreadCurrentContext;

            // same config and at least one time opened
            return((last != null && last.Context != null && last.Context.Instance.Config != null) ? last.Context.Instance : null);
        }