blob: cc25ee4697919be3511c9546b7c9aa6f78d7723a [file] [log] [blame]
solenbergc7a8b082015-10-16 14:35:07 -07001/*
2 * Copyright (c) 2015 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "audio/audio_send_stream.h"
solenbergc7a8b082015-10-16 14:35:07 -070012
13#include <string>
ossu20a4b3f2017-04-27 02:08:52 -070014#include <utility>
15#include <vector>
solenbergc7a8b082015-10-16 14:35:07 -070016
Niels Möllerfa4e1852018-08-14 09:43:34 +020017#include "absl/memory/memory.h"
Yves Gerey988cc082018-10-23 12:03:01 +020018#include "api/audio_codecs/audio_encoder.h"
19#include "api/audio_codecs/audio_encoder_factory.h"
20#include "api/audio_codecs/audio_format.h"
21#include "api/call/transport.h"
22#include "api/crypto/frameencryptorinterface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "audio/audio_state.h"
Yves Gerey988cc082018-10-23 12:03:01 +020024#include "audio/channel_send.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "audio/conversion.h"
Yves Gerey988cc082018-10-23 12:03:01 +020026#include "call/rtp_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "call/rtp_transport_controller_send_interface.h"
Yves Gerey988cc082018-10-23 12:03:01 +020028#include "common_audio/vad/include/vad.h"
Oskar Sundbom56ef3052018-10-30 16:11:02 +010029#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
30#include "logging/rtc_event_log/rtc_event_log.h"
31#include "logging/rtc_event_log/rtc_stream_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
Yves Gerey988cc082018-10-23 12:03:01 +020033#include "modules/audio_processing/include/audio_processing.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/checks.h"
35#include "rtc_base/event.h"
36#include "rtc_base/function_view.h"
37#include "rtc_base/logging.h"
Jonas Olssonabbe8412018-04-03 13:40:05 +020038#include "rtc_base/strings/audio_format_to_string.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020039#include "rtc_base/task_queue.h"
40#include "rtc_base/timeutils.h"
Alex Narestcedd3512017-12-07 20:54:55 +010041#include "system_wrappers/include/field_trial.h"
solenbergc7a8b082015-10-16 14:35:07 -070042
43namespace webrtc {
solenbergc7a8b082015-10-16 14:35:07 -070044namespace internal {
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +010045namespace {
eladalonedd6eea2017-05-25 00:15:35 -070046// TODO(eladalon): Subsequent CL will make these values experiment-dependent.
elad.alond12a8e12017-03-23 11:04:48 -070047constexpr size_t kPacketLossTrackerMaxWindowSizeMs = 15000;
48constexpr size_t kPacketLossRateMinNumAckedPackets = 50;
49constexpr size_t kRecoverablePacketLossRateMinNumAckedPairs = 40;
50
Niels Möllerdced9f62018-11-19 10:27:07 +010051void CallEncoder(const std::unique_ptr<voe::ChannelSendInterface>& channel_send,
ossu20a4b3f2017-04-27 02:08:52 -070052 rtc::FunctionView<void(AudioEncoder*)> lambda) {
Niels Möllerdced9f62018-11-19 10:27:07 +010053 channel_send->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder_ptr) {
ossu20a4b3f2017-04-27 02:08:52 -070054 RTC_DCHECK(encoder_ptr);
55 lambda(encoder_ptr->get());
56 });
57}
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +010058
Oskar Sundbom56ef3052018-10-30 16:11:02 +010059void UpdateEventLogStreamConfig(RtcEventLog* event_log,
60 const AudioSendStream::Config& config,
61 const AudioSendStream::Config* old_config) {
62 using SendCodecSpec = AudioSendStream::Config::SendCodecSpec;
63 // Only update if any of the things we log have changed.
64 auto payload_types_equal = [](const absl::optional<SendCodecSpec>& a,
65 const absl::optional<SendCodecSpec>& b) {
66 if (a.has_value() && b.has_value()) {
67 return a->format.name == b->format.name &&
68 a->payload_type == b->payload_type;
69 }
70 return !a.has_value() && !b.has_value();
71 };
72
73 if (old_config && config.rtp.ssrc == old_config->rtp.ssrc &&
74 config.rtp.extensions == old_config->rtp.extensions &&
75 payload_types_equal(config.send_codec_spec,
76 old_config->send_codec_spec)) {
77 return;
78 }
79
80 auto rtclog_config = absl::make_unique<rtclog::StreamConfig>();
81 rtclog_config->local_ssrc = config.rtp.ssrc;
82 rtclog_config->rtp_extensions = config.rtp.extensions;
83 if (config.send_codec_spec) {
84 rtclog_config->codecs.emplace_back(config.send_codec_spec->format.name,
85 config.send_codec_spec->payload_type, 0);
86 }
87 event_log->Log(absl::make_unique<RtcEventAudioSendStreamConfig>(
88 std::move(rtclog_config)));
89}
90
ossu20a4b3f2017-04-27 02:08:52 -070091} // namespace
92
Sam Zackrisson06953ba2018-02-01 16:53:16 +010093// Helper class to track the actively sending lifetime of this stream.
sazac58f8c02017-07-19 00:39:19 -070094class AudioSendStream::TimedTransport : public Transport {
95 public:
96 TimedTransport(Transport* transport, TimeInterval* time_interval)
97 : transport_(transport), lifetime_(time_interval) {}
98 bool SendRtp(const uint8_t* packet,
99 size_t length,
100 const PacketOptions& options) {
101 if (lifetime_) {
102 lifetime_->Extend();
103 }
104 return transport_->SendRtp(packet, length, options);
105 }
106 bool SendRtcp(const uint8_t* packet, size_t length) {
107 return transport_->SendRtcp(packet, length);
108 }
109 ~TimedTransport() {}
110
111 private:
112 Transport* transport_;
113 TimeInterval* lifetime_;
114};
115
solenberg566ef242015-11-06 15:34:49 -0800116AudioSendStream::AudioSendStream(
117 const webrtc::AudioSendStream::Config& config,
Stefan Holmerb86d4e42015-12-07 10:26:18 +0100118 const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
perkj26091b12016-09-01 01:17:40 -0700119 rtc::TaskQueue* worker_queue,
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100120 ProcessThread* module_process_thread,
Niels Möller7d76a312018-10-26 12:57:07 +0200121 RtpTransportControllerSendInterface* rtp_transport,
Niels Möller67b011d2018-10-22 13:00:40 +0200122 BitrateAllocatorInterface* bitrate_allocator,
michaelt9332b7d2016-11-30 07:51:13 -0800123 RtcEventLog* event_log,
ossuc3d4b482017-05-23 06:07:11 -0700124 RtcpRttStats* rtcp_rtt_stats,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200125 const absl::optional<RtpState>& suspended_rtp_state,
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100126 TimeInterval* overall_call_lifetime)
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100127 : AudioSendStream(config,
128 audio_state,
129 worker_queue,
Niels Möller7d76a312018-10-26 12:57:07 +0200130 rtp_transport,
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100131 bitrate_allocator,
132 event_log,
133 rtcp_rtt_stats,
134 suspended_rtp_state,
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100135 overall_call_lifetime,
Niels Möllerdced9f62018-11-19 10:27:07 +0100136 voe::CreateChannelSend(worker_queue,
137 module_process_thread,
138 config.media_transport,
139 rtcp_rtt_stats,
140 event_log,
141 config.frame_encryptor,
142 config.crypto_options,
143 config.rtp.extmap_allow_mixed,
144 config.rtcp_report_interval_ms)) {}
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100145
146AudioSendStream::AudioSendStream(
147 const webrtc::AudioSendStream::Config& config,
148 const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
149 rtc::TaskQueue* worker_queue,
Niels Möller7d76a312018-10-26 12:57:07 +0200150 RtpTransportControllerSendInterface* rtp_transport,
Niels Möller67b011d2018-10-22 13:00:40 +0200151 BitrateAllocatorInterface* bitrate_allocator,
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100152 RtcEventLog* event_log,
153 RtcpRttStats* rtcp_rtt_stats,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200154 const absl::optional<RtpState>& suspended_rtp_state,
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100155 TimeInterval* overall_call_lifetime,
Niels Möllerdced9f62018-11-19 10:27:07 +0100156 std::unique_ptr<voe::ChannelSendInterface> channel_send)
perkj26091b12016-09-01 01:17:40 -0700157 : worker_queue_(worker_queue),
Niels Möller7d76a312018-10-26 12:57:07 +0200158 config_(Config(/*send_transport=*/nullptr,
159 /*media_transport=*/nullptr)),
mflodman86cc6ff2016-07-26 04:44:06 -0700160 audio_state_(audio_state),
Niels Möllerdced9f62018-11-19 10:27:07 +0100161 channel_send_(std::move(channel_send)),
ossu20a4b3f2017-04-27 02:08:52 -0700162 event_log_(event_log),
michaeltf4caaab2017-01-16 23:55:07 -0800163 bitrate_allocator_(bitrate_allocator),
Niels Möller7d76a312018-10-26 12:57:07 +0200164 rtp_transport_(rtp_transport),
elad.alond12a8e12017-03-23 11:04:48 -0700165 packet_loss_tracker_(kPacketLossTrackerMaxWindowSizeMs,
166 kPacketLossRateMinNumAckedPackets,
ossuc3d4b482017-05-23 06:07:11 -0700167 kRecoverablePacketLossRateMinNumAckedPairs),
168 rtp_rtcp_module_(nullptr),
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100169 suspended_rtp_state_(suspended_rtp_state),
170 overall_call_lifetime_(overall_call_lifetime) {
Jonas Olsson24ea8222018-01-25 10:14:29 +0100171 RTC_LOG(LS_INFO) << "AudioSendStream: " << config.rtp.ssrc;
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100172 RTC_DCHECK(worker_queue_);
173 RTC_DCHECK(audio_state_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100174 RTC_DCHECK(channel_send_);
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100175 RTC_DCHECK(bitrate_allocator_);
Niels Möller7d76a312018-10-26 12:57:07 +0200176 // TODO(nisse): Eventually, we should have only media_transport. But for the
177 // time being, we can have either. When media transport is injected, there
178 // should be no rtp_transport, and below check should be strengthened to XOR
179 // (either rtp_transport or media_transport but not both).
180 RTC_DCHECK(rtp_transport || config.media_transport);
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100181 RTC_DCHECK(overall_call_lifetime_);
solenberg3a941542015-11-16 07:34:50 -0800182
Niels Möllerdced9f62018-11-19 10:27:07 +0100183 rtp_rtcp_module_ = channel_send_->GetRtpRtcp();
ossuc3d4b482017-05-23 06:07:11 -0700184 RTC_DCHECK(rtp_rtcp_module_);
mflodman3d7db262016-04-29 00:57:13 -0700185
ossu20a4b3f2017-04-27 02:08:52 -0700186 ConfigureStream(this, config, true);
elad.alond12a8e12017-03-23 11:04:48 -0700187
188 pacer_thread_checker_.DetachFromThread();
Niels Möller7d76a312018-10-26 12:57:07 +0200189 if (rtp_transport_) {
190 // Signal congestion controller this object is ready for OnPacket*
191 // callbacks.
192 rtp_transport_->RegisterPacketFeedbackObserver(this);
193 }
solenbergc7a8b082015-10-16 14:35:07 -0700194}
195
196AudioSendStream::~AudioSendStream() {
elad.alond12a8e12017-03-23 11:04:48 -0700197 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Jonas Olsson24ea8222018-01-25 10:14:29 +0100198 RTC_LOG(LS_INFO) << "~AudioSendStream: " << config_.rtp.ssrc;
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100199 RTC_DCHECK(!sending_);
Niels Möller7d76a312018-10-26 12:57:07 +0200200 if (rtp_transport_) {
201 rtp_transport_->DeRegisterPacketFeedbackObserver(this);
Niels Möllerdced9f62018-11-19 10:27:07 +0100202 channel_send_->RegisterTransport(nullptr);
203 channel_send_->ResetSenderCongestionControlObjects();
Niels Möller7d76a312018-10-26 12:57:07 +0200204 }
Sam Zackrisson06953ba2018-02-01 16:53:16 +0100205 // Lifetime can only be updated after deregistering
206 // |timed_send_transport_adapter_| in the underlying channel object to avoid
207 // data races in |active_lifetime_|.
208 overall_call_lifetime_->Extend(active_lifetime_);
solenbergc7a8b082015-10-16 14:35:07 -0700209}
210
eladalonabbc4302017-07-26 02:09:44 -0700211const webrtc::AudioSendStream::Config& AudioSendStream::GetConfig() const {
212 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
213 return config_;
214}
215
ossu20a4b3f2017-04-27 02:08:52 -0700216void AudioSendStream::Reconfigure(
217 const webrtc::AudioSendStream::Config& new_config) {
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100218 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
ossu20a4b3f2017-04-27 02:08:52 -0700219 ConfigureStream(this, new_config, false);
220}
221
Alex Narestcedd3512017-12-07 20:54:55 +0100222AudioSendStream::ExtensionIds AudioSendStream::FindExtensionIds(
223 const std::vector<RtpExtension>& extensions) {
224 ExtensionIds ids;
225 for (const auto& extension : extensions) {
226 if (extension.uri == RtpExtension::kAudioLevelUri) {
227 ids.audio_level = extension.id;
228 } else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
229 ids.transport_sequence_number = extension.id;
Steve Antonbb50ce52018-03-26 10:24:32 -0700230 } else if (extension.uri == RtpExtension::kMidUri) {
231 ids.mid = extension.id;
Alex Narestcedd3512017-12-07 20:54:55 +0100232 }
233 }
234 return ids;
235}
236
ossu20a4b3f2017-04-27 02:08:52 -0700237void AudioSendStream::ConfigureStream(
238 webrtc::internal::AudioSendStream* stream,
239 const webrtc::AudioSendStream::Config& new_config,
240 bool first_time) {
Jonas Olsson24ea8222018-01-25 10:14:29 +0100241 RTC_LOG(LS_INFO) << "AudioSendStream::ConfigureStream: "
242 << new_config.ToString();
Oskar Sundbom56ef3052018-10-30 16:11:02 +0100243 UpdateEventLogStreamConfig(stream->event_log_, new_config,
244 first_time ? nullptr : &stream->config_);
245
Niels Möllerdced9f62018-11-19 10:27:07 +0100246 const auto& channel_send = stream->channel_send_;
ossu20a4b3f2017-04-27 02:08:52 -0700247 const auto& old_config = stream->config_;
248
249 if (first_time || old_config.rtp.ssrc != new_config.rtp.ssrc) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100250 channel_send->SetLocalSSRC(new_config.rtp.ssrc);
ossuc3d4b482017-05-23 06:07:11 -0700251 if (stream->suspended_rtp_state_) {
252 stream->rtp_rtcp_module_->SetRtpState(*stream->suspended_rtp_state_);
253 }
ossu20a4b3f2017-04-27 02:08:52 -0700254 }
255 if (first_time || old_config.rtp.c_name != new_config.rtp.c_name) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100256 channel_send->SetRTCP_CNAME(new_config.rtp.c_name);
ossu20a4b3f2017-04-27 02:08:52 -0700257 }
ossu20a4b3f2017-04-27 02:08:52 -0700258
Yves Gerey665174f2018-06-19 15:03:05 +0200259 if (first_time || new_config.send_transport != old_config.send_transport) {
ossu20a4b3f2017-04-27 02:08:52 -0700260 if (old_config.send_transport) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100261 channel_send->RegisterTransport(nullptr);
ossu20a4b3f2017-04-27 02:08:52 -0700262 }
sazac58f8c02017-07-19 00:39:19 -0700263 if (new_config.send_transport) {
264 stream->timed_send_transport_adapter_.reset(new TimedTransport(
265 new_config.send_transport, &stream->active_lifetime_));
266 } else {
267 stream->timed_send_transport_adapter_.reset(nullptr);
268 }
Niels Möllerdced9f62018-11-19 10:27:07 +0100269 channel_send->RegisterTransport(
sazac58f8c02017-07-19 00:39:19 -0700270 stream->timed_send_transport_adapter_.get());
ossu20a4b3f2017-04-27 02:08:52 -0700271 }
272
Benjamin Wright84583f62018-10-04 14:22:34 -0700273 // Enable the frame encryptor if a new frame encryptor has been provided.
274 if (first_time || new_config.frame_encryptor != old_config.frame_encryptor) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100275 channel_send->SetFrameEncryptor(new_config.frame_encryptor);
Benjamin Wright84583f62018-10-04 14:22:34 -0700276 }
277
Johannes Kron9190b822018-10-29 11:22:05 +0100278 if (first_time ||
279 new_config.rtp.extmap_allow_mixed != old_config.rtp.extmap_allow_mixed) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100280 channel_send->SetExtmapAllowMixed(new_config.rtp.extmap_allow_mixed);
Johannes Kron9190b822018-10-29 11:22:05 +0100281 }
282
Alex Narestcedd3512017-12-07 20:54:55 +0100283 const ExtensionIds old_ids = FindExtensionIds(old_config.rtp.extensions);
284 const ExtensionIds new_ids = FindExtensionIds(new_config.rtp.extensions);
ossu20a4b3f2017-04-27 02:08:52 -0700285 // Audio level indication
286 if (first_time || new_ids.audio_level != old_ids.audio_level) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100287 channel_send->SetSendAudioLevelIndicationStatus(new_ids.audio_level != 0,
288 new_ids.audio_level);
ossu20a4b3f2017-04-27 02:08:52 -0700289 }
Sebastian Jansson8d9c5402017-11-15 17:22:16 +0100290 bool transport_seq_num_id_changed =
291 new_ids.transport_sequence_number != old_ids.transport_sequence_number;
Alex Narest867e5102018-06-12 13:40:18 +0200292 if (first_time ||
293 (transport_seq_num_id_changed &&
294 !webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC"))) {
ossu1129df22017-06-30 01:38:56 -0700295 if (!first_time) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100296 channel_send->ResetSenderCongestionControlObjects();
ossu20a4b3f2017-04-27 02:08:52 -0700297 }
298
Sebastian Jansson8d9c5402017-11-15 17:22:16 +0100299 RtcpBandwidthObserver* bandwidth_observer = nullptr;
Alex Narest867e5102018-06-12 13:40:18 +0200300 bool has_transport_sequence_number =
301 new_ids.transport_sequence_number != 0 &&
302 !webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC");
Sebastian Jansson8d9c5402017-11-15 17:22:16 +0100303 if (has_transport_sequence_number) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100304 channel_send->EnableSendTransportSequenceNumber(
ossu20a4b3f2017-04-27 02:08:52 -0700305 new_ids.transport_sequence_number);
Sebastian Jansson8d9c5402017-11-15 17:22:16 +0100306 // Probing in application limited region is only used in combination with
307 // send side congestion control, wich depends on feedback packets which
308 // requires transport sequence numbers to be enabled.
Niels Möller7d76a312018-10-26 12:57:07 +0200309 if (stream->rtp_transport_) {
310 stream->rtp_transport_->EnablePeriodicAlrProbing(true);
311 bandwidth_observer = stream->rtp_transport_->GetBandwidthObserver();
312 }
ossu20a4b3f2017-04-27 02:08:52 -0700313 }
Niels Möller7d76a312018-10-26 12:57:07 +0200314 if (stream->rtp_transport_) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100315 channel_send->RegisterSenderCongestionControlObjects(
Niels Möller7d76a312018-10-26 12:57:07 +0200316 stream->rtp_transport_, bandwidth_observer);
317 }
ossu20a4b3f2017-04-27 02:08:52 -0700318 }
Steve Antonbb50ce52018-03-26 10:24:32 -0700319 // MID RTP header extension.
Steve Anton003930a2018-03-29 12:37:21 -0700320 if ((first_time || new_ids.mid != old_ids.mid ||
321 new_config.rtp.mid != old_config.rtp.mid) &&
322 new_ids.mid != 0 && !new_config.rtp.mid.empty()) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100323 channel_send->SetMid(new_config.rtp.mid, new_ids.mid);
Steve Antonbb50ce52018-03-26 10:24:32 -0700324 }
325
ossu20a4b3f2017-04-27 02:08:52 -0700326 if (!ReconfigureSendCodec(stream, new_config)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100327 RTC_LOG(LS_ERROR) << "Failed to set up send codec state.";
ossu20a4b3f2017-04-27 02:08:52 -0700328 }
329
Oskar Sundbomf85e31b2017-12-20 16:38:09 +0100330 if (stream->sending_) {
331 ReconfigureBitrateObserver(stream, new_config);
332 }
ossu20a4b3f2017-04-27 02:08:52 -0700333 stream->config_ = new_config;
334}
335
solenberg3a941542015-11-16 07:34:50 -0800336void AudioSendStream::Start() {
elad.alond12a8e12017-03-23 11:04:48 -0700337 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100338 if (sending_) {
339 return;
340 }
341
Sebastian Jansson763e9472018-03-21 12:46:56 +0100342 bool has_transport_sequence_number =
Alex Narest867e5102018-06-12 13:40:18 +0200343 FindExtensionIds(config_.rtp.extensions).transport_sequence_number != 0 &&
344 !webrtc::field_trial::IsEnabled("WebRTC-Audio-ForceNoTWCC");
Alex Narestcedd3512017-12-07 20:54:55 +0100345 if (config_.min_bitrate_bps != -1 && config_.max_bitrate_bps != -1 &&
Tim Haloun648d28a2018-10-18 16:52:22 -0700346 !config_.has_dscp &&
Sebastian Jansson763e9472018-03-21 12:46:56 +0100347 (has_transport_sequence_number ||
Alex Narestbcf91802018-06-25 16:08:36 +0200348 !webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe") ||
349 webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC"))) {
Alex Narest78609d52017-10-20 10:37:47 +0200350 // Audio BWE is enabled.
Niels Möller7d76a312018-10-26 12:57:07 +0200351 rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
Sebastian Janssonb6863962018-10-10 10:23:13 +0200352 rtp_rtcp_module_->SetAsPartOfAllocation(true);
Seth Hampson24722b32017-12-22 09:36:42 -0800353 ConfigureBitrateObserver(config_.min_bitrate_bps, config_.max_bitrate_bps,
Sebastian Jansson763e9472018-03-21 12:46:56 +0100354 config_.bitrate_priority,
355 has_transport_sequence_number);
Sebastian Janssonb6863962018-10-10 10:23:13 +0200356 } else {
357 rtp_rtcp_module_->SetAsPartOfAllocation(false);
mflodman86cc6ff2016-07-26 04:44:06 -0700358 }
Niels Möllerdced9f62018-11-19 10:27:07 +0100359 channel_send_->StartSend();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100360 sending_ = true;
361 audio_state()->AddSendingStream(this, encoder_sample_rate_hz_,
362 encoder_num_channels_);
solenberg3a941542015-11-16 07:34:50 -0800363}
364
365void AudioSendStream::Stop() {
elad.alond12a8e12017-03-23 11:04:48 -0700366 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100367 if (!sending_) {
368 return;
369 }
370
ossu20a4b3f2017-04-27 02:08:52 -0700371 RemoveBitrateObserver();
Niels Möllerdced9f62018-11-19 10:27:07 +0100372 channel_send_->StopSend();
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100373 sending_ = false;
374 audio_state()->RemoveSendingStream(this);
375}
376
377void AudioSendStream::SendAudioData(std::unique_ptr<AudioFrame> audio_frame) {
378 RTC_CHECK_RUNS_SERIALIZED(&audio_capture_race_checker_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100379 channel_send_->ProcessAndEncodeAudio(std::move(audio_frame));
solenberg3a941542015-11-16 07:34:50 -0800380}
381
solenbergffbbcac2016-11-17 05:25:37 -0800382bool AudioSendStream::SendTelephoneEvent(int payload_type,
Yves Gerey665174f2018-06-19 15:03:05 +0200383 int payload_frequency,
384 int event,
solenberg8842c3e2016-03-11 03:06:41 -0800385 int duration_ms) {
elad.alond12a8e12017-03-23 11:04:48 -0700386 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Niels Möllerdced9f62018-11-19 10:27:07 +0100387 return channel_send_->SetSendTelephoneEventPayloadType(payload_type,
388 payload_frequency) &&
389 channel_send_->SendTelephoneEventOutband(event, duration_ms);
Fredrik Solenbergb5727682015-12-04 15:22:19 +0100390}
391
solenberg94218532016-06-16 10:53:22 -0700392void AudioSendStream::SetMuted(bool muted) {
elad.alond12a8e12017-03-23 11:04:48 -0700393 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Niels Möllerdced9f62018-11-19 10:27:07 +0100394 channel_send_->SetInputMute(muted);
solenberg94218532016-06-16 10:53:22 -0700395}
396
solenbergc7a8b082015-10-16 14:35:07 -0700397webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const {
Ivo Creusen56d46092017-11-24 17:29:59 +0100398 return GetStats(true);
399}
400
401webrtc::AudioSendStream::Stats AudioSendStream::GetStats(
402 bool has_remote_tracks) const {
elad.alond12a8e12017-03-23 11:04:48 -0700403 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
solenberg85a04962015-10-27 03:35:21 -0700404 webrtc::AudioSendStream::Stats stats;
405 stats.local_ssrc = config_.rtp.ssrc;
Niels Möllerdced9f62018-11-19 10:27:07 +0100406 stats.target_bitrate_bps = channel_send_->GetBitrate();
solenberg85a04962015-10-27 03:35:21 -0700407
Niels Möllerdced9f62018-11-19 10:27:07 +0100408 webrtc::CallSendStatistics call_stats = channel_send_->GetRTCPStatistics();
solenberg85a04962015-10-27 03:35:21 -0700409 stats.bytes_sent = call_stats.bytesSent;
410 stats.packets_sent = call_stats.packetsSent;
solenberg8b85de22015-11-16 09:48:04 -0800411 // RTT isn't known until a RTCP report is received. Until then, VoiceEngine
412 // returns 0 to indicate an error value.
413 if (call_stats.rttMs > 0) {
414 stats.rtt_ms = call_stats.rttMs;
415 }
ossu20a4b3f2017-04-27 02:08:52 -0700416 if (config_.send_codec_spec) {
417 const auto& spec = *config_.send_codec_spec;
418 stats.codec_name = spec.format.name;
Oskar Sundbom2707fb22017-11-16 10:57:35 +0100419 stats.codec_payload_type = spec.payload_type;
solenberg85a04962015-10-27 03:35:21 -0700420
421 // Get data from the last remote RTCP report.
Niels Möllerdced9f62018-11-19 10:27:07 +0100422 for (const auto& block : channel_send_->GetRemoteRTCPReportBlocks()) {
solenberg8b85de22015-11-16 09:48:04 -0800423 // Lookup report for send ssrc only.
424 if (block.source_SSRC == stats.local_ssrc) {
425 stats.packets_lost = block.cumulative_num_packets_lost;
426 stats.fraction_lost = Q8ToFloat(block.fraction_lost);
427 stats.ext_seqnum = block.extended_highest_sequence_number;
ossu20a4b3f2017-04-27 02:08:52 -0700428 // Convert timestamps to milliseconds.
429 if (spec.format.clockrate_hz / 1000 > 0) {
solenberg8b85de22015-11-16 09:48:04 -0800430 stats.jitter_ms =
ossu20a4b3f2017-04-27 02:08:52 -0700431 block.interarrival_jitter / (spec.format.clockrate_hz / 1000);
solenberg85a04962015-10-27 03:35:21 -0700432 }
solenberg8b85de22015-11-16 09:48:04 -0800433 break;
solenberg85a04962015-10-27 03:35:21 -0700434 }
435 }
436 }
437
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100438 AudioState::Stats input_stats = audio_state()->GetAudioInputStats();
439 stats.audio_level = input_stats.audio_level;
440 stats.total_input_energy = input_stats.total_energy;
441 stats.total_input_duration = input_stats.total_duration;
solenberg796b8f92017-03-01 17:02:23 -0800442
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100443 stats.typing_noise_detected = audio_state()->typing_noise_detected();
Niels Möllerdced9f62018-11-19 10:27:07 +0100444 stats.ana_statistics = channel_send_->GetANAStatistics();
Ivo Creusen56d46092017-11-24 17:29:59 +0100445 RTC_DCHECK(audio_state_->audio_processing());
446 stats.apm_statistics =
447 audio_state_->audio_processing()->GetStatistics(has_remote_tracks);
solenberg85a04962015-10-27 03:35:21 -0700448
449 return stats;
450}
451
pbos1ba8d392016-05-01 20:18:34 -0700452void AudioSendStream::SignalNetworkState(NetworkState state) {
elad.alond12a8e12017-03-23 11:04:48 -0700453 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
pbos1ba8d392016-05-01 20:18:34 -0700454}
455
456bool AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
457 // TODO(solenberg): Tests call this function on a network thread, libjingle
458 // calls on the worker thread. We should move towards always using a network
459 // thread. Then this check can be enabled.
elad.alond12a8e12017-03-23 11:04:48 -0700460 // RTC_DCHECK(!worker_thread_checker_.CalledOnValidThread());
Niels Möllerdced9f62018-11-19 10:27:07 +0100461 return channel_send_->ReceivedRTCPPacket(packet, length);
pbos1ba8d392016-05-01 20:18:34 -0700462}
463
Sebastian Janssonc0e4d452018-10-25 15:08:32 +0200464uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) {
stefanfca900a2017-04-10 03:53:00 -0700465 // A send stream may be allocated a bitrate of zero if the allocator decides
466 // to disable it. For now we ignore this decision and keep sending on min
467 // bitrate.
Sebastian Jansson13e59032018-11-21 19:13:07 +0100468 if (update.target_bitrate.IsZero()) {
469 update.target_bitrate = DataRate::bps(config_.min_bitrate_bps);
stefanfca900a2017-04-10 03:53:00 -0700470 }
Sebastian Jansson13e59032018-11-21 19:13:07 +0100471 RTC_DCHECK_GE(update.target_bitrate.bps<int>(), config_.min_bitrate_bps);
mflodman86cc6ff2016-07-26 04:44:06 -0700472 // The bitrate allocator might allocate an higher than max configured bitrate
473 // if there is room, to allow for, as example, extra FEC. Ignore that for now.
Sebastian Jansson13e59032018-11-21 19:13:07 +0100474 const DataRate max_bitrate = DataRate::bps(config_.max_bitrate_bps);
475 if (update.target_bitrate > max_bitrate)
476 update.target_bitrate = max_bitrate;
mflodman86cc6ff2016-07-26 04:44:06 -0700477
Sebastian Jansson13e59032018-11-21 19:13:07 +0100478 channel_send_->SetBitrate(update.target_bitrate.bps(),
479 update.bwe_period.ms());
mflodman86cc6ff2016-07-26 04:44:06 -0700480
481 // The amount of audio protection is not exposed by the encoder, hence
482 // always returning 0.
483 return 0;
484}
485
elad.alond12a8e12017-03-23 11:04:48 -0700486void AudioSendStream::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
487 RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread());
488 // Only packets that belong to this stream are of interest.
489 if (ssrc == config_.rtp.ssrc) {
490 rtc::CritScope lock(&packet_loss_tracker_cs_);
eladalonedd6eea2017-05-25 00:15:35 -0700491 // TODO(eladalon): This function call could potentially reset the window,
elad.alond12a8e12017-03-23 11:04:48 -0700492 // setting both PLR and RPLR to unknown. Consider (during upcoming
493 // refactoring) passing an indication of such an event.
494 packet_loss_tracker_.OnPacketAdded(seq_num, rtc::TimeMillis());
495 }
496}
497
498void AudioSendStream::OnPacketFeedbackVector(
499 const std::vector<PacketFeedback>& packet_feedback_vector) {
eladalon3651fdd2017-08-24 07:26:25 -0700500 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200501 absl::optional<float> plr;
502 absl::optional<float> rplr;
elad.alond12a8e12017-03-23 11:04:48 -0700503 {
504 rtc::CritScope lock(&packet_loss_tracker_cs_);
505 packet_loss_tracker_.OnPacketFeedbackVector(packet_feedback_vector);
506 plr = packet_loss_tracker_.GetPacketLossRate();
elad.alondadb4dc2017-03-23 15:29:50 -0700507 rplr = packet_loss_tracker_.GetRecoverablePacketLossRate();
elad.alond12a8e12017-03-23 11:04:48 -0700508 }
eladalonedd6eea2017-05-25 00:15:35 -0700509 // TODO(eladalon): If R/PLR go back to unknown, no indication is given that
elad.alond12a8e12017-03-23 11:04:48 -0700510 // the previously sent value is no longer relevant. This will be taken care
511 // of with some refactoring which is now being done.
512 if (plr) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100513 channel_send_->OnTwccBasedUplinkPacketLossRate(*plr);
elad.alond12a8e12017-03-23 11:04:48 -0700514 }
elad.alondadb4dc2017-03-23 15:29:50 -0700515 if (rplr) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100516 channel_send_->OnRecoverableUplinkPacketLossRate(*rplr);
elad.alondadb4dc2017-03-23 15:29:50 -0700517 }
elad.alond12a8e12017-03-23 11:04:48 -0700518}
519
michaelt79e05882016-11-08 02:50:09 -0800520void AudioSendStream::SetTransportOverhead(int transport_overhead_per_packet) {
elad.alond12a8e12017-03-23 11:04:48 -0700521 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Niels Möllerdced9f62018-11-19 10:27:07 +0100522 channel_send_->SetTransportOverhead(transport_overhead_per_packet);
michaelt79e05882016-11-08 02:50:09 -0800523}
524
ossuc3d4b482017-05-23 06:07:11 -0700525RtpState AudioSendStream::GetRtpState() const {
526 return rtp_rtcp_module_->GetRtpState();
527}
528
Niels Möllerdced9f62018-11-19 10:27:07 +0100529const voe::ChannelSendInterface* AudioSendStream::GetChannel() const {
530 return channel_send_.get();
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100531}
532
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100533internal::AudioState* AudioSendStream::audio_state() {
534 internal::AudioState* audio_state =
535 static_cast<internal::AudioState*>(audio_state_.get());
536 RTC_DCHECK(audio_state);
537 return audio_state;
538}
539
540const internal::AudioState* AudioSendStream::audio_state() const {
541 internal::AudioState* audio_state =
542 static_cast<internal::AudioState*>(audio_state_.get());
543 RTC_DCHECK(audio_state);
544 return audio_state;
545}
546
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100547void AudioSendStream::StoreEncoderProperties(int sample_rate_hz,
548 size_t num_channels) {
549 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
550 encoder_sample_rate_hz_ = sample_rate_hz;
551 encoder_num_channels_ = num_channels;
552 if (sending_) {
553 // Update AudioState's information about the stream.
554 audio_state()->AddSendingStream(this, sample_rate_hz, num_channels);
555 }
556}
557
minyue7a973442016-10-20 03:27:12 -0700558// Apply current codec settings to a single voe::Channel used for sending.
ossu20a4b3f2017-04-27 02:08:52 -0700559bool AudioSendStream::SetupSendCodec(AudioSendStream* stream,
560 const Config& new_config) {
561 RTC_DCHECK(new_config.send_codec_spec);
562 const auto& spec = *new_config.send_codec_spec;
minyue48368ad2017-05-10 04:06:11 -0700563
564 RTC_DCHECK(new_config.encoder_factory);
ossu20a4b3f2017-04-27 02:08:52 -0700565 std::unique_ptr<AudioEncoder> encoder =
Karl Wiberg77490b92018-03-21 15:18:42 +0100566 new_config.encoder_factory->MakeAudioEncoder(
567 spec.payload_type, spec.format, new_config.codec_pair_id);
minyue7a973442016-10-20 03:27:12 -0700568
ossu20a4b3f2017-04-27 02:08:52 -0700569 if (!encoder) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200570 RTC_DLOG(LS_ERROR) << "Unable to create encoder for "
571 << rtc::ToString(spec.format);
ossu20a4b3f2017-04-27 02:08:52 -0700572 return false;
573 }
Alex Narestbbbe4e12018-07-13 10:32:58 +0200574
575 // If other side does not support audio TWCC and WebRTC-Audio-ABWENoTWCC is
576 // not enabled, do not update target audio bitrate if we are in
577 // WebRTC-Audio-SendSideBwe-For-Video experiment
578 const bool do_not_update_target_bitrate =
579 !webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC") &&
580 webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe-For-Video") &&
581 !FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
ossu20a4b3f2017-04-27 02:08:52 -0700582 // If a bitrate has been specified for the codec, use it over the
583 // codec's default.
Alex Narestbbbe4e12018-07-13 10:32:58 +0200584 if (!do_not_update_target_bitrate && spec.target_bitrate_bps) {
ossu20a4b3f2017-04-27 02:08:52 -0700585 encoder->OnReceivedTargetAudioBitrate(*spec.target_bitrate_bps);
minyue7a973442016-10-20 03:27:12 -0700586 }
587
ossu20a4b3f2017-04-27 02:08:52 -0700588 // Enable ANA if configured (currently only used by Opus).
589 if (new_config.audio_network_adaptor_config) {
590 if (encoder->EnableAudioNetworkAdaptor(
591 *new_config.audio_network_adaptor_config, stream->event_log_)) {
Jonas Olsson24ea8222018-01-25 10:14:29 +0100592 RTC_DLOG(LS_INFO) << "Audio network adaptor enabled on SSRC "
593 << new_config.rtp.ssrc;
ossu20a4b3f2017-04-27 02:08:52 -0700594 } else {
595 RTC_NOTREACHED();
minyue6b825df2016-10-31 04:08:32 -0700596 }
minyue7a973442016-10-20 03:27:12 -0700597 }
598
ossu20a4b3f2017-04-27 02:08:52 -0700599 // Wrap the encoder in a an AudioEncoderCNG, if VAD is enabled.
600 if (spec.cng_payload_type) {
Karl Wiberg23659362018-11-01 11:13:44 +0100601 AudioEncoderCngConfig cng_config;
ossu20a4b3f2017-04-27 02:08:52 -0700602 cng_config.num_channels = encoder->NumChannels();
603 cng_config.payload_type = *spec.cng_payload_type;
604 cng_config.speech_encoder = std::move(encoder);
605 cng_config.vad_mode = Vad::kVadNormal;
Karl Wiberg23659362018-11-01 11:13:44 +0100606 encoder = CreateComfortNoiseEncoder(std::move(cng_config));
ossu3b9ff382017-04-27 08:03:42 -0700607
608 stream->RegisterCngPayloadType(
609 *spec.cng_payload_type,
610 new_config.send_codec_spec->format.clockrate_hz);
minyue7a973442016-10-20 03:27:12 -0700611 }
ossu20a4b3f2017-04-27 02:08:52 -0700612
Fredrik Solenberg2a877972017-12-15 16:42:15 +0100613 stream->StoreEncoderProperties(encoder->SampleRateHz(),
614 encoder->NumChannels());
Niels Möllerdced9f62018-11-19 10:27:07 +0100615 stream->channel_send_->SetEncoder(new_config.send_codec_spec->payload_type,
616 std::move(encoder));
minyue7a973442016-10-20 03:27:12 -0700617 return true;
618}
619
ossu20a4b3f2017-04-27 02:08:52 -0700620bool AudioSendStream::ReconfigureSendCodec(AudioSendStream* stream,
621 const Config& new_config) {
622 const auto& old_config = stream->config_;
minyue-webrtc8de18262017-07-26 14:18:40 +0200623
624 if (!new_config.send_codec_spec) {
625 // We cannot de-configure a send codec. So we will do nothing.
626 // By design, the send codec should have not been configured.
627 RTC_DCHECK(!old_config.send_codec_spec);
628 return true;
629 }
630
631 if (new_config.send_codec_spec == old_config.send_codec_spec &&
632 new_config.audio_network_adaptor_config ==
633 old_config.audio_network_adaptor_config) {
ossu20a4b3f2017-04-27 02:08:52 -0700634 return true;
635 }
636
637 // If we have no encoder, or the format or payload type's changed, create a
638 // new encoder.
639 if (!old_config.send_codec_spec ||
640 new_config.send_codec_spec->format !=
641 old_config.send_codec_spec->format ||
642 new_config.send_codec_spec->payload_type !=
643 old_config.send_codec_spec->payload_type) {
644 return SetupSendCodec(stream, new_config);
645 }
646
Alex Narestbbbe4e12018-07-13 10:32:58 +0200647 // If other side does not support audio TWCC and WebRTC-Audio-ABWENoTWCC is
648 // not enabled, do not update target audio bitrate if we are in
649 // WebRTC-Audio-SendSideBwe-For-Video experiment
650 const bool do_not_update_target_bitrate =
651 !webrtc::field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC") &&
652 webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe-For-Video") &&
653 !FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
654
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200655 const absl::optional<int>& new_target_bitrate_bps =
ossu20a4b3f2017-04-27 02:08:52 -0700656 new_config.send_codec_spec->target_bitrate_bps;
657 // If a bitrate has been specified for the codec, use it over the
658 // codec's default.
Alex Narestbbbe4e12018-07-13 10:32:58 +0200659 if (!do_not_update_target_bitrate && new_target_bitrate_bps &&
ossu20a4b3f2017-04-27 02:08:52 -0700660 new_target_bitrate_bps !=
661 old_config.send_codec_spec->target_bitrate_bps) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100662 CallEncoder(stream->channel_send_, [&](AudioEncoder* encoder) {
ossu20a4b3f2017-04-27 02:08:52 -0700663 encoder->OnReceivedTargetAudioBitrate(*new_target_bitrate_bps);
664 });
665 }
666
667 ReconfigureANA(stream, new_config);
668 ReconfigureCNG(stream, new_config);
669
670 return true;
671}
672
673void AudioSendStream::ReconfigureANA(AudioSendStream* stream,
674 const Config& new_config) {
675 if (new_config.audio_network_adaptor_config ==
676 stream->config_.audio_network_adaptor_config) {
677 return;
678 }
679 if (new_config.audio_network_adaptor_config) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100680 CallEncoder(stream->channel_send_, [&](AudioEncoder* encoder) {
ossu20a4b3f2017-04-27 02:08:52 -0700681 if (encoder->EnableAudioNetworkAdaptor(
682 *new_config.audio_network_adaptor_config, stream->event_log_)) {
Jonas Olsson24ea8222018-01-25 10:14:29 +0100683 RTC_DLOG(LS_INFO) << "Audio network adaptor enabled on SSRC "
684 << new_config.rtp.ssrc;
ossu20a4b3f2017-04-27 02:08:52 -0700685 } else {
686 RTC_NOTREACHED();
687 }
688 });
689 } else {
Niels Möllerdced9f62018-11-19 10:27:07 +0100690 CallEncoder(stream->channel_send_, [&](AudioEncoder* encoder) {
ossu20a4b3f2017-04-27 02:08:52 -0700691 encoder->DisableAudioNetworkAdaptor();
692 });
Jonas Olsson24ea8222018-01-25 10:14:29 +0100693 RTC_DLOG(LS_INFO) << "Audio network adaptor disabled on SSRC "
694 << new_config.rtp.ssrc;
ossu20a4b3f2017-04-27 02:08:52 -0700695 }
696}
697
698void AudioSendStream::ReconfigureCNG(AudioSendStream* stream,
699 const Config& new_config) {
700 if (new_config.send_codec_spec->cng_payload_type ==
701 stream->config_.send_codec_spec->cng_payload_type) {
702 return;
703 }
704
ossu3b9ff382017-04-27 08:03:42 -0700705 // Register the CNG payload type if it's been added, don't do anything if CNG
706 // is removed. Payload types must not be redefined.
707 if (new_config.send_codec_spec->cng_payload_type) {
708 stream->RegisterCngPayloadType(
709 *new_config.send_codec_spec->cng_payload_type,
710 new_config.send_codec_spec->format.clockrate_hz);
711 }
712
ossu20a4b3f2017-04-27 02:08:52 -0700713 // Wrap or unwrap the encoder in an AudioEncoderCNG.
Niels Möllerdced9f62018-11-19 10:27:07 +0100714 stream->channel_send_->ModifyEncoder(
ossu20a4b3f2017-04-27 02:08:52 -0700715 [&](std::unique_ptr<AudioEncoder>* encoder_ptr) {
716 std::unique_ptr<AudioEncoder> old_encoder(std::move(*encoder_ptr));
717 auto sub_encoders = old_encoder->ReclaimContainedEncoders();
718 if (!sub_encoders.empty()) {
719 // Replace enc with its sub encoder. We need to put the sub
720 // encoder in a temporary first, since otherwise the old value
721 // of enc would be destroyed before the new value got assigned,
722 // which would be bad since the new value is a part of the old
723 // value.
724 auto tmp = std::move(sub_encoders[0]);
725 old_encoder = std::move(tmp);
726 }
727 if (new_config.send_codec_spec->cng_payload_type) {
Karl Wiberg23659362018-11-01 11:13:44 +0100728 AudioEncoderCngConfig config;
ossu20a4b3f2017-04-27 02:08:52 -0700729 config.speech_encoder = std::move(old_encoder);
730 config.num_channels = config.speech_encoder->NumChannels();
731 config.payload_type = *new_config.send_codec_spec->cng_payload_type;
732 config.vad_mode = Vad::kVadNormal;
Karl Wiberg23659362018-11-01 11:13:44 +0100733 *encoder_ptr = CreateComfortNoiseEncoder(std::move(config));
ossu20a4b3f2017-04-27 02:08:52 -0700734 } else {
735 *encoder_ptr = std::move(old_encoder);
736 }
737 });
738}
739
740void AudioSendStream::ReconfigureBitrateObserver(
741 AudioSendStream* stream,
742 const webrtc::AudioSendStream::Config& new_config) {
743 // Since the Config's default is for both of these to be -1, this test will
744 // allow us to configure the bitrate observer if the new config has bitrate
745 // limits set, but would only have us call RemoveBitrateObserver if we were
746 // previously configured with bitrate limits.
Alex Narestcedd3512017-12-07 20:54:55 +0100747 int new_transport_seq_num_id =
748 FindExtensionIds(new_config.rtp.extensions).transport_sequence_number;
ossu20a4b3f2017-04-27 02:08:52 -0700749 if (stream->config_.min_bitrate_bps == new_config.min_bitrate_bps &&
Alex Narestcedd3512017-12-07 20:54:55 +0100750 stream->config_.max_bitrate_bps == new_config.max_bitrate_bps &&
Seth Hampson24722b32017-12-22 09:36:42 -0800751 stream->config_.bitrate_priority == new_config.bitrate_priority &&
Alex Narestcedd3512017-12-07 20:54:55 +0100752 (FindExtensionIds(stream->config_.rtp.extensions)
753 .transport_sequence_number == new_transport_seq_num_id ||
754 !webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe"))) {
ossu20a4b3f2017-04-27 02:08:52 -0700755 return;
756 }
757
Sebastian Jansson763e9472018-03-21 12:46:56 +0100758 bool has_transport_sequence_number = new_transport_seq_num_id != 0;
Alex Narestcedd3512017-12-07 20:54:55 +0100759 if (new_config.min_bitrate_bps != -1 && new_config.max_bitrate_bps != -1 &&
Tim Haloun648d28a2018-10-18 16:52:22 -0700760 !new_config.has_dscp &&
Sebastian Jansson763e9472018-03-21 12:46:56 +0100761 (has_transport_sequence_number ||
Alex Narestcedd3512017-12-07 20:54:55 +0100762 !webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe"))) {
Niels Möller7d76a312018-10-26 12:57:07 +0200763 stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(true);
Sebastian Jansson763e9472018-03-21 12:46:56 +0100764 stream->ConfigureBitrateObserver(
765 new_config.min_bitrate_bps, new_config.max_bitrate_bps,
766 new_config.bitrate_priority, has_transport_sequence_number);
Sebastian Janssonb6863962018-10-10 10:23:13 +0200767 stream->rtp_rtcp_module_->SetAsPartOfAllocation(true);
ossu20a4b3f2017-04-27 02:08:52 -0700768 } else {
Niels Möller7d76a312018-10-26 12:57:07 +0200769 stream->rtp_transport_->packet_sender()->SetAccountForAudioPackets(false);
ossu20a4b3f2017-04-27 02:08:52 -0700770 stream->RemoveBitrateObserver();
Sebastian Janssonb6863962018-10-10 10:23:13 +0200771 stream->rtp_rtcp_module_->SetAsPartOfAllocation(false);
ossu20a4b3f2017-04-27 02:08:52 -0700772 }
773}
774
775void AudioSendStream::ConfigureBitrateObserver(int min_bitrate_bps,
Seth Hampson24722b32017-12-22 09:36:42 -0800776 int max_bitrate_bps,
Sebastian Jansson763e9472018-03-21 12:46:56 +0100777 double bitrate_priority,
778 bool has_packet_feedback) {
ossu20a4b3f2017-04-27 02:08:52 -0700779 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
780 RTC_DCHECK_GE(max_bitrate_bps, min_bitrate_bps);
Niels Möllerc572ff32018-11-07 08:43:50 +0100781 rtc::Event thread_sync_event;
ossu20a4b3f2017-04-27 02:08:52 -0700782 worker_queue_->PostTask([&] {
783 // We may get a callback immediately as the observer is registered, so make
784 // sure the bitrate limits in config_ are up-to-date.
785 config_.min_bitrate_bps = min_bitrate_bps;
786 config_.max_bitrate_bps = max_bitrate_bps;
Seth Hampson24722b32017-12-22 09:36:42 -0800787 config_.bitrate_priority = bitrate_priority;
788 // This either updates the current observer or adds a new observer.
Sebastian Jansson24ad7202018-04-19 08:25:12 +0200789 bitrate_allocator_->AddObserver(
790 this, MediaStreamAllocationConfig{
791 static_cast<uint32_t>(min_bitrate_bps),
792 static_cast<uint32_t>(max_bitrate_bps), 0, true,
793 config_.track_id, bitrate_priority, has_packet_feedback});
ossu20a4b3f2017-04-27 02:08:52 -0700794 thread_sync_event.Set();
795 });
796 thread_sync_event.Wait(rtc::Event::kForever);
797}
798
799void AudioSendStream::RemoveBitrateObserver() {
800 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
Niels Möllerc572ff32018-11-07 08:43:50 +0100801 rtc::Event thread_sync_event;
ossu20a4b3f2017-04-27 02:08:52 -0700802 worker_queue_->PostTask([this, &thread_sync_event] {
803 bitrate_allocator_->RemoveObserver(this);
804 thread_sync_event.Set();
805 });
806 thread_sync_event.Wait(rtc::Event::kForever);
807}
808
ossu3b9ff382017-04-27 08:03:42 -0700809void AudioSendStream::RegisterCngPayloadType(int payload_type,
810 int clockrate_hz) {
ossu3b9ff382017-04-27 08:03:42 -0700811 const CodecInst codec = {payload_type, "CN", clockrate_hz, 0, 1, 0};
ossuc3d4b482017-05-23 06:07:11 -0700812 if (rtp_rtcp_module_->RegisterSendPayload(codec) != 0) {
813 rtp_rtcp_module_->DeRegisterSendPayload(codec.pltype);
814 if (rtp_rtcp_module_->RegisterSendPayload(codec) != 0) {
Jonas Olsson24ea8222018-01-25 10:14:29 +0100815 RTC_DLOG(LS_ERROR) << "RegisterCngPayloadType() failed to register CN to "
816 "RTP/RTCP module";
ossu3b9ff382017-04-27 08:03:42 -0700817 }
818 }
819}
solenbergc7a8b082015-10-16 14:35:07 -0700820} // namespace internal
821} // namespace webrtc