blob: 4ff3593c150cc55771f3335ea39f35b36c46a226 [file] [log] [blame]
Sebastian Jansson98b07e92018-09-27 13:47:01 +02001/*
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
Steve Anton40d55332019-01-07 10:21:47 -080012#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080013#include "rtc_base/bitrate_allocation_strategy.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020014#include "test/call_test.h"
15
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020016#if WEBRTC_ENABLE_PROTOBUF
17RTC_PUSH_IGNORING_WUNDEF()
18#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
19#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
20#else
21#include "modules/audio_coding/audio_network_adaptor/config.pb.h"
22#endif
23RTC_POP_IGNORING_WUNDEF()
24#endif
25
Sebastian Jansson98b07e92018-09-27 13:47:01 +020026namespace webrtc {
27namespace test {
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020028namespace {
Sebastian Janssone112bb82019-06-13 17:36:01 +020029enum : int { // The first valid value is 1.
30 kTransportSequenceNumberExtensionId = 1,
31 kAbsSendTimeExtensionId
32};
33
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020034absl::optional<std::string> CreateAdaptationString(
35 AudioStreamConfig::NetworkAdaptation config) {
36#if WEBRTC_ENABLE_PROTOBUF
37
38 audio_network_adaptor::config::ControllerManager cont_conf;
39 if (config.frame.max_rate_for_60_ms.IsFinite()) {
40 auto controller =
41 cont_conf.add_controllers()->mutable_frame_length_controller();
42 controller->set_fl_decreasing_packet_loss_fraction(
43 config.frame.min_packet_loss_for_decrease);
44 controller->set_fl_increasing_packet_loss_fraction(
45 config.frame.max_packet_loss_for_increase);
46
47 controller->set_fl_20ms_to_60ms_bandwidth_bps(
48 config.frame.min_rate_for_20_ms.bps<int32_t>());
49 controller->set_fl_60ms_to_20ms_bandwidth_bps(
50 config.frame.max_rate_for_60_ms.bps<int32_t>());
51
52 if (config.frame.max_rate_for_120_ms.IsFinite()) {
53 controller->set_fl_60ms_to_120ms_bandwidth_bps(
54 config.frame.min_rate_for_60_ms.bps<int32_t>());
55 controller->set_fl_120ms_to_60ms_bandwidth_bps(
56 config.frame.max_rate_for_120_ms.bps<int32_t>());
57 }
58 }
59 cont_conf.add_controllers()->mutable_bitrate_controller();
60 std::string config_string = cont_conf.SerializeAsString();
61 return config_string;
62#else
63 RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
64 " but WEBRTC_ENABLE_PROTOBUF is false.\n"
65 "Ignoring settings.";
66 return absl::nullopt;
67#endif // WEBRTC_ENABLE_PROTOBUF
68}
69} // namespace
Sebastian Jansson98b07e92018-09-27 13:47:01 +020070
71SendAudioStream::SendAudioStream(
72 CallClient* sender,
73 AudioStreamConfig config,
74 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
75 Transport* send_transport)
76 : sender_(sender), config_(config) {
Niels Möller7d76a312018-10-26 12:57:07 +020077 AudioSendStream::Config send_config(send_transport,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070078 webrtc::MediaTransportConfig());
Sebastian Jansson98b07e92018-09-27 13:47:01 +020079 ssrc_ = sender->GetNextAudioSsrc();
80 send_config.rtp.ssrc = ssrc_;
81 SdpAudioFormat::Parameters sdp_params;
82 if (config.source.channels == 2)
83 sdp_params["stereo"] = "1";
84 if (config.encoder.initial_frame_length != TimeDelta::ms(20))
85 sdp_params["ptime"] =
86 std::to_string(config.encoder.initial_frame_length.ms());
Sebastian Janssonad871942019-01-16 17:21:28 +010087 if (config.encoder.enable_dtx)
88 sdp_params["usedtx"] = "1";
Sebastian Jansson98b07e92018-09-27 13:47:01 +020089
90 // SdpAudioFormat::num_channels indicates that the encoder is capable of
91 // stereo, but the actual channel count used is based on the "stereo"
92 // parameter.
93 send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
94 CallTest::kAudioSendPayloadType, {"opus", 48000, 2, sdp_params});
95 RTC_DCHECK_LE(config.source.channels, 2);
96 send_config.encoder_factory = encoder_factory;
97
98 if (config.encoder.fixed_rate)
99 send_config.send_codec_spec->target_bitrate_bps =
100 config.encoder.fixed_rate->bps();
101
Sebastian Janssonb9972fa2018-10-17 16:27:55 +0200102 if (config.network_adaptation) {
103 send_config.audio_network_adaptor_config =
104 CreateAdaptationString(config.adapt);
105 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200106 if (config.encoder.allocate_bitrate ||
107 config.stream.in_bandwidth_estimation) {
108 DataRate min_rate = DataRate::Infinity();
109 DataRate max_rate = DataRate::Infinity();
110 if (config.encoder.fixed_rate) {
111 min_rate = *config.encoder.fixed_rate;
112 max_rate = *config.encoder.fixed_rate;
113 } else {
114 min_rate = *config.encoder.min_rate;
115 max_rate = *config.encoder.max_rate;
116 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200117 send_config.min_bitrate_bps = min_rate.bps();
118 send_config.max_bitrate_bps = max_rate.bps();
119 }
120
121 if (config.stream.in_bandwidth_estimation) {
122 send_config.send_codec_spec->transport_cc_enabled = true;
Sebastian Janssone112bb82019-06-13 17:36:01 +0200123 send_config.rtp.extensions = {{RtpExtension::kTransportSequenceNumberUri,
124 kTransportSequenceNumberExtensionId}};
125 }
126 if (config.stream.abs_send_time) {
127 send_config.rtp.extensions.push_back(
128 {RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId});
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200129 }
130
Sebastian Jansson2b101d22018-11-12 16:33:39 +0100131 if (config.encoder.priority_rate) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200132 send_config.track_id = sender->GetNextPriorityId();
Sebastian Jansson2b101d22018-11-12 16:33:39 +0100133 sender_->call_->SetBitrateAllocationStrategy(
134 absl::make_unique<rtc::AudioPriorityBitrateAllocationStrategy>(
135 send_config.track_id,
136 config.encoder.priority_rate->bps<uint32_t>()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200137 }
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200138 sender_->SendTask([&] {
139 send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
140 if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
141 sender->call_->OnAudioTransportOverheadChanged(
142 sender_->transport_->packet_overhead().bytes());
143 }
144 });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200145}
146
147SendAudioStream::~SendAudioStream() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200148 sender_->SendTask(
149 [this] { sender_->call_->DestroyAudioSendStream(send_stream_); });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200150}
151
152void SendAudioStream::Start() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200153 sender_->SendTask([this] {
154 send_stream_->Start();
155 sender_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
156 });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200157}
158
Sebastian Janssonbdfadd62019-02-08 13:34:57 +0100159void SendAudioStream::Stop() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200160 sender_->SendTask([this] { send_stream_->Stop(); });
Sebastian Janssonbdfadd62019-02-08 13:34:57 +0100161}
162
Sebastian Janssonad871942019-01-16 17:21:28 +0100163void SendAudioStream::SetMuted(bool mute) {
164 send_stream_->SetMuted(mute);
165}
166
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200167ColumnPrinter SendAudioStream::StatsPrinter() {
168 return ColumnPrinter::Lambda(
169 "audio_target_rate",
170 [this](rtc::SimpleStringBuilder& sb) {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200171 sender_->SendTask([this, &sb] {
172 AudioSendStream::Stats stats = send_stream_->GetStats();
173 sb.AppendFormat("%.0lf", stats.target_bitrate_bps / 8.0);
174 });
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200175 },
176 64);
177}
178
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200179ReceiveAudioStream::ReceiveAudioStream(
180 CallClient* receiver,
181 AudioStreamConfig config,
182 SendAudioStream* send_stream,
183 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
184 Transport* feedback_transport)
185 : receiver_(receiver), config_(config) {
186 AudioReceiveStream::Config recv_config;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100187 recv_config.rtp.local_ssrc = receiver_->GetNextAudioLocalSsrc();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200188 recv_config.rtcp_send_transport = feedback_transport;
189 recv_config.rtp.remote_ssrc = send_stream->ssrc_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200190 receiver->ssrc_media_types_[recv_config.rtp.remote_ssrc] = MediaType::AUDIO;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200191 if (config.stream.in_bandwidth_estimation) {
192 recv_config.rtp.transport_cc = true;
193 recv_config.rtp.extensions = {
194 {RtpExtension::kTransportSequenceNumberUri, 8}};
195 }
Sebastian Janssonfd201712018-11-12 16:44:16 +0100196 receiver_->AddExtensions(recv_config.rtp.extensions);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200197 recv_config.decoder_factory = decoder_factory;
198 recv_config.decoder_map = {
199 {CallTest::kAudioSendPayloadType, {"opus", 48000, 2}}};
200 recv_config.sync_group = config.render.sync_group;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200201 receiver_->SendTask([&] {
202 receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config);
203 });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200204}
205ReceiveAudioStream::~ReceiveAudioStream() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200206 receiver_->SendTask(
207 [&] { receiver_->call_->DestroyAudioReceiveStream(receive_stream_); });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200208}
209
Sebastian Jansson49a78432018-11-20 16:15:29 +0100210void ReceiveAudioStream::Start() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200211 receiver_->SendTask([&] {
212 receive_stream_->Start();
213 receiver_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
214 });
Sebastian Jansson49a78432018-11-20 16:15:29 +0100215}
216
Sebastian Janssonbdfadd62019-02-08 13:34:57 +0100217void ReceiveAudioStream::Stop() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200218 receiver_->SendTask([&] { receive_stream_->Stop(); });
Sebastian Janssonbdfadd62019-02-08 13:34:57 +0100219}
220
Sebastian Janssonf4481c82019-04-09 12:48:34 +0200221AudioReceiveStream::Stats ReceiveAudioStream::GetStats() const {
222 AudioReceiveStream::Stats result;
223 receiver_->SendTask([&] { result = receive_stream_->GetStats(); });
224 return result;
225}
226
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200227AudioStreamPair::~AudioStreamPair() = default;
228
229AudioStreamPair::AudioStreamPair(
230 CallClient* sender,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200231 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
232 CallClient* receiver,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200233 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
234 AudioStreamConfig config)
235 : config_(config),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200236 send_stream_(sender, config, encoder_factory, sender->transport_.get()),
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200237 receive_stream_(receiver,
238 config,
239 &send_stream_,
240 decoder_factory,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200241 receiver->transport_.get()) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200242
243} // namespace test
244} // namespace webrtc