xref: /aosp_15_r20/external/webrtc/test/scenario/audio_stream.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 #include "test/scenario/audio_stream.h"
11 
12 #include "absl/memory/memory.h"
13 #include "test/call_test.h"
14 
15 #if WEBRTC_ENABLE_PROTOBUF
16 RTC_PUSH_IGNORING_WUNDEF()
17 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
18 #include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
19 #else
20 #include "modules/audio_coding/audio_network_adaptor/config.pb.h"
21 #endif
22 RTC_POP_IGNORING_WUNDEF()
23 #endif
24 
25 namespace webrtc {
26 namespace test {
27 namespace {
28 enum : int {  // The first valid value is 1.
29   kTransportSequenceNumberExtensionId = 1,
30   kAbsSendTimeExtensionId
31 };
32 
CreateAdaptationString(AudioStreamConfig::NetworkAdaptation config)33 absl::optional<std::string> CreateAdaptationString(
34     AudioStreamConfig::NetworkAdaptation config) {
35 #if WEBRTC_ENABLE_PROTOBUF
36 
37   audio_network_adaptor::config::ControllerManager cont_conf;
38   if (config.frame.max_rate_for_60_ms.IsFinite()) {
39     auto controller =
40         cont_conf.add_controllers()->mutable_frame_length_controller();
41     controller->set_fl_decreasing_packet_loss_fraction(
42         config.frame.min_packet_loss_for_decrease);
43     controller->set_fl_increasing_packet_loss_fraction(
44         config.frame.max_packet_loss_for_increase);
45 
46     controller->set_fl_20ms_to_60ms_bandwidth_bps(
47         config.frame.min_rate_for_20_ms.bps<int32_t>());
48     controller->set_fl_60ms_to_20ms_bandwidth_bps(
49         config.frame.max_rate_for_60_ms.bps<int32_t>());
50 
51     if (config.frame.max_rate_for_120_ms.IsFinite()) {
52       controller->set_fl_60ms_to_120ms_bandwidth_bps(
53           config.frame.min_rate_for_60_ms.bps<int32_t>());
54       controller->set_fl_120ms_to_60ms_bandwidth_bps(
55           config.frame.max_rate_for_120_ms.bps<int32_t>());
56     }
57   }
58   cont_conf.add_controllers()->mutable_bitrate_controller();
59   std::string config_string = cont_conf.SerializeAsString();
60   return config_string;
61 #else
62   RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
63                        " but WEBRTC_ENABLE_PROTOBUF is false.\n"
64                        "Ignoring settings.";
65   return absl::nullopt;
66 #endif  // WEBRTC_ENABLE_PROTOBUF
67 }
68 }  // namespace
69 
SendAudioStream(CallClient * sender,AudioStreamConfig config,rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,Transport * send_transport)70 SendAudioStream::SendAudioStream(
71     CallClient* sender,
72     AudioStreamConfig config,
73     rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
74     Transport* send_transport)
75     : sender_(sender), config_(config) {
76   AudioSendStream::Config send_config(send_transport);
77   ssrc_ = sender->GetNextAudioSsrc();
78   send_config.rtp.ssrc = ssrc_;
79   SdpAudioFormat::Parameters sdp_params;
80   if (config.source.channels == 2)
81     sdp_params["stereo"] = "1";
82   if (config.encoder.initial_frame_length != TimeDelta::Millis(20))
83     sdp_params["ptime"] =
84         std::to_string(config.encoder.initial_frame_length.ms());
85   if (config.encoder.enable_dtx)
86     sdp_params["usedtx"] = "1";
87 
88   // SdpAudioFormat::num_channels indicates that the encoder is capable of
89   // stereo, but the actual channel count used is based on the "stereo"
90   // parameter.
91   send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
92       CallTest::kAudioSendPayloadType, {"opus", 48000, 2, sdp_params});
93   RTC_DCHECK_LE(config.source.channels, 2);
94   send_config.encoder_factory = encoder_factory;
95 
96   if (config.encoder.fixed_rate)
97     send_config.send_codec_spec->target_bitrate_bps =
98         config.encoder.fixed_rate->bps();
99   if (!config.adapt.binary_proto.empty()) {
100     send_config.audio_network_adaptor_config = config.adapt.binary_proto;
101   } else if (config.network_adaptation) {
102     send_config.audio_network_adaptor_config =
103         CreateAdaptationString(config.adapt);
104   }
105   if (config.encoder.allocate_bitrate ||
106       config.stream.in_bandwidth_estimation) {
107     DataRate min_rate = DataRate::Infinity();
108     DataRate max_rate = DataRate::Infinity();
109     if (config.encoder.fixed_rate) {
110       min_rate = *config.encoder.fixed_rate;
111       max_rate = *config.encoder.fixed_rate;
112     } else {
113       min_rate = *config.encoder.min_rate;
114       max_rate = *config.encoder.max_rate;
115     }
116     send_config.min_bitrate_bps = min_rate.bps();
117     send_config.max_bitrate_bps = max_rate.bps();
118   }
119 
120   if (config.stream.in_bandwidth_estimation) {
121     send_config.send_codec_spec->transport_cc_enabled = true;
122     send_config.rtp.extensions = {{RtpExtension::kTransportSequenceNumberUri,
123                                    kTransportSequenceNumberExtensionId}};
124   }
125   if (config.stream.abs_send_time) {
126     send_config.rtp.extensions.push_back(
127         {RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId});
128   }
129 
130   sender_->SendTask([&] {
131     send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
132     sender->call_->OnAudioTransportOverheadChanged(
133         sender_->transport_->packet_overhead().bytes());
134   });
135 }
136 
~SendAudioStream()137 SendAudioStream::~SendAudioStream() {
138   sender_->SendTask(
139       [this] { sender_->call_->DestroyAudioSendStream(send_stream_); });
140 }
141 
Start()142 void SendAudioStream::Start() {
143   sender_->SendTask([this] {
144     send_stream_->Start();
145     sender_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
146   });
147 }
148 
Stop()149 void SendAudioStream::Stop() {
150   sender_->SendTask([this] { send_stream_->Stop(); });
151 }
152 
SetMuted(bool mute)153 void SendAudioStream::SetMuted(bool mute) {
154   sender_->SendTask([this, mute] { send_stream_->SetMuted(mute); });
155 }
156 
StatsPrinter()157 ColumnPrinter SendAudioStream::StatsPrinter() {
158   return ColumnPrinter::Lambda(
159       "audio_target_rate",
160       [this](rtc::SimpleStringBuilder& sb) {
161         sender_->SendTask([this, &sb] {
162           AudioSendStream::Stats stats = send_stream_->GetStats();
163           sb.AppendFormat("%.0lf", stats.target_bitrate_bps / 8.0);
164         });
165       },
166       64);
167 }
168 
ReceiveAudioStream(CallClient * receiver,AudioStreamConfig config,SendAudioStream * send_stream,rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,Transport * feedback_transport)169 ReceiveAudioStream::ReceiveAudioStream(
170     CallClient* receiver,
171     AudioStreamConfig config,
172     SendAudioStream* send_stream,
173     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
174     Transport* feedback_transport)
175     : receiver_(receiver), config_(config) {
176   AudioReceiveStreamInterface::Config recv_config;
177   recv_config.rtp.local_ssrc = receiver_->GetNextAudioLocalSsrc();
178   recv_config.rtcp_send_transport = feedback_transport;
179   recv_config.rtp.remote_ssrc = send_stream->ssrc_;
180   receiver->ssrc_media_types_[recv_config.rtp.remote_ssrc] = MediaType::AUDIO;
181   if (config.stream.in_bandwidth_estimation) {
182     recv_config.rtp.transport_cc = true;
183     recv_config.rtp.extensions = {{RtpExtension::kTransportSequenceNumberUri,
184                                    kTransportSequenceNumberExtensionId}};
185   }
186   recv_config.decoder_factory = decoder_factory;
187   recv_config.decoder_map = {
188       {CallTest::kAudioSendPayloadType, {"opus", 48000, 2}}};
189   recv_config.sync_group = config.render.sync_group;
190   receiver_->SendTask([&] {
191     receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config);
192   });
193 }
~ReceiveAudioStream()194 ReceiveAudioStream::~ReceiveAudioStream() {
195   receiver_->SendTask(
196       [&] { receiver_->call_->DestroyAudioReceiveStream(receive_stream_); });
197 }
198 
Start()199 void ReceiveAudioStream::Start() {
200   receiver_->SendTask([&] {
201     receive_stream_->Start();
202     receiver_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
203   });
204 }
205 
Stop()206 void ReceiveAudioStream::Stop() {
207   receiver_->SendTask([&] { receive_stream_->Stop(); });
208 }
209 
GetStats() const210 AudioReceiveStreamInterface::Stats ReceiveAudioStream::GetStats() const {
211   AudioReceiveStreamInterface::Stats result;
212   receiver_->SendTask([&] {
213     result = receive_stream_->GetStats(/*get_and_clear_legacy_stats=*/true);
214   });
215   return result;
216 }
217 
218 AudioStreamPair::~AudioStreamPair() = default;
219 
AudioStreamPair(CallClient * sender,rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,CallClient * receiver,rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,AudioStreamConfig config)220 AudioStreamPair::AudioStreamPair(
221     CallClient* sender,
222     rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
223     CallClient* receiver,
224     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
225     AudioStreamConfig config)
226     : config_(config),
227       send_stream_(sender, config, encoder_factory, sender->transport_.get()),
228       receive_stream_(receiver,
229                       config,
230                       &send_stream_,
231                       decoder_factory,
232                       receiver->transport_.get()) {}
233 
234 }  // namespace test
235 }  // namespace webrtc
236