| /* |
| * Copyright (c) 2025 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. |
| */ |
| |
| #ifndef MODULES_CONGESTION_CONTROLLER_SCREAM_TEST_CC_FEEDBACK_GENERATOR_H_ |
| #define MODULES_CONGESTION_CONTROLLER_SCREAM_TEST_CC_FEEDBACK_GENERATOR_H_ |
| |
| #include <cstdint> |
| #include <deque> |
| #include <memory> |
| #include <optional> |
| |
| #include "absl/functional/any_invocable.h" |
| #include "api/test/network_emulation/leaky_bucket_network_queue.h" |
| #include "api/test/network_emulation/network_queue.h" |
| #include "api/test/simulated_network.h" |
| #include "api/transport/network_types.h" |
| #include "api/units/data_rate.h" |
| #include "api/units/data_size.h" |
| #include "api/units/time_delta.h" |
| #include "api/units/timestamp.h" |
| #include "system_wrappers/include/clock.h" |
| #include "test/network/simulated_network.h" |
| |
| namespace webrtc { |
| |
| // Simulates sending packets with a given send rate over a simulated network and |
| // generates TransportPacketsFeedback that is supposed to match |
| // TransportPacketsFeedback from rtcp::CongestionControlFeedback (RFC8888). |
| class CcFeedbackGenerator { |
| public: |
| struct Config { |
| SimulatedNetwork::Config network_config; |
| TimeDelta time_between_feedback = TimeDelta::Millis(25); |
| bool send_as_ect1 = true; |
| std::unique_ptr<NetworkQueue> queue = |
| std::make_unique<LeakyBucketNetworkQueue>( |
| LeakyBucketNetworkQueue::Config{ |
| .max_ect1_sojourn_time = TimeDelta::Millis(8), |
| .target_ect1_sojourn_time = TimeDelta::Millis(4)}); |
| DataSize packet_size = DataSize::Bytes(1000); |
| }; |
| |
| explicit CcFeedbackGenerator(Config config); |
| |
| // Processes the simulation until the next feedback message is received. |
| // The function will send packets at the given send rate until the next |
| // feedback message is generated. |
| TransportPacketsFeedback ProcessUntilNextFeedback(DataRate send_rate, |
| SimulatedClock& clock) { |
| return ProcessUntilNextFeedback(send_rate, clock, nullptr); |
| } |
| |
| TransportPacketsFeedback ProcessUntilNextFeedback( |
| DataRate send_rate, |
| SimulatedClock& clock, |
| absl::AnyInvocable<void(const SentPacket&)> sent_packet_cb, |
| TimeDelta max_time = TimeDelta::Seconds(1)); |
| |
| static int CountCeMarks(const TransportPacketsFeedback& feedback); |
| |
| private: |
| std::optional<SentPacket> MaybeSendPackets(Timestamp time, |
| DataRate send_rate); |
| void ProcessNetwork(Timestamp time); |
| std::optional<TransportPacketsFeedback> MaybeSendFeedback(Timestamp time); |
| |
| const DataSize packet_size_; |
| const TimeDelta time_between_feedback_; |
| const TimeDelta one_way_delay_; |
| const bool send_as_ect1_; |
| SimulatedNetwork network_; |
| |
| int64_t next_packet_id_ = 0; |
| std::deque<PacketInFlightInfo> packets_in_flight_; |
| // `packets_received_` are packed that have been received by the remote, but |
| // feedback has not yet been received by the sender. Feedback is delivered one |
| // way delay later than when the packets were received. |
| std::deque<PacketDeliveryInfo> packets_received_; |
| |
| Timestamp last_feedback_time_ = Timestamp::MinusInfinity(); |
| |
| Timestamp last_send_budget_update = Timestamp::MinusInfinity(); |
| DataSize send_budget_; |
| }; |
| } // namespace webrtc |
| |
| #endif // MODULES_CONGESTION_CONTROLLER_SCREAM_TEST_CC_FEEDBACK_GENERATOR_H_ |