xref: /aosp_15_r20/external/webrtc/rtc_tools/rtc_event_log_visualizer/log_simulation.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "rtc_tools/rtc_event_log_visualizer/log_simulation.h"
11 
12 #include <algorithm>
13 #include <utility>
14 
15 #include "logging/rtc_event_log/rtc_event_processor.h"
16 #include "modules/rtp_rtcp/source/time_util.h"
17 #include "system_wrappers/include/clock.h"
18 
19 namespace webrtc {
20 
LogBasedNetworkControllerSimulation(std::unique_ptr<NetworkControllerFactoryInterface> factory,std::function<void (const NetworkControlUpdate &,Timestamp)> update_handler)21 LogBasedNetworkControllerSimulation::LogBasedNetworkControllerSimulation(
22     std::unique_ptr<NetworkControllerFactoryInterface> factory,
23     std::function<void(const NetworkControlUpdate&, Timestamp)> update_handler)
24     : update_handler_(update_handler), factory_(std::move(factory)) {}
25 
~LogBasedNetworkControllerSimulation()26 LogBasedNetworkControllerSimulation::~LogBasedNetworkControllerSimulation() {}
27 
HandleStateUpdate(const NetworkControlUpdate & update)28 void LogBasedNetworkControllerSimulation::HandleStateUpdate(
29     const NetworkControlUpdate& update) {
30   update_handler_(update, current_time_);
31 }
32 
ProcessUntil(Timestamp to_time)33 void LogBasedNetworkControllerSimulation::ProcessUntil(Timestamp to_time) {
34   if (last_process_.IsInfinite()) {
35     NetworkControllerConfig config;
36     config.constraints.at_time = to_time;
37     config.constraints.min_data_rate = DataRate::KilobitsPerSec(30);
38     config.constraints.starting_rate = DataRate::KilobitsPerSec(300);
39     config.event_log = &null_event_log_;
40     controller_ = factory_->Create(config);
41   }
42   if (last_process_.IsInfinite() ||
43       to_time - last_process_ > TimeDelta::Seconds(1)) {
44     last_process_ = to_time;
45     current_time_ = to_time;
46     ProcessInterval msg;
47     msg.at_time = to_time;
48     HandleStateUpdate(controller_->OnProcessInterval(msg));
49   } else {
50     while (last_process_ + factory_->GetProcessInterval() <= to_time) {
51       last_process_ += factory_->GetProcessInterval();
52       current_time_ = last_process_;
53       ProcessInterval msg;
54       msg.at_time = current_time_;
55       HandleStateUpdate(controller_->OnProcessInterval(msg));
56     }
57     current_time_ = to_time;
58   }
59 }
60 
OnProbeCreated(const LoggedBweProbeClusterCreatedEvent & probe_cluster)61 void LogBasedNetworkControllerSimulation::OnProbeCreated(
62     const LoggedBweProbeClusterCreatedEvent& probe_cluster) {
63   pending_probes_.push_back({probe_cluster, 0, 0});
64 }
65 
OnPacketSent(const LoggedPacketInfo & packet)66 void LogBasedNetworkControllerSimulation::OnPacketSent(
67     const LoggedPacketInfo& packet) {
68   ProcessUntil(packet.log_packet_time);
69   if (packet.has_transport_seq_no) {
70     PacedPacketInfo probe_info;
71     if (!pending_probes_.empty() &&
72         packet.media_type == LoggedMediaType::kVideo) {
73       auto& probe = pending_probes_.front();
74       probe_info.probe_cluster_id = probe.event.id;
75       probe_info.send_bitrate_bps = probe.event.bitrate_bps;
76       probe_info.probe_cluster_min_bytes = probe.event.min_bytes;
77       probe_info.probe_cluster_min_probes = probe.event.min_packets;
78       probe.packets_sent++;
79       probe.bytes_sent += packet.size + packet.overhead;
80       if (probe.bytes_sent >= probe.event.min_bytes &&
81           probe.packets_sent >= probe.event.min_packets) {
82         pending_probes_.pop_front();
83       }
84     }
85 
86     RtpPacketSendInfo packet_info;
87     packet_info.media_ssrc = packet.ssrc;
88     packet_info.transport_sequence_number = packet.transport_seq_no;
89     packet_info.rtp_sequence_number = packet.stream_seq_no;
90     packet_info.length = packet.size;
91     packet_info.pacing_info = probe_info;
92     transport_feedback_.AddPacket(packet_info, packet.overhead,
93                                   packet.log_packet_time);
94   }
95   rtc::SentPacket sent_packet;
96   sent_packet.send_time_ms = packet.log_packet_time.ms();
97   sent_packet.info.included_in_allocation = true;
98   sent_packet.info.packet_size_bytes = packet.size + packet.overhead;
99   if (packet.has_transport_seq_no) {
100     sent_packet.packet_id = packet.transport_seq_no;
101     sent_packet.info.included_in_feedback = true;
102   }
103   auto msg = transport_feedback_.ProcessSentPacket(sent_packet);
104   if (msg)
105     HandleStateUpdate(controller_->OnSentPacket(*msg));
106 }
107 
OnFeedback(const LoggedRtcpPacketTransportFeedback & feedback)108 void LogBasedNetworkControllerSimulation::OnFeedback(
109     const LoggedRtcpPacketTransportFeedback& feedback) {
110   auto feedback_time = Timestamp::Millis(feedback.log_time_ms());
111   ProcessUntil(feedback_time);
112   auto msg = transport_feedback_.ProcessTransportFeedback(
113       feedback.transport_feedback, feedback_time);
114   if (msg)
115     HandleStateUpdate(controller_->OnTransportPacketsFeedback(*msg));
116 }
117 
OnReceiverReport(const LoggedRtcpPacketReceiverReport & report)118 void LogBasedNetworkControllerSimulation::OnReceiverReport(
119     const LoggedRtcpPacketReceiverReport& report) {
120   if (report.rr.report_blocks().empty())
121     return;
122   auto report_time = Timestamp::Millis(report.log_time_ms());
123   ProcessUntil(report_time);
124   int packets_delta = 0;
125   int lost_delta = 0;
126   for (auto& block : report.rr.report_blocks()) {
127     auto it = last_report_blocks_.find(block.source_ssrc());
128     if (it != last_report_blocks_.end()) {
129       packets_delta +=
130           block.extended_high_seq_num() - it->second.extended_high_seq_num();
131       lost_delta += block.cumulative_lost() - it->second.cumulative_lost();
132     }
133     last_report_blocks_[block.source_ssrc()] = block;
134   }
135   if (packets_delta > lost_delta) {
136     TransportLossReport msg;
137     msg.packets_lost_delta = lost_delta;
138     msg.packets_received_delta = packets_delta - lost_delta;
139     msg.receive_time = report_time;
140     msg.start_time = last_report_block_time_;
141     msg.end_time = report_time;
142     last_report_block_time_ = report_time;
143     HandleStateUpdate(controller_->OnTransportLossReport(msg));
144   }
145 
146   Clock* clock = Clock::GetRealTimeClock();
147   TimeDelta rtt = TimeDelta::PlusInfinity();
148   for (auto& rb : report.rr.report_blocks()) {
149     if (rb.last_sr()) {
150       Timestamp report_log_time = Timestamp::Micros(report.log_time_us());
151       uint32_t receive_time_ntp =
152           CompactNtp(clock->ConvertTimestampToNtpTime(report_log_time));
153       uint32_t rtt_ntp =
154           receive_time_ntp - rb.delay_since_last_sr() - rb.last_sr();
155       rtt = std::min(rtt, CompactNtpRttToTimeDelta(rtt_ntp));
156     }
157   }
158   if (rtt.IsFinite()) {
159     RoundTripTimeUpdate msg;
160     msg.receive_time = report_time;
161     msg.round_trip_time = rtt;
162     HandleStateUpdate(controller_->OnRoundTripTimeUpdate(msg));
163   }
164 }
165 
OnIceConfig(const LoggedIceCandidatePairConfig & candidate)166 void LogBasedNetworkControllerSimulation::OnIceConfig(
167     const LoggedIceCandidatePairConfig& candidate) {
168   if (candidate.type == IceCandidatePairConfigType::kSelected) {
169     auto log_time = Timestamp::Micros(candidate.log_time_us());
170     ProcessUntil(log_time);
171     NetworkRouteChange msg;
172     msg.at_time = log_time;
173     msg.constraints.min_data_rate = DataRate::KilobitsPerSec(30);
174     msg.constraints.starting_rate = DataRate::KilobitsPerSec(300);
175     msg.constraints.at_time = log_time;
176     HandleStateUpdate(controller_->OnNetworkRouteChange(msg));
177   }
178 }
179 
ProcessEventsInLog(const ParsedRtcEventLog & parsed_log_)180 void LogBasedNetworkControllerSimulation::ProcessEventsInLog(
181     const ParsedRtcEventLog& parsed_log_) {
182   auto packet_infos = parsed_log_.GetOutgoingPacketInfos();
183   RtcEventProcessor processor;
184   processor.AddEvents(
185       parsed_log_.bwe_probe_cluster_created_events(),
186       [this](const LoggedBweProbeClusterCreatedEvent& probe_cluster) {
187         OnProbeCreated(probe_cluster);
188       });
189   processor.AddEvents(packet_infos, [this](const LoggedPacketInfo& packet) {
190     OnPacketSent(packet);
191   });
192   processor.AddEvents(
193       parsed_log_.transport_feedbacks(PacketDirection::kIncomingPacket),
194       [this](const LoggedRtcpPacketTransportFeedback& feedback) {
195         OnFeedback(feedback);
196       });
197   processor.AddEvents(
198       parsed_log_.receiver_reports(PacketDirection::kIncomingPacket),
199       [this](const LoggedRtcpPacketReceiverReport& report) {
200         OnReceiverReport(report);
201       });
202   processor.AddEvents(parsed_log_.ice_candidate_pair_configs(),
203                       [this](const LoggedIceCandidatePairConfig& candidate) {
204                         OnIceConfig(candidate);
205                       });
206   processor.ProcessEventsInOrder();
207 }
208 
209 }  // namespace webrtc
210