diff --git a/logging/rtc_event_log/logged_events.h b/logging/rtc_event_log/logged_events.h index 5bbfa53d8d..4bcd937227 100644 --- a/logging/rtc_event_log/logged_events.h +++ b/logging/rtc_event_log/logged_events.h @@ -571,6 +571,9 @@ struct LoggedGenericPacketSent { int64_t log_time_us() const { return timestamp_us; } int64_t log_time_ms() const { return timestamp_us / 1000; } + size_t packet_length() const { + return payload_length + padding_length + overhead_length; + } int64_t timestamp_us; int64_t packet_number; size_t overhead_length; diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h index ad5d98fb46..de37d31927 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.h +++ b/logging/rtc_event_log/rtc_event_log_parser.h @@ -497,14 +497,15 @@ class ParsedRtcEventLog { } } - const std::vector& generic_packets_received() { + const std::vector& generic_packets_received() + const { return generic_packets_received_; } - const std::vector& generic_packets_sent() { + const std::vector& generic_packets_sent() const { return generic_packets_sent_; } - const std::vector& generic_acks_received() { + const std::vector& generic_acks_received() const { return generic_acks_received_; } diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc index a77f378083..48cfbff24b 100644 --- a/rtc_tools/event_log_visualizer/analyzer.cc +++ b/rtc_tools/event_log_visualizer/analyzer.cc @@ -812,27 +812,29 @@ void EventLogAnalyzer::CreateTotalIncomingBitrateGraph(Plot* plot) { auto window_end = packets_in_order.begin(); size_t bytes_in_window = 0; - // Calculate a moving average of the bitrate and store in a TimeSeries. - TimeSeries bitrate_series("Bitrate", LineStyle::kLine); - for (int64_t time = config_.begin_time_; - time < config_.end_time_ + config_.step_; time += config_.step_) { - while (window_end != packets_in_order.end() && window_end->first < time) { - bytes_in_window += window_end->second; - ++window_end; + if (!packets_in_order.empty()) { + // Calculate a moving average of the bitrate and store in a TimeSeries. + TimeSeries bitrate_series("Bitrate", LineStyle::kLine); + for (int64_t time = config_.begin_time_; + time < config_.end_time_ + config_.step_; time += config_.step_) { + while (window_end != packets_in_order.end() && window_end->first < time) { + bytes_in_window += window_end->second; + ++window_end; + } + while (window_begin != packets_in_order.end() && + window_begin->first < time - config_.window_duration_) { + RTC_DCHECK_LE(window_begin->second, bytes_in_window); + bytes_in_window -= window_begin->second; + ++window_begin; + } + float window_duration_in_seconds = + static_cast(config_.window_duration_) / kNumMicrosecsPerSec; + float x = config_.GetCallTimeSec(time); + float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; + bitrate_series.points.emplace_back(x, y); } - while (window_begin != packets_in_order.end() && - window_begin->first < time - config_.window_duration_) { - RTC_DCHECK_LE(window_begin->second, bytes_in_window); - bytes_in_window -= window_begin->second; - ++window_begin; - } - float window_duration_in_seconds = - static_cast(config_.window_duration_) / kNumMicrosecsPerSec; - float x = config_.GetCallTimeSec(time); - float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; - bitrate_series.points.emplace_back(x, y); + plot->AppendTimeSeries(std::move(bitrate_series)); } - plot->AppendTimeSeries(std::move(bitrate_series)); // Overlay the outgoing REMB over incoming bitrate. TimeSeries remb_series("Remb", LineStyle::kStep); @@ -843,6 +845,17 @@ void EventLogAnalyzer::CreateTotalIncomingBitrateGraph(Plot* plot) { } plot->AppendTimeSeriesIfNotEmpty(std::move(remb_series)); + if (!parsed_log_.generic_packets_received().empty()) { + TimeSeries time_series("Incoming generic bitrate", LineStyle::kLine); + auto GetPacketSizeKilobits = [](const LoggedGenericPacketReceived& packet) { + return packet.packet_length * 8.0 / 1000.0; + }; + MovingAverage( + GetPacketSizeKilobits, parsed_log_.generic_packets_received(), config_, + &time_series); + plot->AppendTimeSeries(std::move(time_series)); + } + plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(), "Time (s)", kLeftMargin, kRightMargin); plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin); @@ -865,27 +878,29 @@ void EventLogAnalyzer::CreateTotalOutgoingBitrateGraph(Plot* plot, auto window_end = packets_in_order.begin(); size_t bytes_in_window = 0; - // Calculate a moving average of the bitrate and store in a TimeSeries. - TimeSeries bitrate_series("Bitrate", LineStyle::kLine); - for (int64_t time = config_.begin_time_; - time < config_.end_time_ + config_.step_; time += config_.step_) { - while (window_end != packets_in_order.end() && window_end->first < time) { - bytes_in_window += window_end->second; - ++window_end; + if (!packets_in_order.empty()) { + // Calculate a moving average of the bitrate and store in a TimeSeries. + TimeSeries bitrate_series("Bitrate", LineStyle::kLine); + for (int64_t time = config_.begin_time_; + time < config_.end_time_ + config_.step_; time += config_.step_) { + while (window_end != packets_in_order.end() && window_end->first < time) { + bytes_in_window += window_end->second; + ++window_end; + } + while (window_begin != packets_in_order.end() && + window_begin->first < time - config_.window_duration_) { + RTC_DCHECK_LE(window_begin->second, bytes_in_window); + bytes_in_window -= window_begin->second; + ++window_begin; + } + float window_duration_in_seconds = + static_cast(config_.window_duration_) / kNumMicrosecsPerSec; + float x = config_.GetCallTimeSec(time); + float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; + bitrate_series.points.emplace_back(x, y); } - while (window_begin != packets_in_order.end() && - window_begin->first < time - config_.window_duration_) { - RTC_DCHECK_LE(window_begin->second, bytes_in_window); - bytes_in_window -= window_begin->second; - ++window_begin; - } - float window_duration_in_seconds = - static_cast(config_.window_duration_) / kNumMicrosecsPerSec; - float x = config_.GetCallTimeSec(time); - float y = bytes_in_window * 8 / window_duration_in_seconds / 1000; - bitrate_series.points.emplace_back(x, y); + plot->AppendTimeSeries(std::move(bitrate_series)); } - plot->AppendTimeSeries(std::move(bitrate_series)); // Overlay the send-side bandwidth estimate over the outgoing bitrate. TimeSeries loss_series("Loss-based estimate", LineStyle::kStep); @@ -1005,6 +1020,32 @@ void EventLogAnalyzer::CreateTotalOutgoingBitrateGraph(Plot* plot, } plot->AppendTimeSeriesIfNotEmpty(std::move(remb_series)); + if (!parsed_log_.generic_packets_sent().empty()) { + { + TimeSeries time_series("Outgoing generic total bitrate", + LineStyle::kLine); + auto GetPacketSizeKilobits = [](const LoggedGenericPacketSent& packet) { + return packet.packet_length() * 8.0 / 1000.0; + }; + MovingAverage( + GetPacketSizeKilobits, parsed_log_.generic_packets_sent(), config_, + &time_series); + plot->AppendTimeSeries(std::move(time_series)); + } + + { + TimeSeries time_series("Outgoing generic payload bitrate", + LineStyle::kLine); + auto GetPacketSizeKilobits = [](const LoggedGenericPacketSent& packet) { + return packet.payload_length * 8.0 / 1000.0; + }; + MovingAverage( + GetPacketSizeKilobits, parsed_log_.generic_packets_sent(), config_, + &time_series); + plot->AppendTimeSeries(std::move(time_series)); + } + } + plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(), "Time (s)", kLeftMargin, kRightMargin); plot->SetSuggestedYAxis(0, 1, "Bitrate (kbps)", kBottomMargin, kTopMargin);