/// <summary> /// Processes RTCP packets. /// </summary> /// <param name="packets">The packets to process.</param> public override void ProcessRTCP(RTCPPacket[] packets) { if (_Encoder != null) { foreach (var packet in packets) { if (packet is RTCPReportPacket) { _ReportsReceived++; var report = (RTCPReportPacket)packet; foreach (var block in report.ReportBlocks) { Log.DebugFormat("Opus report: {0} packet loss ({1} cumulative packets lost)", block.PercentLost.ToString("P2"), block.CumulativeNumberOfPacketsLost.ToString()); if (block.PercentLost > 0) { _LosslessCount = 0; _LossyCount++; if (_LossyCount > 5 && _Encoder.Quality > 0.0) { _LossyCount = 0; _Encoder.Quality = MathAssistant.Max(0.0, _Encoder.Quality - 0.1); Log.InfoFormat("Decreasing Opus encoder quality to {0}.", _Encoder.Quality.ToString("P2")); } } else { _LossyCount = 0; _LosslessCount++; if (_LosslessCount > 5 && _Encoder.Quality < 1.0) { _LosslessCount = 0; _Encoder.Quality = MathAssistant.Min(1.0, _Encoder.Quality + 0.1); Log.InfoFormat("Increasing Opus encoder quality to {0}.", _Encoder.Quality.ToString("P2")); } } if (!DisableFEC && !FecActive && _ReportsReceived > _MinimumReportsBeforeFEC) { if ((block.PercentLost * 100) > PercentLossToTriggerFEC) { Log.InfoFormat("Activating FEC for Opus audio stream."); _Encoder.ActivateFEC(PercentLossToTriggerFEC); FecActive = true; } } } } } } }
public long GetIndex(long value, out long rolloverCounter) // i { if (HighestValue == -1) { HighestValue = value; rolloverCounter = RolloverCounter; return(value); } long v; if (HighestValue < _RolloverSize_2) { // use > instead of >= to favour forward movement if (value - HighestValue > _RolloverSize_2) { v = (RolloverCounter - 1) % 4294967296; } else { v = RolloverCounter; HighestValue = MathAssistant.Max(HighestValue, value); } } else { // use >= instead of > to favour forward movement if (HighestValue - _RolloverSize_2 >= value) { v = (RolloverCounter + 1) % 4294967296; HighestValue = value; RolloverCounter = v; } else { v = RolloverCounter; HighestValue = MathAssistant.Max(HighestValue, value); } } rolloverCounter = v; return(_RolloverSize * v + value); }
/// <summary> /// Processes RTCP packets. /// </summary> /// <param name="packets">The packets to process.</param> public override void ProcessRTCP(RTCPPacket[] packets) { if (_Encoder != null) { foreach (var packet in packets) { if (packet is RTCPPliPacket) { Log.Info("Received PLI for video stream."); _Encoder.ForceKeyFrame(); } else if (packet is RTCPReportPacket) { var report = (RTCPReportPacket)packet; foreach (var block in report.ReportBlocks) { Log.DebugFormat("VP8 report: {0} packet loss ({1} cumulative packets lost)", block.PercentLost.ToString("P2"), block.CumulativeNumberOfPacketsLost.ToString()); if (block.PercentLost > 0) { _LosslessCount = 0; _LossyCount++; if (_LossyCount > 5 && (_Encoder.Quality > 0.0 || _Encoder.Bitrate > 64 || _Encoder.Scale > 0.2)) { _LossyCount = 0; if (_Encoder.Quality > 0.0) { _Encoder.Quality = MathAssistant.Max(0.0, _Encoder.Quality - 0.1); Log.InfoFormat("Decreasing VP8 encoder quality to {0}.", _Encoder.Quality.ToString("P2")); } if (_Encoder.Bitrate > 64) { _Encoder.Bitrate = MathAssistant.Max(64, _Encoder.Bitrate - 64); Log.InfoFormat("Decreasing VP8 encoder bitrate to {0}.", _Encoder.Bitrate.ToString()); } if (_Encoder.Scale > 0.2) { _Encoder.Scale = MathAssistant.Max(0.2, _Encoder.Scale - 0.2); Log.InfoFormat("Decreasing VP8 encoder scale to {0}.", _Encoder.Scale.ToString("P2")); } } } else { _LossyCount = 0; _LosslessCount++; if (_LosslessCount > 5 && (_Encoder.Quality < 1.0 || _Encoder.Bitrate < 640 || _Encoder.Scale < 1.0)) { _LosslessCount = 0; if (_Encoder.Quality < 1.0) { _Encoder.Quality = MathAssistant.Min(1.0, _Encoder.Quality + 0.1); Log.InfoFormat("Increasing VP8 encoder quality to {0}.", _Encoder.Quality.ToString("P2")); } if (_Encoder.Bitrate < 640) { _Encoder.Bitrate = MathAssistant.Min(640, _Encoder.Bitrate + 64); Log.InfoFormat("Increasing VP8 encoder bitrate to {0}.", _Encoder.Bitrate.ToString()); } if (_Encoder.Scale < 1.0) { _Encoder.Scale = MathAssistant.Min(1.0, _Encoder.Scale + 0.2); Log.InfoFormat("Increasing VP8 encoder scale to {0}.", _Encoder.Scale.ToString("P2")); } } } } } } } }