internal RenderingContext(IntPtr displayPointer, IntPtr configPointer, ContextVersion clientVersion) { this.displayPointer = displayPointer; this.configPointer = configPointer; this.clientVersion = clientVersion; this.Initialize(); }
protected override void ProcessData(Data <Frame> data, ContextVersion <VideoBlenderContext, VideoBlenderSetup, Frame> currentVersion) { if (currentVersion == null) { return; } if (data != null) { _statisticKeeper.Data.InFrames++; //unsafe, but ok if (currentVersion == null || currentVersion.Version < _latestVersion) //TODO:NextRelease: we need some how handle older version packets to not lose frames { Streamer.FramePool.Back(data.Payload); return; } _latestVersion = currentVersion.Version; data.Trace?.Received(Name); int writeRes = currentVersion.Context.Instance.Write(data, currentVersion.ContextSetup, _statisticKeeper2.Data); if (Core.IsFailed(writeRes)) { _statisticKeeper.Data.Errors++; Core.LogError($"Write to {Name} (sid:{data.SourceId}): {Core.GetErrorMessage(writeRes)}", "write to node failed"); return; } } else { currentVersion.Context.Instance.Write(null, currentVersion.ContextSetup, null); } while (!currentVersion.IsInterrupted) { var resultPayload = Streamer.FramePool.Rent(); var readRes = currentVersion.Context.Instance.Read(resultPayload, out var resultTrace); if (readRes == ErrorCodes.TryAgainLater) { Streamer.FramePool.Back(resultPayload); break; } else if (Core.IsFailed(readRes)) { _statisticKeeper2.Data.Errors++; Streamer.FramePool.Back(resultPayload); Core.LogError($"Read from {Name}: {Core.GetErrorMessage((int)readRes)}", "read from node failed"); break; } else // success { //Core.LogInfo($"-------------------------------------------------------------Out {Name}"); _statisticKeeper2.Data.OutFrames++; //unsafe, but ok currentVersion.OutputQueue.Enqueue(new Data <Frame>(resultPayload, currentVersion.Version, data?.SequenceNumber ?? 0, resultTrace)); } } }
protected override void ProcessData(Data <Frame> data, ContextVersion <IEncoderContext, EncoderSetup, Packet> currentVersion) { _statisticKeeper.Data.InFrames++; //unsafe, but ok lock (this) { if (currentVersion == null || currentVersion.Context == null) { Streamer.FramePool.Back(data.Payload); return; } data.Trace?.Received(Name); bool enforceIFrame = false; if (_makeIFrameNextPacket == data.Version && currentVersion.ContextSetup.SupportsEnforcingIFrame) { Core.LogInfo("Trying to enforce IFrame on encoder"); _makeIFrameNextPacket = 0; enforceIFrame = true; } int writeRes = currentVersion.Context.Instance.Write(data.Payload, enforceIFrame); Streamer.FramePool.Back(data.Payload); if (Core.IsFailed(writeRes)) { _statisticKeeper.Data.Errors++; Core.LogError($"Write to {Name}: {Core.GetErrorMessage(writeRes)}", "write to node failed"); return; } while (!currentVersion.IsInterrupted) { var resultPayload = Streamer.PacketPool.Rent(); var readRes = currentVersion.Context.Instance.Read(resultPayload); if (readRes == ErrorCodes.TryAgainLater) { Streamer.PacketPool.Back(resultPayload); break; } else if (Core.IsFailed(readRes)) { _statisticKeeper.Data.Errors++; Streamer.PacketPool.Back(resultPayload); Core.LogError($"Read from {Name}: {Core.GetErrorMessage(writeRes)}", "read from node failed"); break; } else // success { _statisticKeeper.Data.OutFrames++; //unsafe, but ok currentVersion.OutputQueue.Enqueue(new Data <Packet>(resultPayload, currentVersion.Version, data.SequenceNumber, PayloadTrace.Create(Name, data.Trace))); } } } }
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); }
private void OnOpenThread() { while (true) { lock (this) { if (_openThreadPendingContext == null) { _openThreadIsRunning = false; _lastOpenCycle = DateTime.MaxValue; return; } _openThreadRunningContext = _openThreadPendingContext; _openThreadRunningContext.Context = new RefCounted <IInputContext>(CreateInputContext(_openThreadRunningContext.ContextSetup)); _openThreadPendingContext = null; _lastOpenCycle = DateTime.UtcNow; } try { Open(_openThreadRunningContext); } catch (OperationCanceledException) { Core.LogInfo($"Open stream cancelled for {Name} on OpenThread"); } catch (Exception e) { UpdateError(e); Core.LogError(e, $"Open stream failed for {Name} on OpenThread"); } lock (this) { if (_openThreadRunningContext != null) { if (_inputThreadCurrentContext != null && _inputThreadCurrentContext.Context != null) { _inputThreadCurrentContext.Context.Instance.Interrupt(); } _inputThreadPendingContext = _openThreadRunningContext; _openThreadRunningContext = null; } } } }
protected override void ProcessData(Data <Packet> data, ContextVersion <IDecoderContext, DecoderSetup, Frame> currentVersion) { _statisticKeeper.Data.InFrames++; //unsafe, but ok if (currentVersion == null) { Streamer.PacketPool.Back(data.Payload); return; } data.Trace?.Received(Name); int writeRes = currentVersion.Context.Instance.Write(data.Payload); Streamer.PacketPool.Back(data.Payload); if (Core.IsFailed(writeRes)) { _statisticKeeper.Data.Errors++; Core.LogError($"Write to {Name}: {Core.GetErrorMessage(writeRes)}", "write to node failed"); return; } while (!currentVersion.IsInterrupted) { var resultPayload = Streamer.FramePool.Rent(); var readRes = currentVersion.Context.Instance.Read(resultPayload); if (readRes == ErrorCodes.TryAgainLater) { Streamer.FramePool.Back(resultPayload); break; } else if (Core.IsFailed(readRes)) { _statisticKeeper.Data.Errors++; Streamer.FramePool.Back(resultPayload); Core.LogError($"Read from {Name}: {Core.GetErrorMessage(writeRes)}", "read from node failed"); break; } else // success { _statisticKeeper.Data.OutFrames++; //unsafe, but ok currentVersion.OutputQueue.Enqueue(new Data <Frame>(resultPayload, currentVersion.Version, data.SequenceNumber, PayloadTrace.Create(Name, data.Trace))); } } }
private void On1Second() { ContextVersion <IInputContext, InputSetup, Packet> openContextToClose = null; lock (this) { DateTime now = DateTime.UtcNow; if (now - _lastOpenCycle > TimeSpan.FromSeconds(5)) // open thread is hanged { openContextToClose = _openThreadRunningContext; _openThreadRunningContext = null; _openThreadDenied = true; } } if (openContextToClose != null) { } }
protected ContextVersion <TContext, TContextConfig, TOutput> GetVersion(int payloadVersion) { ContextVersion <TContext, TContextConfig, TOutput> result = null; lock (this) { var last = _versions.Last; if (payloadVersion >= 0) { while (last != null && last.Value.Version != payloadVersion) { last = last.Previous; } } if (last == null) { if (_versions.Count == 0) { Core.LogWarning($"Version {payloadVersion} not found for {Name}: No versions defined", "Version not found"); } else if (payloadVersion > _versions.Last.Value.Version) { Core.LogWarning($"Version {payloadVersion} not found for {Name}: payload is newer", "Version not found"); } else { Core.LogWarning($"Version {payloadVersion} not found for {Name}: payload is older", "Version not found"); } } else { result = last.Value; result.IsInUse = true; } } return(result); }
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); }
protected override void ProcessData(Data <Frame> data, ContextVersion <IFilterContext, FilterSetup, Frame> currentVersion) { //if (Name.Name == "FMix" && data.Payload != null) //{ // Core.LogInfo($"--------------------------------In {Name} {data.SourceId} {data.Payload.Properties.Pts}"); //} _statisticKeeper.Data.InFrames++; //unsafe, but ok if (currentVersion == null) { Streamer.FramePool.Back(data.Payload); return; } data.Trace?.Received(Name); var instance = currentVersion.Context.Instance; //using var mem = new TimeMeasurer($"Filter '{Name}'"); int writeRes = instance.Write(data.Payload, data.SourceId); if (writeRes == (int)ErrorCodes.NullFilter) { _statisticKeeper.Data.OutFrames++; //unsafe, but ok currentVersion.OutputQueue.Enqueue(data); return; } Streamer.FramePool.Back(data.Payload); if (Core.IsFailed(writeRes)) { _statisticKeeper.Data.Errors++; Core.LogError($"Write to {Name} (sid:{data.SourceId}): {Core.GetErrorMessage(writeRes)}", "write to node failed"); return; } while (!currentVersion.IsInterrupted) { var resultPayload = Streamer.FramePool.Rent(); var readRes = instance.Read(resultPayload); if (readRes == ErrorCodes.TryAgainLater) { Streamer.FramePool.Back(resultPayload); break; } else if (Core.IsFailed(readRes)) { _statisticKeeper.Data.Errors++; Streamer.FramePool.Back(resultPayload); Core.LogError($"Read from {Name}: {Core.GetErrorMessage((int)readRes)}", "read from node failed"); break; } else // success { //if (Name.Name == "FMix" && data.Payload != null) //{ // Core.LogInfo($"----------------------------------Out {Name} - {resultPayload.Properties.Pts}"); //} _statisticKeeper.Data.OutFrames++; //unsafe, but ok currentVersion.OutputQueue.Enqueue(new Data <Frame>(resultPayload, currentVersion.Version, data.SequenceNumber, PayloadTrace.Create(Name, data.Trace))); } } }
protected abstract void ProcessData(Data <TInput> data, ContextVersion <TContext, TContextConfig, TOutput> currentContext);
public RenderingContext CreateContext(Config config, ContextVersion attribs) { var renderingContext = new RenderingContext(this.display.DisplayPointer, config.ConfigPointer, attribs); return(renderingContext); }