/// <summary> /// Callback function for the RTCP report timer. /// </summary> /// <param name="stateInfo">Not used.</param> private void SendReportTimerCallback(Object stateInfo) { try { if (!IsClosed) { lock (m_rtcpReportTimer) { if ((LastActivityAt != DateTime.MinValue && DateTime.Now.Subtract(LastActivityAt).TotalMilliseconds > NO_ACTIVITY_TIMEOUT_MILLISECONDS) || (LastActivityAt == DateTime.MinValue && DateTime.Now.Subtract(CreatedAt).TotalMilliseconds > NO_ACTIVITY_TIMEOUT_MILLISECONDS)) { if (!IsTimedOut) { logger.LogWarning( $"RTCP session for local ssrc {Ssrc} has not had any activity for over {NO_ACTIVITY_TIMEOUT_MILLISECONDS / 1000} seconds."); IsTimedOut = true; OnTimeout?.Invoke(MediaType); } } //logger.LogDebug($"SendRtcpSenderReport ssrc {Ssrc}, last seqnum {LastSeqNum}, pkts {PacketsSentCount}, bytes {OctetsSentCount} "); var report = GetRtcpReport(); OnReportReadyToSend?.Invoke(MediaType, report); m_previousPacketsSentCount = PacketsSentCount; var interval = GetNextRtcpInterval(RTCP_MINIMUM_REPORT_PERIOD_MILLISECONDS); if (m_rtcpReportTimer == null) { m_rtcpReportTimer = new Timer(SendReportTimerCallback, null, interval, Timeout.Infinite); } else { m_rtcpReportTimer?.Change(interval, Timeout.Infinite); } } } } catch (ObjectDisposedException) // The RTP socket can disappear between the null check and the report send. { m_rtcpReportTimer?.Dispose(); } catch (Exception excp) { // RTCP reports are not critical enough to bubble the exception up to the application. logger.LogError($"Exception SendReportTimerCallback. {excp.Message}"); m_rtcpReportTimer?.Dispose(); } }
public void Close(string reason) { if (!IsClosed) { IsClosed = true; m_rtcpReportTimer?.Dispose(); var byeReport = GetRtcpReport(); byeReport.Bye = new RTCPBye(Ssrc, reason); OnReportReadyToSend?.Invoke(MediaType, byeReport); } }