blob: 232f7382bd6f444480d3219d8d6b8aab2dfecd30 [file] [log] [blame]
Sebastian Jansson98b07e912018-09-27 11:47:011/*
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 18:21:4712#include "absl/memory/memory.h"
Sebastian Jansson98b07e912018-09-27 11:47:0113#include "test/call_test.h"
Artem Titov8a9f3a82023-04-25 07:56:4914#include "test/video_test_constants.h"
Sebastian Jansson98b07e912018-09-27 11:47:0115
Sebastian Janssonb9972fa2018-10-17 14:27:5516#if WEBRTC_ENABLE_PROTOBUF
Sebastian Janssonb9972fa2018-10-17 14:27:5517#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
Sebastian Janssonb9972fa2018-10-17 14:27:5522#endif
23
Sebastian Jansson98b07e912018-09-27 11:47:0124namespace webrtc {
25namespace test {
Sebastian Janssonb9972fa2018-10-17 14:27:5526namespace {
Sebastian Janssone112bb82019-06-13 15:36:0127enum : int { // The first valid value is 1.
28 kTransportSequenceNumberExtensionId = 1,
29 kAbsSendTimeExtensionId
30};
31
Sebastian Janssonb9972fa2018-10-17 14:27:5532absl::optional<std::string> CreateAdaptationString(
33 AudioStreamConfig::NetworkAdaptation config) {
34#if WEBRTC_ENABLE_PROTOBUF
35
36 audio_network_adaptor::config::ControllerManager cont_conf;
37 if (config.frame.max_rate_for_60_ms.IsFinite()) {
38 auto controller =
39 cont_conf.add_controllers()->mutable_frame_length_controller();
40 controller->set_fl_decreasing_packet_loss_fraction(
41 config.frame.min_packet_loss_for_decrease);
42 controller->set_fl_increasing_packet_loss_fraction(
43 config.frame.max_packet_loss_for_increase);
44
45 controller->set_fl_20ms_to_60ms_bandwidth_bps(
46 config.frame.min_rate_for_20_ms.bps<int32_t>());
47 controller->set_fl_60ms_to_20ms_bandwidth_bps(
48 config.frame.max_rate_for_60_ms.bps<int32_t>());
49
50 if (config.frame.max_rate_for_120_ms.IsFinite()) {
51 controller->set_fl_60ms_to_120ms_bandwidth_bps(
52 config.frame.min_rate_for_60_ms.bps<int32_t>());
53 controller->set_fl_120ms_to_60ms_bandwidth_bps(
54 config.frame.max_rate_for_120_ms.bps<int32_t>());
55 }
56 }
57 cont_conf.add_controllers()->mutable_bitrate_controller();
58 std::string config_string = cont_conf.SerializeAsString();
59 return config_string;
60#else
61 RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
62 " but WEBRTC_ENABLE_PROTOBUF is false.\n"
63 "Ignoring settings.";
64 return absl::nullopt;
65#endif // WEBRTC_ENABLE_PROTOBUF
66}
67} // namespace
Sebastian Jansson98b07e912018-09-27 11:47:0168
Per Kb3046c22023-01-12 16:00:2269std::vector<RtpExtension> GetAudioRtpExtensions(
70 const AudioStreamConfig& config) {
71 std::vector<RtpExtension> extensions;
72 if (config.stream.in_bandwidth_estimation) {
73 extensions.push_back({RtpExtension::kTransportSequenceNumberUri,
74 kTransportSequenceNumberExtensionId});
75 }
76 if (config.stream.abs_send_time) {
77 extensions.push_back(
78 {RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId});
79 }
80 return extensions;
81}
82
Sebastian Jansson98b07e912018-09-27 11:47:0183SendAudioStream::SendAudioStream(
84 CallClient* sender,
85 AudioStreamConfig config,
86 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
87 Transport* send_transport)
88 : sender_(sender), config_(config) {
Bjorn A Mellem7a9a0922019-11-26 17:19:4089 AudioSendStream::Config send_config(send_transport);
Sebastian Jansson98b07e912018-09-27 11:47:0190 ssrc_ = sender->GetNextAudioSsrc();
91 send_config.rtp.ssrc = ssrc_;
Philipp Hanckede172522023-12-14 08:45:3992 CodecParameterMap sdp_params;
Sebastian Jansson98b07e912018-09-27 11:47:0193 if (config.source.channels == 2)
94 sdp_params["stereo"] = "1";
Danil Chapovalov0c626af2020-02-10 10:16:0095 if (config.encoder.initial_frame_length != TimeDelta::Millis(20))
Sebastian Jansson98b07e912018-09-27 11:47:0196 sdp_params["ptime"] =
97 std::to_string(config.encoder.initial_frame_length.ms());
Sebastian Janssonad871942019-01-16 16:21:2898 if (config.encoder.enable_dtx)
99 sdp_params["usedtx"] = "1";
Sebastian Jansson98b07e912018-09-27 11:47:01100
101 // SdpAudioFormat::num_channels indicates that the encoder is capable of
102 // stereo, but the actual channel count used is based on the "stereo"
103 // parameter.
104 send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
Artem Titov8a9f3a82023-04-25 07:56:49105 VideoTestConstants::kAudioSendPayloadType,
106 {"opus", 48000, 2, sdp_params});
Sebastian Jansson98b07e912018-09-27 11:47:01107 RTC_DCHECK_LE(config.source.channels, 2);
108 send_config.encoder_factory = encoder_factory;
109
Per Kjellanderce79f872022-12-02 15:07:09110 bool use_fixed_rate = !config.encoder.min_rate && !config.encoder.max_rate;
111 if (use_fixed_rate)
Sebastian Jansson98b07e912018-09-27 11:47:01112 send_config.send_codec_spec->target_bitrate_bps =
Per Kjellanderce79f872022-12-02 15:07:09113 config.encoder.fixed_rate.bps();
Sebastian Jansson7c1ac762020-02-27 11:04:20114 if (!config.adapt.binary_proto.empty()) {
115 send_config.audio_network_adaptor_config = config.adapt.binary_proto;
116 } else if (config.network_adaptation) {
Sebastian Janssonb9972fa2018-10-17 14:27:55117 send_config.audio_network_adaptor_config =
118 CreateAdaptationString(config.adapt);
119 }
Sebastian Jansson98b07e912018-09-27 11:47:01120 if (config.encoder.allocate_bitrate ||
121 config.stream.in_bandwidth_estimation) {
122 DataRate min_rate = DataRate::Infinity();
123 DataRate max_rate = DataRate::Infinity();
Per Kjellanderce79f872022-12-02 15:07:09124 if (use_fixed_rate) {
125 min_rate = config.encoder.fixed_rate;
126 max_rate = config.encoder.fixed_rate;
Sebastian Jansson98b07e912018-09-27 11:47:01127 } else {
128 min_rate = *config.encoder.min_rate;
129 max_rate = *config.encoder.max_rate;
130 }
Sebastian Jansson98b07e912018-09-27 11:47:01131 send_config.min_bitrate_bps = min_rate.bps();
132 send_config.max_bitrate_bps = max_rate.bps();
133 }
134
135 if (config.stream.in_bandwidth_estimation) {
136 send_config.send_codec_spec->transport_cc_enabled = true;
Sebastian Janssone112bb82019-06-13 15:36:01137 }
Per Kb3046c22023-01-12 16:00:22138 send_config.rtp.extensions = GetAudioRtpExtensions(config);
Sebastian Jansson98b07e912018-09-27 11:47:01139
Sebastian Jansson105a10a2019-04-01 07:18:14140 sender_->SendTask([&] {
141 send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
Per Kjellandere0b4cab2022-11-30 18:41:22142 sender->call_->OnAudioTransportOverheadChanged(
143 sender_->transport_->packet_overhead().bytes());
Sebastian Jansson105a10a2019-04-01 07:18:14144 });
Sebastian Jansson98b07e912018-09-27 11:47:01145}
146
147SendAudioStream::~SendAudioStream() {
Sebastian Jansson105a10a2019-04-01 07:18:14148 sender_->SendTask(
149 [this] { sender_->call_->DestroyAudioSendStream(send_stream_); });
Sebastian Jansson98b07e912018-09-27 11:47:01150}
151
152void SendAudioStream::Start() {
Sebastian Jansson105a10a2019-04-01 07:18:14153 sender_->SendTask([this] {
154 send_stream_->Start();
155 sender_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
156 });
Sebastian Jansson98b07e912018-09-27 11:47:01157}
158
Sebastian Janssonbdfadd62019-02-08 12:34:57159void SendAudioStream::Stop() {
Sebastian Jansson105a10a2019-04-01 07:18:14160 sender_->SendTask([this] { send_stream_->Stop(); });
Sebastian Janssonbdfadd62019-02-08 12:34:57161}
162
Sebastian Janssonad871942019-01-16 16:21:28163void SendAudioStream::SetMuted(bool mute) {
Sebastian Jansson9f215a72020-02-27 10:51:53164 sender_->SendTask([this, mute] { send_stream_->SetMuted(mute); });
Sebastian Janssonad871942019-01-16 16:21:28165}
166
Sebastian Jansson359d60a2018-10-25 14:22:02167ColumnPrinter SendAudioStream::StatsPrinter() {
168 return ColumnPrinter::Lambda(
169 "audio_target_rate",
170 [this](rtc::SimpleStringBuilder& sb) {
Sebastian Jansson105a10a2019-04-01 07:18:14171 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 14:22:02175 },
176 64);
177}
178
Sebastian Jansson98b07e912018-09-27 11:47:01179ReceiveAudioStream::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) {
Tommi3176ef72022-05-22 18:47:28186 AudioReceiveStreamInterface::Config recv_config;
Sebastian Jansson5fbebd52019-02-20 10:16:19187 recv_config.rtp.local_ssrc = receiver_->GetNextAudioLocalSsrc();
Sebastian Jansson98b07e912018-09-27 11:47:01188 recv_config.rtcp_send_transport = feedback_transport;
189 recv_config.rtp.remote_ssrc = send_stream->ssrc_;
Sebastian Jansson800e1212018-10-22 09:49:03190 receiver->ssrc_media_types_[recv_config.rtp.remote_ssrc] = MediaType::AUDIO;
Sebastian Jansson98b07e912018-09-27 11:47:01191 recv_config.decoder_factory = decoder_factory;
192 recv_config.decoder_map = {
Artem Titov8a9f3a82023-04-25 07:56:49193 {VideoTestConstants::kAudioSendPayloadType, {"opus", 48000, 2}}};
Sebastian Jansson98b07e912018-09-27 11:47:01194 recv_config.sync_group = config.render.sync_group;
Sebastian Jansson105a10a2019-04-01 07:18:14195 receiver_->SendTask([&] {
196 receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config);
197 });
Sebastian Jansson98b07e912018-09-27 11:47:01198}
199ReceiveAudioStream::~ReceiveAudioStream() {
Sebastian Jansson105a10a2019-04-01 07:18:14200 receiver_->SendTask(
201 [&] { receiver_->call_->DestroyAudioReceiveStream(receive_stream_); });
Sebastian Jansson98b07e912018-09-27 11:47:01202}
203
Sebastian Jansson49a78432018-11-20 15:15:29204void ReceiveAudioStream::Start() {
Sebastian Jansson105a10a2019-04-01 07:18:14205 receiver_->SendTask([&] {
206 receive_stream_->Start();
207 receiver_->call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
208 });
Sebastian Jansson49a78432018-11-20 15:15:29209}
210
Sebastian Janssonbdfadd62019-02-08 12:34:57211void ReceiveAudioStream::Stop() {
Sebastian Jansson105a10a2019-04-01 07:18:14212 receiver_->SendTask([&] { receive_stream_->Stop(); });
Sebastian Janssonbdfadd62019-02-08 12:34:57213}
214
Tommi3176ef72022-05-22 18:47:28215AudioReceiveStreamInterface::Stats ReceiveAudioStream::GetStats() const {
216 AudioReceiveStreamInterface::Stats result;
Niels Möller6b4d9622020-09-14 08:47:50217 receiver_->SendTask([&] {
218 result = receive_stream_->GetStats(/*get_and_clear_legacy_stats=*/true);
219 });
Sebastian Janssonf4481c82019-04-09 10:48:34220 return result;
221}
222
Sebastian Jansson98b07e912018-09-27 11:47:01223AudioStreamPair::~AudioStreamPair() = default;
224
225AudioStreamPair::AudioStreamPair(
226 CallClient* sender,
Sebastian Jansson98b07e912018-09-27 11:47:01227 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
228 CallClient* receiver,
Sebastian Jansson98b07e912018-09-27 11:47:01229 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
230 AudioStreamConfig config)
231 : config_(config),
Sebastian Jansson105a10a2019-04-01 07:18:14232 send_stream_(sender, config, encoder_factory, sender->transport_.get()),
Sebastian Jansson98b07e912018-09-27 11:47:01233 receive_stream_(receiver,
234 config,
235 &send_stream_,
236 decoder_factory,
Sebastian Jansson105a10a2019-04-01 07:18:14237 receiver->transport_.get()) {}
Sebastian Jansson98b07e912018-09-27 11:47:01238
239} // namespace test
240} // namespace webrtc