blob: 21acebb2aeef2465598ba56247e5d5359a5fa26e [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
12#include "test/call_test.h"
13
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020014#if WEBRTC_ENABLE_PROTOBUF
15RTC_PUSH_IGNORING_WUNDEF()
16#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
17#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
18#else
19#include "modules/audio_coding/audio_network_adaptor/config.pb.h"
20#endif
21RTC_POP_IGNORING_WUNDEF()
22#endif
23
Sebastian Jansson98b07e92018-09-27 13:47:01 +020024namespace webrtc {
25namespace test {
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020026namespace {
27absl::optional<std::string> CreateAdaptationString(
28 AudioStreamConfig::NetworkAdaptation config) {
29#if WEBRTC_ENABLE_PROTOBUF
30
31 audio_network_adaptor::config::ControllerManager cont_conf;
32 if (config.frame.max_rate_for_60_ms.IsFinite()) {
33 auto controller =
34 cont_conf.add_controllers()->mutable_frame_length_controller();
35 controller->set_fl_decreasing_packet_loss_fraction(
36 config.frame.min_packet_loss_for_decrease);
37 controller->set_fl_increasing_packet_loss_fraction(
38 config.frame.max_packet_loss_for_increase);
39
40 controller->set_fl_20ms_to_60ms_bandwidth_bps(
41 config.frame.min_rate_for_20_ms.bps<int32_t>());
42 controller->set_fl_60ms_to_20ms_bandwidth_bps(
43 config.frame.max_rate_for_60_ms.bps<int32_t>());
44
45 if (config.frame.max_rate_for_120_ms.IsFinite()) {
46 controller->set_fl_60ms_to_120ms_bandwidth_bps(
47 config.frame.min_rate_for_60_ms.bps<int32_t>());
48 controller->set_fl_120ms_to_60ms_bandwidth_bps(
49 config.frame.max_rate_for_120_ms.bps<int32_t>());
50 }
51 }
52 cont_conf.add_controllers()->mutable_bitrate_controller();
53 std::string config_string = cont_conf.SerializeAsString();
54 return config_string;
55#else
56 RTC_LOG(LS_ERROR) << "audio_network_adaptation is enabled"
57 " but WEBRTC_ENABLE_PROTOBUF is false.\n"
58 "Ignoring settings.";
59 return absl::nullopt;
60#endif // WEBRTC_ENABLE_PROTOBUF
61}
62} // namespace
Sebastian Jansson98b07e92018-09-27 13:47:01 +020063
64SendAudioStream::SendAudioStream(
65 CallClient* sender,
66 AudioStreamConfig config,
67 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
68 Transport* send_transport)
69 : sender_(sender), config_(config) {
70 AudioSendStream::Config send_config(send_transport);
71 ssrc_ = sender->GetNextAudioSsrc();
72 send_config.rtp.ssrc = ssrc_;
73 SdpAudioFormat::Parameters sdp_params;
74 if (config.source.channels == 2)
75 sdp_params["stereo"] = "1";
76 if (config.encoder.initial_frame_length != TimeDelta::ms(20))
77 sdp_params["ptime"] =
78 std::to_string(config.encoder.initial_frame_length.ms());
79
80 // SdpAudioFormat::num_channels indicates that the encoder is capable of
81 // stereo, but the actual channel count used is based on the "stereo"
82 // parameter.
83 send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec(
84 CallTest::kAudioSendPayloadType, {"opus", 48000, 2, sdp_params});
85 RTC_DCHECK_LE(config.source.channels, 2);
86 send_config.encoder_factory = encoder_factory;
87
88 if (config.encoder.fixed_rate)
89 send_config.send_codec_spec->target_bitrate_bps =
90 config.encoder.fixed_rate->bps();
91
Sebastian Janssonb9972fa2018-10-17 16:27:55 +020092 if (config.network_adaptation) {
93 send_config.audio_network_adaptor_config =
94 CreateAdaptationString(config.adapt);
95 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +020096 if (config.encoder.allocate_bitrate ||
97 config.stream.in_bandwidth_estimation) {
98 DataRate min_rate = DataRate::Infinity();
99 DataRate max_rate = DataRate::Infinity();
100 if (config.encoder.fixed_rate) {
101 min_rate = *config.encoder.fixed_rate;
102 max_rate = *config.encoder.fixed_rate;
103 } else {
104 min_rate = *config.encoder.min_rate;
105 max_rate = *config.encoder.max_rate;
106 }
107 if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
Sebastian Janssonb9972fa2018-10-17 16:27:55 +0200108 TimeDelta min_frame_length = config.encoder.initial_frame_length;
109 ;
110 TimeDelta max_frame_length = config.encoder.initial_frame_length;
111 ;
112 if (field_trial::IsEnabled("WebRTC-Audio-FrameLengthAdaptation") &&
113 !config.adapt.frame.min_rate_for_20_ms.IsZero()) {
114 if (!config.adapt.frame.min_rate_for_60_ms.IsZero()) {
115 max_frame_length = TimeDelta::ms(120);
116 } else {
117 max_frame_length = TimeDelta::ms(60);
118 }
119 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200120 DataSize rtp_overhead = DataSize::bytes(12);
121 DataSize total_overhead = config.stream.packet_overhead + rtp_overhead;
Sebastian Janssonb9972fa2018-10-17 16:27:55 +0200122 min_rate += total_overhead / max_frame_length;
123 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
135 if (config.stream.rate_allocation_priority) {
136 send_config.track_id = sender->GetNextPriorityId();
137 }
138 send_stream_ = sender_->call_->CreateAudioSendStream(send_config);
139 if (field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200140 sender->call_->OnAudioTransportOverheadChanged(
141 config.stream.packet_overhead.bytes());
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200142 }
143}
144
145SendAudioStream::~SendAudioStream() {
146 sender_->call_->DestroyAudioSendStream(send_stream_);
147}
148
149void SendAudioStream::Start() {
150 send_stream_->Start();
151}
152
153bool SendAudioStream::TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
154 uint64_t receiver,
155 Timestamp at_time) {
156 // Removes added overhead before delivering RTCP packet to sender.
157 RTC_DCHECK_GE(packet.size(), config_.stream.packet_overhead.bytes());
158 packet.SetSize(packet.size() - config_.stream.packet_overhead.bytes());
159 sender_->DeliverPacket(MediaType::AUDIO, packet, at_time);
160 return true;
161}
162ReceiveAudioStream::ReceiveAudioStream(
163 CallClient* receiver,
164 AudioStreamConfig config,
165 SendAudioStream* send_stream,
166 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
167 Transport* feedback_transport)
168 : receiver_(receiver), config_(config) {
169 AudioReceiveStream::Config recv_config;
170 recv_config.rtp.local_ssrc = CallTest::kReceiverLocalAudioSsrc;
171 recv_config.rtcp_send_transport = feedback_transport;
172 recv_config.rtp.remote_ssrc = send_stream->ssrc_;
173 if (config.stream.in_bandwidth_estimation) {
174 recv_config.rtp.transport_cc = true;
175 recv_config.rtp.extensions = {
176 {RtpExtension::kTransportSequenceNumberUri, 8}};
177 }
178 recv_config.decoder_factory = decoder_factory;
179 recv_config.decoder_map = {
180 {CallTest::kAudioSendPayloadType, {"opus", 48000, 2}}};
181 recv_config.sync_group = config.render.sync_group;
182 receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config);
183}
184ReceiveAudioStream::~ReceiveAudioStream() {
185 receiver_->call_->DestroyAudioReceiveStream(receive_stream_);
186}
187
188bool ReceiveAudioStream::TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
189 uint64_t receiver,
190 Timestamp at_time) {
191 RTC_DCHECK_GE(packet.size(), config_.stream.packet_overhead.bytes());
192 packet.SetSize(packet.size() - config_.stream.packet_overhead.bytes());
193 receiver_->DeliverPacket(MediaType::AUDIO, packet, at_time);
194 return true;
195}
196
197AudioStreamPair::~AudioStreamPair() = default;
198
199AudioStreamPair::AudioStreamPair(
200 CallClient* sender,
201 std::vector<NetworkNode*> send_link,
202 uint64_t send_receiver_id,
203 rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
204 CallClient* receiver,
205 std::vector<NetworkNode*> return_link,
206 uint64_t return_receiver_id,
207 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
208 AudioStreamConfig config)
209 : config_(config),
210 send_link_(send_link),
211 return_link_(return_link),
212 send_transport_(sender,
213 send_link.front(),
214 send_receiver_id,
215 config.stream.packet_overhead),
216 return_transport_(receiver,
217 return_link.front(),
218 return_receiver_id,
219 config.stream.packet_overhead),
220 send_stream_(sender, config, encoder_factory, &send_transport_),
221 receive_stream_(receiver,
222 config,
223 &send_stream_,
224 decoder_factory,
225 &return_transport_) {
226 NetworkNode::Route(send_transport_.ReceiverId(), send_link_,
227 &receive_stream_);
228 NetworkNode::Route(return_transport_.ReceiverId(), return_link_,
229 &send_stream_);
230}
231
232} // namespace test
233} // namespace webrtc