blob: 076b4eaf8608bc86002b48092b316b78a6cb4765 [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
Sebastian Jansson2b101d22018-11-12 16:33:39 +010012#include "rtc_base/bitrateallocationstrategy.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020013#include "test/call_test.h"
14
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020015#if WEBRTC_ENABLE_PROTOBUF
16RTC_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
22RTC_POP_IGNORING_WUNDEF()
23#endif
24
Sebastian Jansson98b07e92018-09-27 13:47:01 +020025namespace webrtc {
26namespace test {
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020027namespace {
28absl::optional<std::string> CreateAdaptationString(
29 AudioStreamConfig::NetworkAdaptation config) {
30#if WEBRTC_ENABLE_PROTOBUF
31
32 audio_network_adaptor::config::ControllerManager cont_conf;
33 if (config.frame.max_rate_for_60_ms.IsFinite()) {
34 auto controller =
35 cont_conf.add_controllers()->mutable_frame_length_controller();
36 controller->set_fl_decreasing_packet_loss_fraction(
37 config.frame.min_packet_loss_for_decrease);
38 controller->set_fl_increasing_packet_loss_fraction(
39 config.frame.max_packet_loss_for_increase);
40
41 controller->set_fl_20ms_to_60ms_bandwidth_bps(
42 config.frame.min_rate_for_20_ms.bps<int32_t>());
43 controller->set_fl_60ms_to_20ms_bandwidth_bps(
44 config.frame.max_rate_for_60_ms.bps<int32_t>());
45
46 if (config.frame.max_rate_for_120_ms.IsFinite()) {
47 controller->set_fl_60ms_to_120ms_bandwidth_bps(
48 config.frame.min_rate_for_60_ms.bps<int32_t>());
49 controller->set_fl_120ms_to_60ms_bandwidth_bps(
50 config.frame.max_rate_for_120_ms.bps<int32_t>());
51 }
52 }
53 cont_conf.add_controllers()->mutable_bitrate_controller();
54 std::string config_string = cont_conf.SerializeAsString();
55 return config_string;
56#else
57 RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
58 " but WEBRTC_ENABLE_PROTOBUF is false.\n"
59 "Ignoring settings.";
60 return absl::nullopt;
61#endif // WEBRTC_ENABLE_PROTOBUF
62}
63} // namespace
Sebastian Jansson98b07e92018-09-27 13:47:01 +020064
65SendAudioStream::SendAudioStream(
66 CallClient* sender,
67 AudioStreamConfig config,
68 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
69 Transport* send_transport)
70 : sender_(sender), config_(config) {
Niels Möller7d76a312018-10-26 12:57:07 +020071 AudioSendStream::Config send_config(send_transport,
72 /*media_transport=*/nullptr);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020073 ssrc_ = sender->GetNextAudioSsrc();
74 send_config.rtp.ssrc = ssrc_;
75 SdpAudioFormat::Parameters sdp_params;
76 if (config.source.channels == 2)
77 sdp_params["stereo"] = "1";
78 if (config.encoder.initial_frame_length != TimeDelta::ms(20))
79 sdp_params["ptime"] =
80 std::to_string(config.encoder.initial_frame_length.ms());
81
82 // SdpAudioFormat::num_channels indicates that the encoder is capable of
83 // stereo, but the actual channel count used is based on the "stereo"
84 // parameter.
85 send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
86 CallTest::kAudioSendPayloadType, {"opus", 48000, 2, sdp_params});
87 RTC_DCHECK_LE(config.source.channels, 2);
88 send_config.encoder_factory = encoder_factory;
89
90 if (config.encoder.fixed_rate)
91 send_config.send_codec_spec->target_bitrate_bps =
92 config.encoder.fixed_rate->bps();
93
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020094 if (config.network_adaptation) {
95 send_config.audio_network_adaptor_config =
96 CreateAdaptationString(config.adapt);
97 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020098 if (config.encoder.allocate_bitrate ||
99 config.stream.in_bandwidth_estimation) {
100 DataRate min_rate = DataRate::Infinity();
101 DataRate max_rate = DataRate::Infinity();
102 if (config.encoder.fixed_rate) {
103 min_rate = *config.encoder.fixed_rate;
104 max_rate = *config.encoder.fixed_rate;
105 } else {
106 min_rate = *config.encoder.min_rate;
107 max_rate = *config.encoder.max_rate;
108 }
109 if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
Sebastian Janssoned45c572018-10-24 11:18:07 +0200110 TimeDelta min_frame_length = TimeDelta::ms(20);
111 // Note, depends on WEBRTC_OPUS_SUPPORT_120MS_PTIME being set, which is
112 // the default.
113 TimeDelta max_frame_length = TimeDelta::ms(120);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200114 DataSize rtp_overhead = DataSize::bytes(12);
Sebastian Janssoned45c572018-10-24 11:18:07 +0200115 // Note that this does not include rtp extension overhead and will not
116 // follow updates in the transport overhead over time.
Sebastian Jansson800e1212018-10-22 11:49:03 +0200117 DataSize total_overhead =
118 sender_->transport_.packet_overhead() + rtp_overhead;
Sebastian Janssoned45c572018-10-24 11:18:07 +0200119
Sebastian Janssonb9972fa2018-10-17 16:27:55 +0200120 min_rate += total_overhead / max_frame_length;
Sebastian Janssoned45c572018-10-24 11:18:07 +0200121 // In WebRTCVoiceEngine the max rate is also based on the max frame
122 // length.
Sebastian Janssonb9972fa2018-10-17 16:27:55 +0200123 max_rate += total_overhead / min_frame_length;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200124 }
125 send_config.min_bitrate_bps = min_rate.bps();
126 send_config.max_bitrate_bps = max_rate.bps();
127 }
128
129 if (config.stream.in_bandwidth_estimation) {
130 send_config.send_codec_spec->transport_cc_enabled = true;
131 send_config.rtp.extensions = {
132 {RtpExtension::kTransportSequenceNumberUri, 8}};
133 }
134
Sebastian Jansson2b101d22018-11-12 16:33:39 +0100135 if (config.encoder.priority_rate) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200136 send_config.track_id = sender->GetNextPriorityId();
Sebastian Jansson2b101d22018-11-12 16:33:39 +0100137 sender_->call_->SetBitrateAllocationStrategy(
138 absl::make_unique<rtc::AudioPriorityBitrateAllocationStrategy>(
139 send_config.track_id,
140 config.encoder.priority_rate->bps<uint32_t>()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200141 }
142 send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
143 if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200144 sender->call_->OnAudioTransportOverheadChanged(
Sebastian Jansson800e1212018-10-22 11:49:03 +0200145 sender_->transport_.packet_overhead().bytes());
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200146 }
147}
148
149SendAudioStream::~SendAudioStream() {
150 sender_->call_->DestroyAudioSendStream(send_stream_);
151}
152
153void SendAudioStream::Start() {
154 send_stream_->Start();
155}
156
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200157ColumnPrinter SendAudioStream::StatsPrinter() {
158 return ColumnPrinter::Lambda(
159 "audio_target_rate",
160 [this](rtc::SimpleStringBuilder& sb) {
161 AudioSendStream::Stats stats = send_stream_->GetStats();
162 sb.AppendFormat("%.0lf", stats.target_bitrate_bps / 8.0);
163 },
164 64);
165}
166
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200167ReceiveAudioStream::ReceiveAudioStream(
168 CallClient* receiver,
169 AudioStreamConfig config,
170 SendAudioStream* send_stream,
171 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
172 Transport* feedback_transport)
173 : receiver_(receiver), config_(config) {
174 AudioReceiveStream::Config recv_config;
175 recv_config.rtp.local_ssrc = CallTest::kReceiverLocalAudioSsrc;
176 recv_config.rtcp_send_transport = feedback_transport;
177 recv_config.rtp.remote_ssrc = send_stream->ssrc_;
Sebastian Jansson800e1212018-10-22 11:49:03 +0200178 receiver->ssrc_media_types_[recv_config.rtp.remote_ssrc] = MediaType::AUDIO;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200179 if (config.stream.in_bandwidth_estimation) {
180 recv_config.rtp.transport_cc = true;
181 recv_config.rtp.extensions = {
182 {RtpExtension::kTransportSequenceNumberUri, 8}};
183 }
Sebastian Janssonfd201712018-11-12 16:44:16 +0100184 receiver_->AddExtensions(recv_config.rtp.extensions);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200185 recv_config.decoder_factory = decoder_factory;
186 recv_config.decoder_map = {
187 {CallTest::kAudioSendPayloadType, {"opus", 48000, 2}}};
188 recv_config.sync_group = config.render.sync_group;
189 receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config);
190}
191ReceiveAudioStream::~ReceiveAudioStream() {
192 receiver_->call_->DestroyAudioReceiveStream(receive_stream_);
193}
194
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200195AudioStreamPair::~AudioStreamPair() = default;
196
197AudioStreamPair::AudioStreamPair(
198 CallClient* sender,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200199 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
200 CallClient* receiver,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200201 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
202 AudioStreamConfig config)
203 : config_(config),
Sebastian Jansson800e1212018-10-22 11:49:03 +0200204 send_stream_(sender, config, encoder_factory, &sender->transport_),
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200205 receive_stream_(receiver,
206 config,
207 &send_stream_,
208 decoder_factory,
Sebastian Jansson800e1212018-10-22 11:49:03 +0200209 &receiver->transport_) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200210
211} // namespace test
212} // namespace webrtc