Ejemplo n.º 1
0
 internal RenderingContext(IntPtr displayPointer, IntPtr configPointer, ContextVersion clientVersion)
 {
     this.displayPointer = displayPointer;
     this.configPointer  = configPointer;
     this.clientVersion  = clientVersion;
     this.Initialize();
 }
Ejemplo n.º 2
0
        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));
                }
            }
        }
Ejemplo n.º 3
0
        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)));
                    }
                }
            }
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        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;
                    }
                }
            }
        }
Ejemplo n.º 6
0
        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)));
                }
            }
        }
Ejemplo n.º 7
0
        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)
            {
            }
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
0
        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)));
                }
            }
        }
Ejemplo n.º 11
0
 protected abstract void ProcessData(Data <TInput> data, ContextVersion <TContext, TContextConfig, TOutput> currentContext);
Ejemplo n.º 12
0
        public RenderingContext CreateContext(Config config, ContextVersion attribs)
        {
            var renderingContext = new RenderingContext(this.display.DisplayPointer, config.ConfigPointer, attribs);

            return(renderingContext);
        }