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); }
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); }
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); }
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); }