diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/log_simulation.cc | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/log_simulation.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/log_simulation.cc new file mode 100644 index 0000000000..30c4de199a --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/log_simulation.cc @@ -0,0 +1,209 @@ +/* + * Copyright 2019 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "rtc_tools/rtc_event_log_visualizer/log_simulation.h" + +#include <algorithm> +#include <utility> + +#include "logging/rtc_event_log/rtc_event_processor.h" +#include "modules/rtp_rtcp/source/time_util.h" +#include "system_wrappers/include/clock.h" + +namespace webrtc { + +LogBasedNetworkControllerSimulation::LogBasedNetworkControllerSimulation( + std::unique_ptr<NetworkControllerFactoryInterface> factory, + std::function<void(const NetworkControlUpdate&, Timestamp)> update_handler) + : update_handler_(update_handler), factory_(std::move(factory)) {} + +LogBasedNetworkControllerSimulation::~LogBasedNetworkControllerSimulation() {} + +void LogBasedNetworkControllerSimulation::HandleStateUpdate( + const NetworkControlUpdate& update) { + update_handler_(update, current_time_); +} + +void LogBasedNetworkControllerSimulation::ProcessUntil(Timestamp to_time) { + if (last_process_.IsInfinite()) { + NetworkControllerConfig config; + config.constraints.at_time = to_time; + config.constraints.min_data_rate = DataRate::KilobitsPerSec(30); + config.constraints.starting_rate = DataRate::KilobitsPerSec(300); + config.event_log = &null_event_log_; + controller_ = factory_->Create(config); + } + if (last_process_.IsInfinite() || + to_time - last_process_ > TimeDelta::Seconds(1)) { + last_process_ = to_time; + current_time_ = to_time; + ProcessInterval msg; + msg.at_time = to_time; + HandleStateUpdate(controller_->OnProcessInterval(msg)); + } else { + while (last_process_ + factory_->GetProcessInterval() <= to_time) { + last_process_ += factory_->GetProcessInterval(); + current_time_ = last_process_; + ProcessInterval msg; + msg.at_time = current_time_; + HandleStateUpdate(controller_->OnProcessInterval(msg)); + } + current_time_ = to_time; + } +} + +void LogBasedNetworkControllerSimulation::OnProbeCreated( + const LoggedBweProbeClusterCreatedEvent& probe_cluster) { + pending_probes_.push_back({probe_cluster, 0, 0}); +} + +void LogBasedNetworkControllerSimulation::OnPacketSent( + const LoggedPacketInfo& packet) { + ProcessUntil(packet.log_packet_time); + if (packet.has_transport_seq_no) { + PacedPacketInfo probe_info; + if (!pending_probes_.empty() && + packet.media_type == LoggedMediaType::kVideo) { + auto& probe = pending_probes_.front(); + probe_info.probe_cluster_id = probe.event.id; + probe_info.send_bitrate_bps = probe.event.bitrate_bps; + probe_info.probe_cluster_min_bytes = probe.event.min_bytes; + probe_info.probe_cluster_min_probes = probe.event.min_packets; + probe.packets_sent++; + probe.bytes_sent += packet.size + packet.overhead; + if (probe.bytes_sent >= probe.event.min_bytes && + probe.packets_sent >= probe.event.min_packets) { + pending_probes_.pop_front(); + } + } + + RtpPacketSendInfo packet_info; + packet_info.media_ssrc = packet.ssrc; + packet_info.transport_sequence_number = packet.transport_seq_no; + packet_info.rtp_sequence_number = packet.stream_seq_no; + packet_info.length = packet.size; + packet_info.pacing_info = probe_info; + transport_feedback_.AddPacket(packet_info, packet.overhead, + packet.log_packet_time); + } + rtc::SentPacket sent_packet; + sent_packet.send_time_ms = packet.log_packet_time.ms(); + sent_packet.info.included_in_allocation = true; + sent_packet.info.packet_size_bytes = packet.size + packet.overhead; + if (packet.has_transport_seq_no) { + sent_packet.packet_id = packet.transport_seq_no; + sent_packet.info.included_in_feedback = true; + } + auto msg = transport_feedback_.ProcessSentPacket(sent_packet); + if (msg) + HandleStateUpdate(controller_->OnSentPacket(*msg)); +} + +void LogBasedNetworkControllerSimulation::OnFeedback( + const LoggedRtcpPacketTransportFeedback& feedback) { + auto feedback_time = Timestamp::Millis(feedback.log_time_ms()); + ProcessUntil(feedback_time); + auto msg = transport_feedback_.ProcessTransportFeedback( + feedback.transport_feedback, feedback_time); + if (msg) + HandleStateUpdate(controller_->OnTransportPacketsFeedback(*msg)); +} + +void LogBasedNetworkControllerSimulation::OnReceiverReport( + const LoggedRtcpPacketReceiverReport& report) { + if (report.rr.report_blocks().empty()) + return; + auto report_time = Timestamp::Millis(report.log_time_ms()); + ProcessUntil(report_time); + int packets_delta = 0; + int lost_delta = 0; + for (auto& block : report.rr.report_blocks()) { + auto it = last_report_blocks_.find(block.source_ssrc()); + if (it != last_report_blocks_.end()) { + packets_delta += + block.extended_high_seq_num() - it->second.extended_high_seq_num(); + lost_delta += block.cumulative_lost() - it->second.cumulative_lost(); + } + last_report_blocks_[block.source_ssrc()] = block; + } + if (packets_delta > lost_delta) { + TransportLossReport msg; + msg.packets_lost_delta = lost_delta; + msg.packets_received_delta = packets_delta - lost_delta; + msg.receive_time = report_time; + msg.start_time = last_report_block_time_; + msg.end_time = report_time; + last_report_block_time_ = report_time; + HandleStateUpdate(controller_->OnTransportLossReport(msg)); + } + + Clock* clock = Clock::GetRealTimeClock(); + TimeDelta rtt = TimeDelta::PlusInfinity(); + for (auto& rb : report.rr.report_blocks()) { + if (rb.last_sr()) { + Timestamp report_log_time = Timestamp::Micros(report.log_time_us()); + uint32_t receive_time_ntp = + CompactNtp(clock->ConvertTimestampToNtpTime(report_log_time)); + uint32_t rtt_ntp = + receive_time_ntp - rb.delay_since_last_sr() - rb.last_sr(); + rtt = std::min(rtt, CompactNtpRttToTimeDelta(rtt_ntp)); + } + } + if (rtt.IsFinite()) { + RoundTripTimeUpdate msg; + msg.receive_time = report_time; + msg.round_trip_time = rtt; + HandleStateUpdate(controller_->OnRoundTripTimeUpdate(msg)); + } +} + +void LogBasedNetworkControllerSimulation::OnIceConfig( + const LoggedIceCandidatePairConfig& candidate) { + if (candidate.type == IceCandidatePairConfigType::kSelected) { + auto log_time = Timestamp::Micros(candidate.log_time_us()); + ProcessUntil(log_time); + NetworkRouteChange msg; + msg.at_time = log_time; + msg.constraints.min_data_rate = DataRate::KilobitsPerSec(30); + msg.constraints.starting_rate = DataRate::KilobitsPerSec(300); + msg.constraints.at_time = log_time; + HandleStateUpdate(controller_->OnNetworkRouteChange(msg)); + } +} + +void LogBasedNetworkControllerSimulation::ProcessEventsInLog( + const ParsedRtcEventLog& parsed_log_) { + auto packet_infos = parsed_log_.GetOutgoingPacketInfos(); + RtcEventProcessor processor; + processor.AddEvents( + parsed_log_.bwe_probe_cluster_created_events(), + [this](const LoggedBweProbeClusterCreatedEvent& probe_cluster) { + OnProbeCreated(probe_cluster); + }); + processor.AddEvents(packet_infos, [this](const LoggedPacketInfo& packet) { + OnPacketSent(packet); + }); + processor.AddEvents( + parsed_log_.transport_feedbacks(PacketDirection::kIncomingPacket), + [this](const LoggedRtcpPacketTransportFeedback& feedback) { + OnFeedback(feedback); + }); + processor.AddEvents( + parsed_log_.receiver_reports(PacketDirection::kIncomingPacket), + [this](const LoggedRtcpPacketReceiverReport& report) { + OnReceiverReport(report); + }); + processor.AddEvents(parsed_log_.ice_candidate_pair_configs(), + [this](const LoggedIceCandidatePairConfig& candidate) { + OnIceConfig(candidate); + }); + processor.ProcessEventsInOrder(); +} + +} // namespace webrtc |