diff --git a/src/statistics/io_statistics.cpp b/src/statistics/io_statistics.cpp index fde5f97..263d76f 100644 --- a/src/statistics/io_statistics.cpp +++ b/src/statistics/io_statistics.cpp @@ -2,12 +2,13 @@ #include "log.h" +#define STATISTICAL_PERIOD 1000 #define RTP_SEQ_NUM_MAX 65535 IOStatistics::IOStatistics( std::function io_report_callback) : io_report_callback_(io_report_callback) { - interval_ = 1000; + interval_ = STATISTICAL_PERIOD; } IOStatistics::~IOStatistics() {} @@ -18,111 +19,120 @@ void IOStatistics::Process() { cond_var_.wait_for(lock, std::chrono::milliseconds(interval_), [this] { return !running_; }); - video_inbound_bitrate_ = video_inbound_bytes_ * 1000 * 8 / interval_; - video_outbound_bitrate_ = video_outbound_bytes_ * 1000 * 8 / interval_; - audio_inbound_bitrate_ = audio_inbound_bytes_ * 1000 * 8 / interval_; - audio_outbound_bitrate_ = audio_outbound_bytes_ * 1000 * 8 / interval_; - data_inbound_bitrate_ = data_inbound_bytes_ * 1000 * 8 / interval_; - data_outbound_bitrate_ = data_outbound_bytes_ * 1000 * 8 / interval_; + video_inbound_bitrate_ = video_inbound_bytes_.load() * 1000 * 8 / interval_; + video_outbound_bitrate_ = + video_outbound_bytes_.load() * 1000 * 8 / interval_; + audio_inbound_bitrate_ = audio_inbound_bytes_.load() * 1000 * 8 / interval_; + audio_outbound_bitrate_ = + audio_outbound_bytes_.load() * 1000 * 8 / interval_; + data_inbound_bitrate_ = data_inbound_bytes_.load() * 1000 * 8 / interval_; + data_outbound_bitrate_ = data_outbound_bytes_.load() * 1000 * 8 / interval_; total_inbound_bitrate_ = video_inbound_bitrate_ + audio_inbound_bitrate_ + data_inbound_bitrate_; total_outbound_bitrate_ = video_outbound_bitrate_ + audio_outbound_bitrate_ + data_outbound_bitrate_; - video_inbound_bytes_ = 0; - video_outbound_bytes_ = 0; - audio_inbound_bytes_ = 0; - audio_outbound_bytes_ = 0; - data_inbound_bytes_ = 0; - data_outbound_bytes_ = 0; - // packet loss rate - { - video_rtp_pkt_loss_cnt_ = - expected_video_inbound_rtp_pkt_cnt_ - video_inbound_rtp_pkt_cnt_tmp_; - audio_rtp_pkt_loss_cnt_ = - expected_audio_inbound_rtp_pkt_cnt_ - audio_inbound_rtp_pkt_cnt_tmp_; - data_rtp_pkt_loss_cnt_ = - expected_data_inbound_rtp_pkt_cnt_ - data_inbound_rtp_pkt_cnt_tmp_; - - if (expected_video_inbound_rtp_pkt_cnt_ > 0 && - video_rtp_pkt_loss_cnt_ >= 0) { - video_rtp_pkt_loss_rate_ = video_rtp_pkt_loss_cnt_ / - (float)expected_video_inbound_rtp_pkt_cnt_; - } else { - video_rtp_pkt_loss_rate_ = 0; - } - - if (expected_audio_inbound_rtp_pkt_cnt_ > 0 && - audio_inbound_rtp_pkt_cnt_tmp_ >= 0) { - audio_rtp_pkt_loss_rate_ = - audio_rtp_pkt_loss_cnt_ / (float)audio_inbound_rtp_pkt_cnt_; - } else { - audio_rtp_pkt_loss_rate_ = 0; - } - - if (expected_data_inbound_rtp_pkt_cnt_ > 0 && - data_inbound_rtp_pkt_cnt_ >= 0) { - data_rtp_pkt_loss_rate_ = - data_rtp_pkt_loss_cnt_ / (float)data_inbound_rtp_pkt_cnt_; - } else { - data_rtp_pkt_loss_rate_ = 0; - } - - expected_video_inbound_rtp_pkt_cnt_ = 0; - expected_audio_inbound_rtp_pkt_cnt_ = 0; - expected_data_inbound_rtp_pkt_cnt_ = 0; - video_inbound_rtp_pkt_cnt_tmp_ = 0; - audio_inbound_rtp_pkt_cnt_tmp_ = 0; - data_inbound_rtp_pkt_cnt_tmp_ = 0; - video_rtp_pkt_loss_cnt_ = 0; - audio_rtp_pkt_loss_cnt_ = 0; - data_rtp_pkt_loss_cnt_ = 0; + current_period_last_received_video_rtp_pkt_seq_ = + last_received_video_rtp_pkt_seq_.load(); + expected_video_inbound_rtp_pkt_cnt_ = + current_period_last_received_video_rtp_pkt_seq_ - + previous_period_last_received_video_rtp_pkt_seq_ - 1; + previous_period_last_received_video_rtp_pkt_seq_ = + current_period_last_received_video_rtp_pkt_seq_; + if (current_period_last_received_video_rtp_pkt_seq_ > 0 && + expected_video_inbound_rtp_pkt_cnt_ >= 0) { + video_rtp_pkt_loss_rate_ = video_rtp_pkt_loss_cnt_.load() / + (float)expected_video_inbound_rtp_pkt_cnt_; + } else { + video_rtp_pkt_loss_rate_ = 0; } + current_period_last_received_audio_rtp_pkt_seq_ = + last_received_audio_rtp_pkt_seq_.load(); + expected_audio_inbound_rtp_pkt_cnt_ = + current_period_last_received_audio_rtp_pkt_seq_ - + previous_period_last_received_audio_rtp_pkt_seq_ - 1; + previous_period_last_received_audio_rtp_pkt_seq_ = + current_period_last_received_audio_rtp_pkt_seq_; + if (current_period_last_received_audio_rtp_pkt_seq_ > 0 && + expected_audio_inbound_rtp_pkt_cnt_ >= 0) { + audio_rtp_pkt_loss_rate_ = audio_rtp_pkt_loss_cnt_.load() / + (float)expected_audio_inbound_rtp_pkt_cnt_; + } else { + audio_rtp_pkt_loss_rate_ = 0; + } + + current_period_last_received_data_rtp_pkt_seq_ = + last_received_data_rtp_pkt_seq_.load(); + expected_data_inbound_rtp_pkt_cnt_ = + current_period_last_received_data_rtp_pkt_seq_ - + previous_period_last_received_data_rtp_pkt_seq_ - 1; + previous_period_last_received_data_rtp_pkt_seq_ = + current_period_last_received_data_rtp_pkt_seq_; + if (current_period_last_received_data_rtp_pkt_seq_ > 0 && + expected_data_inbound_rtp_pkt_cnt_ >= 0) { + data_rtp_pkt_loss_rate_ = data_rtp_pkt_loss_cnt_.load() / + (float)expected_data_inbound_rtp_pkt_cnt_; + } else { + data_rtp_pkt_loss_rate_ = 0; + } + + video_inbound_bytes_.store(0); + video_outbound_bytes_.store(0); + audio_inbound_bytes_.store(0); + audio_outbound_bytes_.store(0); + data_inbound_bytes_.store(0); + data_outbound_bytes_.store(0); + video_rtp_pkt_loss_cnt_.store(0); + audio_rtp_pkt_loss_cnt_.store(0); + data_rtp_pkt_loss_cnt_.store(0); + if (io_report_callback_) { NetTrafficStats net_traffic_stats; net_traffic_stats.video_inbound_stats.bitrate = video_inbound_bitrate_; net_traffic_stats.video_inbound_stats.rtp_packet_count = - video_inbound_rtp_pkt_cnt_; + video_inbound_rtp_pkt_cnt_.load(); net_traffic_stats.video_inbound_stats.loss_rate = video_rtp_pkt_loss_rate_; net_traffic_stats.video_outbound_stats.bitrate = video_outbound_bitrate_; net_traffic_stats.video_outbound_stats.rtp_packet_count = - video_outbound_rtp_pkt_cnt_; + video_outbound_rtp_pkt_cnt_.load(); net_traffic_stats.audio_inbound_stats.bitrate = audio_inbound_bitrate_; net_traffic_stats.audio_inbound_stats.rtp_packet_count = - audio_inbound_rtp_pkt_cnt_; + audio_inbound_rtp_pkt_cnt_.load(); net_traffic_stats.audio_inbound_stats.loss_rate = audio_rtp_pkt_loss_rate_; net_traffic_stats.audio_outbound_stats.bitrate = audio_outbound_bitrate_; net_traffic_stats.audio_outbound_stats.rtp_packet_count = - audio_outbound_rtp_pkt_cnt_; + audio_outbound_rtp_pkt_cnt_.load(); net_traffic_stats.data_inbound_stats.bitrate = data_inbound_bitrate_; net_traffic_stats.data_inbound_stats.rtp_packet_count = - data_inbound_rtp_pkt_cnt_; + data_inbound_rtp_pkt_cnt_.load(); net_traffic_stats.data_inbound_stats.loss_rate = data_rtp_pkt_loss_rate_; net_traffic_stats.data_outbound_stats.bitrate = data_outbound_bitrate_; net_traffic_stats.data_outbound_stats.rtp_packet_count = - data_outbound_rtp_pkt_cnt_; + data_outbound_rtp_pkt_cnt_.load(); net_traffic_stats.total_inbound_stats.bitrate = total_inbound_bitrate_; net_traffic_stats.total_inbound_stats.loss_rate = video_rtp_pkt_loss_rate_ + audio_rtp_pkt_loss_rate_ + data_rtp_pkt_loss_rate_; net_traffic_stats.total_inbound_stats.rtp_packet_count = - video_inbound_rtp_pkt_cnt_ + audio_inbound_rtp_pkt_cnt_ + - data_inbound_rtp_pkt_cnt_; + net_traffic_stats.video_inbound_stats.rtp_packet_count + + net_traffic_stats.audio_inbound_stats.rtp_packet_count + + net_traffic_stats.data_inbound_stats.rtp_packet_count; net_traffic_stats.total_outbound_stats.bitrate = total_outbound_bitrate_; net_traffic_stats.total_outbound_stats.rtp_packet_count = - video_outbound_rtp_pkt_cnt_ + audio_outbound_rtp_pkt_cnt_ + - data_outbound_rtp_pkt_cnt_; + net_traffic_stats.video_outbound_stats.rtp_packet_count + + net_traffic_stats.audio_outbound_stats.rtp_packet_count + + net_traffic_stats.data_outbound_stats.rtp_packet_count; io_report_callback_(net_traffic_stats); } @@ -153,26 +163,21 @@ void IOStatistics::UpdateVideoOutboundBytes(uint32_t bytes) { } void IOStatistics::UpdateVideoPacketLossCount(uint16_t seq_num) { - if (last_received_video_rtp_pkt_seq_ != 0) { - if (last_received_video_rtp_pkt_seq_ < seq_num) { - if (seq_num - last_received_video_rtp_pkt_seq_ > 0x8000) { - expected_video_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_video_rtp_pkt_seq_ + seq_num + 1, - std::memory_order_relaxed); - } else { - expected_video_inbound_rtp_pkt_cnt_.fetch_add( - seq_num - last_received_video_rtp_pkt_seq_, - std::memory_order_relaxed); + uint16_t last_v_seq = last_received_video_rtp_pkt_seq_.load(); + if (last_v_seq != 0) { + if (seq_num > last_v_seq) { + if (seq_num - last_v_seq != 1) { + video_rtp_pkt_loss_cnt_.fetch_add(seq_num - last_v_seq - 1, + std::memory_order_relaxed); } - } else if (last_received_video_rtp_pkt_seq_ > seq_num) { - expected_video_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_video_rtp_pkt_seq_ + seq_num + 1, + } else { + video_rtp_pkt_loss_cnt_.fetch_add( + seq_num + (std::numeric_limits::max() - last_v_seq) - 1, std::memory_order_relaxed); } - } else { - expected_video_inbound_rtp_pkt_cnt_.fetch_add(1, std::memory_order_relaxed); } - last_received_video_rtp_pkt_seq_ = seq_num; + + last_received_video_rtp_pkt_seq_.store(seq_num); } void IOStatistics::UpdateAudioInboundBytes(uint32_t bytes) { @@ -184,24 +189,21 @@ void IOStatistics::UpdateAudioOutboundBytes(uint32_t bytes) { } void IOStatistics::UpdateAudioPacketLossCount(uint16_t seq_num) { - if (last_received_audio_rtp_pkt_seq_ != 0) { - if (last_received_audio_rtp_pkt_seq_ < seq_num) { - if (seq_num - last_received_audio_rtp_pkt_seq_ > 0x8000) { - expected_audio_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_audio_rtp_pkt_seq_ + seq_num + 1, - std::memory_order_relaxed); - } else { - expected_audio_inbound_rtp_pkt_cnt_.fetch_add( - seq_num - last_received_audio_rtp_pkt_seq_, - std::memory_order_relaxed); + uint16_t last_a_seq = last_received_audio_rtp_pkt_seq_.load(); + if (last_a_seq != 0) { + if (seq_num > last_a_seq) { + if (seq_num - last_a_seq != 1) { + audio_rtp_pkt_loss_cnt_.fetch_add(seq_num - last_a_seq - 1, + std::memory_order_relaxed); } - } else if (last_received_audio_rtp_pkt_seq_ > seq_num) { - expected_audio_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_audio_rtp_pkt_seq_ + seq_num + 1, + } else { + audio_rtp_pkt_loss_cnt_.fetch_add( + seq_num + (std::numeric_limits::max() - last_a_seq) - 1, std::memory_order_relaxed); } } - last_received_audio_rtp_pkt_seq_ = seq_num; + + last_received_audio_rtp_pkt_seq_.store(seq_num); } void IOStatistics::UpdateDataInboundBytes(uint32_t bytes) { @@ -213,29 +215,25 @@ void IOStatistics::UpdateDataOutboundBytes(uint32_t bytes) { } void IOStatistics::UpdateDataPacketLossCount(uint16_t seq_num) { - if (last_received_data_rtp_pkt_seq_ != 0) { - if (last_received_data_rtp_pkt_seq_ < seq_num) { - if (seq_num - last_received_data_rtp_pkt_seq_ > 0x8000) { - expected_data_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_data_rtp_pkt_seq_ + seq_num + 1, - std::memory_order_relaxed); - } else { - expected_data_inbound_rtp_pkt_cnt_.fetch_add( - seq_num - last_received_data_rtp_pkt_seq_, - std::memory_order_relaxed); + uint16_t last_d_seq = last_received_data_rtp_pkt_seq_.load(); + if (last_d_seq != 0) { + if (seq_num > last_d_seq) { + if (seq_num - last_d_seq != 1) { + data_rtp_pkt_loss_cnt_.fetch_add(seq_num - last_d_seq - 1, + std::memory_order_relaxed); } - } else if (last_received_data_rtp_pkt_seq_ > seq_num) { - expected_data_inbound_rtp_pkt_cnt_.fetch_add( - 0xffff - last_received_data_rtp_pkt_seq_ + seq_num + 1, + } else { + data_rtp_pkt_loss_cnt_.fetch_add( + seq_num + (std::numeric_limits::max() - last_d_seq) - 1, std::memory_order_relaxed); } } - last_received_data_rtp_pkt_seq_ = seq_num; + + last_received_data_rtp_pkt_seq_.store(seq_num); } void IOStatistics::IncrementVideoInboundRtpPacketCount() { ++video_inbound_rtp_pkt_cnt_; - ++video_inbound_rtp_pkt_cnt_tmp_; } void IOStatistics::IncrementVideoOutboundRtpPacketCount() { @@ -244,7 +242,6 @@ void IOStatistics::IncrementVideoOutboundRtpPacketCount() { void IOStatistics::IncrementAudioInboundRtpPacketCount() { ++audio_inbound_rtp_pkt_cnt_; - ++audio_inbound_rtp_pkt_cnt_tmp_; } void IOStatistics::IncrementAudioOutboundRtpPacketCount() { @@ -253,7 +250,6 @@ void IOStatistics::IncrementAudioOutboundRtpPacketCount() { void IOStatistics::IncrementDataInboundRtpPacketCount() { ++data_inbound_rtp_pkt_cnt_; - ++data_inbound_rtp_pkt_cnt_tmp_; } void IOStatistics::IncrementDataOutboundRtpPacketCount() { diff --git a/src/statistics/io_statistics.h b/src/statistics/io_statistics.h index 04ea09a..5470600 100644 --- a/src/statistics/io_statistics.h +++ b/src/statistics/io_statistics.h @@ -79,13 +79,22 @@ class IOStatistics { std::atomic video_inbound_bytes_ = 0; std::atomic video_outbound_bytes_ = 0; - uint16_t last_received_video_rtp_pkt_seq_ = 0; + std::atomic last_received_video_rtp_pkt_seq_ = 0; + uint16_t current_period_last_received_video_rtp_pkt_seq_ = 0; + uint16_t previous_period_last_received_video_rtp_pkt_seq_ = 0; + uint16_t expected_video_inbound_rtp_pkt_cnt_ = 0; std::atomic audio_inbound_bytes_ = 0; std::atomic audio_outbound_bytes_ = 0; - uint16_t last_received_audio_rtp_pkt_seq_ = 0; + std::atomic last_received_audio_rtp_pkt_seq_ = 0; + uint16_t current_period_last_received_audio_rtp_pkt_seq_ = 0; + uint16_t previous_period_last_received_audio_rtp_pkt_seq_ = 0; + uint16_t expected_audio_inbound_rtp_pkt_cnt_ = 0; std::atomic data_inbound_bytes_ = 0; std::atomic data_outbound_bytes_ = 0; - uint16_t last_received_data_rtp_pkt_seq_ = 0; + std::atomic last_received_data_rtp_pkt_seq_ = 0; + uint16_t current_period_last_received_data_rtp_pkt_seq_ = 0; + uint16_t previous_period_last_received_data_rtp_pkt_seq_ = 0; + uint16_t expected_data_inbound_rtp_pkt_cnt_ = 0; std::atomic total_inbound_bytes_ = 0; std::atomic total_outbound_bytes_ = 0; @@ -93,20 +102,13 @@ class IOStatistics { std::atomic audio_inbound_rtp_pkt_cnt_ = 0; std::atomic data_inbound_rtp_pkt_cnt_ = 0; - std::atomic video_inbound_rtp_pkt_cnt_tmp_ = 0; - std::atomic audio_inbound_rtp_pkt_cnt_tmp_ = 0; - std::atomic data_inbound_rtp_pkt_cnt_tmp_ = 0; - std::atomic data_outbound_rtp_pkt_cnt_ = 0; std::atomic video_outbound_rtp_pkt_cnt_ = 0; std::atomic audio_outbound_rtp_pkt_cnt_ = 0; - std::atomic expected_video_inbound_rtp_pkt_cnt_ = 0; - std::atomic expected_audio_inbound_rtp_pkt_cnt_ = 0; - std::atomic expected_data_inbound_rtp_pkt_cnt_ = 0; - int32_t video_rtp_pkt_loss_cnt_ = 0; - int32_t audio_rtp_pkt_loss_cnt_ = 0; - int32_t data_rtp_pkt_loss_cnt_ = 0; + std::atomic video_rtp_pkt_loss_cnt_ = 0; + std::atomic audio_rtp_pkt_loss_cnt_ = 0; + std::atomic data_rtp_pkt_loss_cnt_ = 0; uint32_t video_inbound_bitrate_ = 0; uint32_t video_outbound_bitrate_ = 0;