Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 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 | #ifndef TEST_SCENARIO_CALL_CLIENT_H_ |
| 11 | #define TEST_SCENARIO_CALL_CLIENT_H_ |
Bjorn Terelius | 5c2f1f0 | 2019-01-16 17:45:05 +0100 | [diff] [blame] | 12 | |
| 13 | #include <map> |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 14 | #include <memory> |
| 15 | #include <string> |
Bjorn Terelius | 5c2f1f0 | 2019-01-16 17:45:05 +0100 | [diff] [blame] | 16 | #include <utility> |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 17 | #include <vector> |
| 18 | |
Danil Chapovalov | 83bbe91 | 2019-08-07 12:24:53 +0200 | [diff] [blame] | 19 | #include "api/rtc_event_log/rtc_event_log.h" |
Bjorn A Mellem | c4f8654 | 2019-11-21 10:37:18 -0800 | [diff] [blame] | 20 | #include "api/test/time_controller.h" |
Christoffer Rodbro | 8649e49 | 2020-12-15 20:20:54 +0100 | [diff] [blame] | 21 | #include "api/units/data_rate.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 22 | #include "call/call.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 23 | #include "modules/audio_device/include/test_audio_device.h" |
Sebastian Jansson | 871ac42 | 2019-05-17 17:53:44 +0200 | [diff] [blame] | 24 | #include "modules/congestion_controller/goog_cc/test/goog_cc_printer.h" |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 25 | #include "rtc_base/task_queue_for_test.h" |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 26 | #include "test/logging/log_writer.h" |
Artem Titov | 386802e | 2019-07-05 10:48:17 +0200 | [diff] [blame] | 27 | #include "test/network/network_emulation.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 28 | #include "test/scenario/column_printer.h" |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 29 | #include "test/scenario/network_node.h" |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 30 | #include "test/scenario/scenario_config.h" |
| 31 | |
| 32 | namespace webrtc { |
| 33 | |
| 34 | namespace test { |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 35 | // Helper class to capture network controller state. |
| 36 | class NetworkControleUpdateCache : public NetworkControllerInterface { |
| 37 | public: |
| 38 | explicit NetworkControleUpdateCache( |
| 39 | std::unique_ptr<NetworkControllerInterface> controller); |
| 40 | |
| 41 | NetworkControlUpdate OnNetworkAvailability(NetworkAvailability msg) override; |
| 42 | NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange msg) override; |
| 43 | NetworkControlUpdate OnProcessInterval(ProcessInterval msg) override; |
| 44 | NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; |
| 45 | NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; |
| 46 | NetworkControlUpdate OnSentPacket(SentPacket msg) override; |
| 47 | NetworkControlUpdate OnReceivedPacket(ReceivedPacket msg) override; |
| 48 | NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override; |
| 49 | NetworkControlUpdate OnTargetRateConstraints( |
| 50 | TargetRateConstraints msg) override; |
| 51 | NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override; |
| 52 | NetworkControlUpdate OnTransportPacketsFeedback( |
| 53 | TransportPacketsFeedback msg) override; |
Sebastian Jansson | 49167de | 2019-06-27 15:59:03 +0200 | [diff] [blame] | 54 | NetworkControlUpdate OnNetworkStateEstimate( |
| 55 | NetworkStateEstimate msg) override; |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 56 | |
| 57 | NetworkControlUpdate update_state() const; |
| 58 | |
| 59 | private: |
| 60 | NetworkControlUpdate Update(NetworkControlUpdate update); |
| 61 | const std::unique_ptr<NetworkControllerInterface> controller_; |
| 62 | NetworkControlUpdate update_state_; |
| 63 | }; |
| 64 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 65 | class LoggingNetworkControllerFactory |
| 66 | : public NetworkControllerFactoryInterface { |
| 67 | public: |
Sebastian Jansson | 7ccaf89 | 2019-04-24 15:13:26 +0200 | [diff] [blame] | 68 | LoggingNetworkControllerFactory(LogWriterFactoryInterface* log_writer_factory, |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 69 | TransportControllerConfig config); |
Artem Titov | 6cae2d5 | 2022-01-26 15:01:10 +0000 | [diff] [blame] | 70 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 71 | ~LoggingNetworkControllerFactory(); |
Artem Titov | 6cae2d5 | 2022-01-26 15:01:10 +0000 | [diff] [blame] | 72 | |
| 73 | LoggingNetworkControllerFactory(const LoggingNetworkControllerFactory&) = |
| 74 | delete; |
| 75 | LoggingNetworkControllerFactory& operator=( |
| 76 | const LoggingNetworkControllerFactory&) = delete; |
| 77 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 78 | std::unique_ptr<NetworkControllerInterface> Create( |
| 79 | NetworkControllerConfig config) override; |
| 80 | TimeDelta GetProcessInterval() const override; |
| 81 | // TODO(srte): Consider using the Columnprinter interface for this. |
| 82 | void LogCongestionControllerStats(Timestamp at_time); |
Christoffer Rodbro | 8649e49 | 2020-12-15 20:20:54 +0100 | [diff] [blame] | 83 | void SetRemoteBitrateEstimate(RemoteBitrateReport msg); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 84 | |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 85 | NetworkControlUpdate GetUpdate() const; |
| 86 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 87 | private: |
Sebastian Jansson | 871ac42 | 2019-05-17 17:53:44 +0200 | [diff] [blame] | 88 | GoogCcDebugFactory goog_cc_factory_; |
Sebastian Jansson | f0d0312 | 2018-12-18 15:53:04 +0100 | [diff] [blame] | 89 | NetworkControllerFactoryInterface* cc_factory_ = nullptr; |
Sebastian Jansson | 871ac42 | 2019-05-17 17:53:44 +0200 | [diff] [blame] | 90 | bool print_cc_state_ = false; |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 91 | NetworkControleUpdateCache* last_controller_ = nullptr; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 92 | }; |
| 93 | |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 94 | struct CallClientFakeAudio { |
| 95 | rtc::scoped_refptr<AudioProcessing> apm; |
| 96 | rtc::scoped_refptr<TestAudioDeviceModule> fake_audio_device; |
| 97 | rtc::scoped_refptr<AudioState> audio_state; |
| 98 | }; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 99 | // CallClient represents a participant in a call scenario. It is created by the |
| 100 | // Scenario class and is used as sender and receiver when setting up a media |
| 101 | // stream session. |
Artem Titov | 40f5115 | 2019-01-04 15:45:01 +0100 | [diff] [blame] | 102 | class CallClient : public EmulatedNetworkReceiverInterface { |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 103 | public: |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 104 | CallClient(TimeController* time_controller, |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 105 | std::unique_ptr<LogWriterFactoryInterface> log_writer_factory, |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 106 | CallClientConfig config); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 107 | |
| 108 | ~CallClient(); |
Artem Titov | 6cae2d5 | 2022-01-26 15:01:10 +0000 | [diff] [blame] | 109 | |
| 110 | CallClient(const CallClient&) = delete; |
| 111 | CallClient& operator=(const CallClient&) = delete; |
| 112 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 113 | ColumnPrinter StatsPrinter(); |
| 114 | Call::Stats GetStats(); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 115 | DataRate send_bandwidth() { |
Danil Chapovalov | cad3e0e | 2020-02-17 18:46:07 +0100 | [diff] [blame] | 116 | return DataRate::BitsPerSec(GetStats().send_bandwidth_bps); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 117 | } |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 118 | DataRate target_rate() const; |
Florent Castelli | 4e615d5 | 2019-08-22 16:09:06 +0200 | [diff] [blame] | 119 | DataRate stable_target_rate() const; |
Sebastian Jansson | a7d70ab | 2019-06-11 10:21:32 +0200 | [diff] [blame] | 120 | DataRate padding_rate() const; |
Erik Språng | 3e3e166 | 2020-10-06 21:51:21 +0200 | [diff] [blame] | 121 | void UpdateBitrateConstraints(const BitrateConstraints& constraints); |
Christoffer Rodbro | 8649e49 | 2020-12-15 20:20:54 +0100 | [diff] [blame] | 122 | void SetRemoteBitrate(DataRate bitrate); |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 123 | |
Artem Titov | 40f5115 | 2019-01-04 15:45:01 +0100 | [diff] [blame] | 124 | void OnPacketReceived(EmulatedIpPacket packet) override; |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 125 | std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 126 | |
Tommi | 3c9bcc1 | 2020-04-15 16:45:47 +0200 | [diff] [blame] | 127 | // Exposed publicly so that tests can execute tasks such as querying stats |
| 128 | // for media streams in the expected runtime environment (essentially what |
| 129 | // CallClient does internally for GetStats()). |
| 130 | void SendTask(std::function<void()> task); |
| 131 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 132 | private: |
| 133 | friend class Scenario; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 134 | friend class CallClientPair; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 135 | friend class SendVideoStream; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 136 | friend class VideoStreamPair; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 137 | friend class ReceiveVideoStream; |
| 138 | friend class SendAudioStream; |
| 139 | friend class ReceiveAudioStream; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 140 | friend class AudioStreamPair; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 141 | friend class NetworkNodeTransport; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 142 | uint32_t GetNextVideoSsrc(); |
Sebastian Jansson | 5fbebd5 | 2019-02-20 11:16:19 +0100 | [diff] [blame] | 143 | uint32_t GetNextVideoLocalSsrc(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 144 | uint32_t GetNextAudioSsrc(); |
Sebastian Jansson | 5fbebd5 | 2019-02-20 11:16:19 +0100 | [diff] [blame] | 145 | uint32_t GetNextAudioLocalSsrc(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 146 | uint32_t GetNextRtxSsrc(); |
Sebastian Jansson | 77bd385 | 2020-01-17 13:05:54 +0100 | [diff] [blame] | 147 | int16_t Bind(EmulatedEndpoint* endpoint); |
| 148 | void UnBind(); |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 149 | |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 150 | TimeController* const time_controller_; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 151 | Clock* clock_; |
Sebastian Jansson | 52de8b0 | 2019-01-16 17:25:44 +0100 | [diff] [blame] | 152 | const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; |
Sebastian Jansson | 7ccaf89 | 2019-04-24 15:13:26 +0200 | [diff] [blame] | 153 | std::unique_ptr<RtcEventLog> event_log_; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 154 | LoggingNetworkControllerFactory network_controller_factory_; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 155 | CallClientFakeAudio fake_audio_setup_; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 156 | std::unique_ptr<Call> call_; |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 157 | std::unique_ptr<NetworkNodeTransport> transport_; |
Sebastian Jansson | 77bd385 | 2020-01-17 13:05:54 +0100 | [diff] [blame] | 158 | std::vector<std::pair<EmulatedEndpoint*, uint16_t>> endpoints_; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 159 | |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 160 | int next_video_ssrc_index_ = 0; |
Sebastian Jansson | 5fbebd5 | 2019-02-20 11:16:19 +0100 | [diff] [blame] | 161 | int next_video_local_ssrc_index_ = 0; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 162 | int next_rtx_ssrc_index_ = 0; |
| 163 | int next_audio_ssrc_index_ = 0; |
Sebastian Jansson | 5fbebd5 | 2019-02-20 11:16:19 +0100 | [diff] [blame] | 164 | int next_audio_local_ssrc_index_ = 0; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 165 | std::map<uint32_t, MediaType> ssrc_media_types_; |
Sebastian Jansson | 105a10a | 2019-04-01 09:18:14 +0200 | [diff] [blame] | 166 | // Defined last so it's destroyed first. |
| 167 | TaskQueueForTest task_queue_; |
Erik Språng | 014dd3c | 2019-11-28 13:44:25 +0100 | [diff] [blame] | 168 | |
Tommi | 25c77c1 | 2020-05-25 17:44:55 +0200 | [diff] [blame] | 169 | rtc::scoped_refptr<SharedModuleThread> module_thread_; |
| 170 | |
Erik Språng | 014dd3c | 2019-11-28 13:44:25 +0100 | [diff] [blame] | 171 | const FieldTrialBasedConfig field_trials_; |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 172 | }; |
| 173 | |
| 174 | class CallClientPair { |
| 175 | public: |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 176 | ~CallClientPair(); |
Artem Titov | 6cae2d5 | 2022-01-26 15:01:10 +0000 | [diff] [blame] | 177 | |
| 178 | CallClientPair(const CallClientPair&) = delete; |
| 179 | CallClientPair& operator=(const CallClientPair&) = delete; |
| 180 | |
Sebastian Jansson | 800e121 | 2018-10-22 11:49:03 +0200 | [diff] [blame] | 181 | CallClient* first() { return first_; } |
| 182 | CallClient* second() { return second_; } |
| 183 | std::pair<CallClient*, CallClient*> forward() { return {first(), second()}; } |
| 184 | std::pair<CallClient*, CallClient*> reverse() { return {second(), first()}; } |
| 185 | |
| 186 | private: |
| 187 | friend class Scenario; |
| 188 | CallClientPair(CallClient* first, CallClient* second) |
| 189 | : first_(first), second_(second) {} |
| 190 | CallClient* const first_; |
| 191 | CallClient* const second_; |
Sebastian Jansson | 98b07e9 | 2018-09-27 13:47:01 +0200 | [diff] [blame] | 192 | }; |
| 193 | } // namespace test |
| 194 | } // namespace webrtc |
| 195 | |
| 196 | #endif // TEST_SCENARIO_CALL_CLIENT_H_ |