public void Update(bool muted, float deltaTime) { //Delay the initial startup of the capture pipeline. This spreads out the cost of initialising Dissonance over more frames, preventing very large spikes caused by everything being set up at once _startupDelay--; if (_startupDelay > 0) { return; } _receivingPacketLossMonitor.Update(); //Early exit if we don't need to record audio. Either because: // - Netmode doesn't require audio (i.e. dedicated server) // - A fatal exception occurred, permanently killing capture if (!_netModeRequiresPipeline || _encounteredFatalException || _cannotStartMic) { StopTransmissionPipeline(); return; } //Update microphone and reset it either if there is a frame skip or the microphone requests a reset var skipped = _skipDetector.IsFrameSkip(deltaTime); var request = _microphone.IsRecording && _microphone.UpdateSubscribers(); var netmode = _netModeRequiresPipeline && _encoder == null; if (skipped || request || _pendingResetRequest || netmode) { var reason = skipped ? "Detected a frame skip, forcing capture pipeline reset" : netmode ? "Network mode changed" : _pendingResetRequest ? "Applying external reset request" : "Microphone requested a pipeline reset"; if (skipped) { //If warn level logging is turned on show some extra information in the reason (at the cost of a string allocation) if (Log.IsWarn) { reason = string.Format("Detected a frame skip, forcing capture pipeline reset (Delta Time:{0})", deltaTime); } Log.Warn(reason); } RestartTransmissionPipeline(reason); } if (_encoder != null) { //If the encoder is finally stopped and still subscribed then unsubscribe and reset it. This puts it into a state ready to be used again. if (_encoder.Stopped && _encoderSubscribed) { Log.Debug("Unsubscribing encoder from preprocessor"); _preprocessor.Unsubscribe(_encoder); _encoder.Reset(); _encoderSubscribed = false; } //Determine if the encoder should be subscribed: // - If encoder is stopping (but has not yet stopped) then do not sub // - If mute is explicitly set then do not sub // - if there are open channels then sub var shouldSub = !(_encoder.Stopping && !_encoder.Stopped) && !muted && (_roomChannels.Count + _playerChannels.Count) > 0; //Change the encoder state to the desired state if (shouldSub != _encoderSubscribed) { if (shouldSub) { Log.Debug("Subscribing encoder to preprocessor"); _encoder.Reset(); _preprocessor.Subscribe(_encoder); _encoderSubscribed = true; } else { //If the encoder has not been told to stop, tell it now if (!_encoder.Stopping) { //Set the encoder state to stopping - it will stop after it sends one final packet to end the stream _encoder.Stop(); Log.Debug("Stopping encoder"); } else { Log.Debug("Waiting for encoder to send last packet"); } } } else { //Log.Debug("Should Sub - Stopping:{0} Stopped:{1} Muted:{1}", _encoder.Stopping, _encoder.Stopped, muted); } //Propogate measured *incoming* packet loss to encoder as expected *outgoing* packet loss if (_encoder != null) { _encoder.TransmissionPacketLoss = _receivingPacketLossMonitor.PacketLoss; } } }
public void Update(bool muted, float deltaTime) { _receivingPacketLossMonitor.Update(); //Update microphone and reset it either if there is a frame skip or the microphone requests a reset var skipped = _skipDetector.IsFrameSkip(deltaTime); var request = _microphone.IsRecording && _microphone.UpdateSubscribers(); if (skipped || request) { if (skipped) { Log.Warn("Detected a frame skip, forcing capture pipeline reset"); } RestartTransmissionPipeline(); } if (_encoder != null) { //If the encoder is finally stopped and still subscribed then unsubscribe and reset it. This puts it into a state ready to be used again. if (_encoder.Stopped && _encoderSubscribed) { Log.Debug("Unsubscribing encoder from preprocessor"); _preprocessor.Unsubscribe(_encoder); _encoder.Reset(); _encoderSubscribed = false; } //Check if the encoder state matches the desired state var shouldSub = !(_encoder.Stopping && !_encoder.Stopped) && !muted && (_roomChannels.Count + _playerChannels.Count) > 0; if (shouldSub != _encoderSubscribed) { if (shouldSub) { Log.Debug("Subscribing encoder to preprocessor"); _encoder.Reset(); _preprocessor.Subscribe(_encoder); _encoderSubscribed = true; } else { //Inform the encoder that it should stop encoding (after sending one final packet) if (!_encoder.Stopping) { _encoder.Stop(); Log.Debug("Stopping encoder"); } else { Log.Debug("Waiting for encoder to send last packet"); } } } else { //Log.Debug("Should Sub - Stopping:{0} Muted:{1}", _encoder.Stopping, muted); } //Propogate measured *incoming* packet loss to encoder as expected *outgoing* packet loss if (_encoder != null) { _encoder.TransmissionPacketLoss = _receivingPacketLossMonitor.PacketLoss; } } }