1 /*
2 * Copyright (c) 2014 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
11 #include "modules/audio_coding/codecs/opus/audio_encoder_opus.h"
12
13 #include <algorithm>
14 #include <iterator>
15 #include <memory>
16 #include <string>
17 #include <utility>
18
19 #include "absl/strings/match.h"
20 #include "absl/strings/string_view.h"
21 #include "modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
22 #include "modules/audio_coding/audio_network_adaptor/controller_manager.h"
23 #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h"
24 #include "modules/audio_coding/codecs/opus/opus_interface.h"
25 #include "rtc_base/arraysize.h"
26 #include "rtc_base/checks.h"
27 #include "rtc_base/logging.h"
28 #include "rtc_base/numerics/exp_filter.h"
29 #include "rtc_base/numerics/safe_conversions.h"
30 #include "rtc_base/numerics/safe_minmax.h"
31 #include "rtc_base/string_encode.h"
32 #include "rtc_base/string_to_number.h"
33 #include "rtc_base/time_utils.h"
34 #include "system_wrappers/include/field_trial.h"
35
36 namespace webrtc {
37
38 namespace {
39
40 // Codec parameters for Opus.
41 // draft-spittka-payload-rtp-opus-03
42
43 // Recommended bitrates:
44 // 8-12 kb/s for NB speech,
45 // 16-20 kb/s for WB speech,
46 // 28-40 kb/s for FB speech,
47 // 48-64 kb/s for FB mono music, and
48 // 64-128 kb/s for FB stereo music.
49 // The current implementation applies the following values to mono signals,
50 // and multiplies them by 2 for stereo.
51 constexpr int kOpusBitrateNbBps = 12000;
52 constexpr int kOpusBitrateWbBps = 20000;
53 constexpr int kOpusBitrateFbBps = 32000;
54
55 constexpr int kRtpTimestampRateHz = 48000;
56 constexpr int kDefaultMaxPlaybackRate = 48000;
57
58 // These two lists must be sorted from low to high
59 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME
60 constexpr int kANASupportedFrameLengths[] = {20, 40, 60, 120};
61 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60, 120};
62 #else
63 constexpr int kANASupportedFrameLengths[] = {20, 40, 60};
64 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60};
65 #endif
66
67 // PacketLossFractionSmoother uses an exponential filter with a time constant
68 // of -1.0 / ln(0.9999) = 10000 ms.
69 constexpr float kAlphaForPacketLossFractionSmoother = 0.9999f;
70 constexpr float kMaxPacketLossFraction = 0.2f;
71
CalculateDefaultBitrate(int max_playback_rate,size_t num_channels)72 int CalculateDefaultBitrate(int max_playback_rate, size_t num_channels) {
73 const int bitrate = [&] {
74 if (max_playback_rate <= 8000) {
75 return kOpusBitrateNbBps * rtc::dchecked_cast<int>(num_channels);
76 } else if (max_playback_rate <= 16000) {
77 return kOpusBitrateWbBps * rtc::dchecked_cast<int>(num_channels);
78 } else {
79 return kOpusBitrateFbBps * rtc::dchecked_cast<int>(num_channels);
80 }
81 }();
82 RTC_DCHECK_GE(bitrate, AudioEncoderOpusConfig::kMinBitrateBps);
83 RTC_DCHECK_LE(bitrate, AudioEncoderOpusConfig::kMaxBitrateBps);
84 return bitrate;
85 }
86
87 // Get the maxaveragebitrate parameter in string-form, so we can properly figure
88 // out how invalid it is and accurately log invalid values.
CalculateBitrate(int max_playback_rate_hz,size_t num_channels,absl::optional<std::string> bitrate_param)89 int CalculateBitrate(int max_playback_rate_hz,
90 size_t num_channels,
91 absl::optional<std::string> bitrate_param) {
92 const int default_bitrate =
93 CalculateDefaultBitrate(max_playback_rate_hz, num_channels);
94
95 if (bitrate_param) {
96 const auto bitrate = rtc::StringToNumber<int>(*bitrate_param);
97 if (bitrate) {
98 const int chosen_bitrate =
99 std::max(AudioEncoderOpusConfig::kMinBitrateBps,
100 std::min(*bitrate, AudioEncoderOpusConfig::kMaxBitrateBps));
101 if (bitrate != chosen_bitrate) {
102 RTC_LOG(LS_WARNING) << "Invalid maxaveragebitrate " << *bitrate
103 << " clamped to " << chosen_bitrate;
104 }
105 return chosen_bitrate;
106 }
107 RTC_LOG(LS_WARNING) << "Invalid maxaveragebitrate \"" << *bitrate_param
108 << "\" replaced by default bitrate " << default_bitrate;
109 }
110
111 return default_bitrate;
112 }
113
GetChannelCount(const SdpAudioFormat & format)114 int GetChannelCount(const SdpAudioFormat& format) {
115 const auto param = GetFormatParameter(format, "stereo");
116 if (param == "1") {
117 return 2;
118 } else {
119 return 1;
120 }
121 }
122
GetMaxPlaybackRate(const SdpAudioFormat & format)123 int GetMaxPlaybackRate(const SdpAudioFormat& format) {
124 const auto param = GetFormatParameter<int>(format, "maxplaybackrate");
125 if (param && *param >= 8000) {
126 return std::min(*param, kDefaultMaxPlaybackRate);
127 }
128 return kDefaultMaxPlaybackRate;
129 }
130
GetFrameSizeMs(const SdpAudioFormat & format)131 int GetFrameSizeMs(const SdpAudioFormat& format) {
132 const auto ptime = GetFormatParameter<int>(format, "ptime");
133 if (ptime) {
134 // Pick the next highest supported frame length from
135 // kOpusSupportedFrameLengths.
136 for (const int supported_frame_length : kOpusSupportedFrameLengths) {
137 if (supported_frame_length >= *ptime) {
138 return supported_frame_length;
139 }
140 }
141 // If none was found, return the largest supported frame length.
142 return *(std::end(kOpusSupportedFrameLengths) - 1);
143 }
144
145 return AudioEncoderOpusConfig::kDefaultFrameSizeMs;
146 }
147
FindSupportedFrameLengths(int min_frame_length_ms,int max_frame_length_ms,std::vector<int> * out)148 void FindSupportedFrameLengths(int min_frame_length_ms,
149 int max_frame_length_ms,
150 std::vector<int>* out) {
151 out->clear();
152 std::copy_if(std::begin(kANASupportedFrameLengths),
153 std::end(kANASupportedFrameLengths), std::back_inserter(*out),
154 [&](int frame_length_ms) {
155 return frame_length_ms >= min_frame_length_ms &&
156 frame_length_ms <= max_frame_length_ms;
157 });
158 RTC_DCHECK(std::is_sorted(out->begin(), out->end()));
159 }
160
GetBitrateBps(const AudioEncoderOpusConfig & config)161 int GetBitrateBps(const AudioEncoderOpusConfig& config) {
162 RTC_DCHECK(config.IsOk());
163 return *config.bitrate_bps;
164 }
165
GetBitrateMultipliers()166 std::vector<float> GetBitrateMultipliers() {
167 constexpr char kBitrateMultipliersName[] =
168 "WebRTC-Audio-OpusBitrateMultipliers";
169 const bool use_bitrate_multipliers =
170 webrtc::field_trial::IsEnabled(kBitrateMultipliersName);
171 if (use_bitrate_multipliers) {
172 const std::string field_trial_string =
173 webrtc::field_trial::FindFullName(kBitrateMultipliersName);
174 std::vector<std::string> pieces;
175 rtc::tokenize(field_trial_string, '-', &pieces);
176 if (pieces.size() < 2 || pieces[0] != "Enabled") {
177 RTC_LOG(LS_WARNING) << "Invalid parameters for "
178 << kBitrateMultipliersName
179 << ", not using custom values.";
180 return std::vector<float>();
181 }
182 std::vector<float> multipliers(pieces.size() - 1);
183 for (size_t i = 1; i < pieces.size(); i++) {
184 if (!rtc::FromString(pieces[i], &multipliers[i - 1])) {
185 RTC_LOG(LS_WARNING)
186 << "Invalid parameters for " << kBitrateMultipliersName
187 << ", not using custom values.";
188 return std::vector<float>();
189 }
190 }
191 RTC_LOG(LS_INFO) << "Using custom bitrate multipliers: "
192 << field_trial_string;
193 return multipliers;
194 }
195 return std::vector<float>();
196 }
197
GetMultipliedBitrate(int bitrate,const std::vector<float> & multipliers)198 int GetMultipliedBitrate(int bitrate, const std::vector<float>& multipliers) {
199 // The multipliers are valid from 5 kbps.
200 const size_t bitrate_kbps = static_cast<size_t>(bitrate / 1000);
201 if (bitrate_kbps < 5 || bitrate_kbps >= multipliers.size() + 5) {
202 return bitrate;
203 }
204 return static_cast<int>(multipliers[bitrate_kbps - 5] * bitrate);
205 }
206 } // namespace
207
AppendSupportedEncoders(std::vector<AudioCodecSpec> * specs)208 void AudioEncoderOpusImpl::AppendSupportedEncoders(
209 std::vector<AudioCodecSpec>* specs) {
210 const SdpAudioFormat fmt = {"opus",
211 kRtpTimestampRateHz,
212 2,
213 {{"minptime", "10"}, {"useinbandfec", "1"}}};
214 const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
215 specs->push_back({fmt, info});
216 }
217
QueryAudioEncoder(const AudioEncoderOpusConfig & config)218 AudioCodecInfo AudioEncoderOpusImpl::QueryAudioEncoder(
219 const AudioEncoderOpusConfig& config) {
220 RTC_DCHECK(config.IsOk());
221 AudioCodecInfo info(config.sample_rate_hz, config.num_channels,
222 *config.bitrate_bps,
223 AudioEncoderOpusConfig::kMinBitrateBps,
224 AudioEncoderOpusConfig::kMaxBitrateBps);
225 info.allow_comfort_noise = false;
226 info.supports_network_adaption = true;
227 return info;
228 }
229
MakeAudioEncoder(const AudioEncoderOpusConfig & config,int payload_type)230 std::unique_ptr<AudioEncoder> AudioEncoderOpusImpl::MakeAudioEncoder(
231 const AudioEncoderOpusConfig& config,
232 int payload_type) {
233 if (!config.IsOk()) {
234 RTC_DCHECK_NOTREACHED();
235 return nullptr;
236 }
237 return std::make_unique<AudioEncoderOpusImpl>(config, payload_type);
238 }
239
SdpToConfig(const SdpAudioFormat & format)240 absl::optional<AudioEncoderOpusConfig> AudioEncoderOpusImpl::SdpToConfig(
241 const SdpAudioFormat& format) {
242 if (!absl::EqualsIgnoreCase(format.name, "opus") ||
243 format.clockrate_hz != kRtpTimestampRateHz || format.num_channels != 2) {
244 return absl::nullopt;
245 }
246
247 AudioEncoderOpusConfig config;
248 config.num_channels = GetChannelCount(format);
249 config.frame_size_ms = GetFrameSizeMs(format);
250 config.max_playback_rate_hz = GetMaxPlaybackRate(format);
251 config.fec_enabled = (GetFormatParameter(format, "useinbandfec") == "1");
252 config.dtx_enabled = (GetFormatParameter(format, "usedtx") == "1");
253 config.cbr_enabled = (GetFormatParameter(format, "cbr") == "1");
254 config.bitrate_bps =
255 CalculateBitrate(config.max_playback_rate_hz, config.num_channels,
256 GetFormatParameter(format, "maxaveragebitrate"));
257 config.application = config.num_channels == 1
258 ? AudioEncoderOpusConfig::ApplicationMode::kVoip
259 : AudioEncoderOpusConfig::ApplicationMode::kAudio;
260
261 constexpr int kMinANAFrameLength = kANASupportedFrameLengths[0];
262 constexpr int kMaxANAFrameLength =
263 kANASupportedFrameLengths[arraysize(kANASupportedFrameLengths) - 1];
264
265 // For now, minptime and maxptime are only used with ANA. If ptime is outside
266 // of this range, it will get adjusted once ANA takes hold. Ideally, we'd know
267 // if ANA was to be used when setting up the config, and adjust accordingly.
268 const int min_frame_length_ms =
269 GetFormatParameter<int>(format, "minptime").value_or(kMinANAFrameLength);
270 const int max_frame_length_ms =
271 GetFormatParameter<int>(format, "maxptime").value_or(kMaxANAFrameLength);
272
273 FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms,
274 &config.supported_frame_lengths_ms);
275 if (!config.IsOk()) {
276 RTC_DCHECK_NOTREACHED();
277 return absl::nullopt;
278 }
279 return config;
280 }
281
GetNewComplexity(const AudioEncoderOpusConfig & config)282 absl::optional<int> AudioEncoderOpusImpl::GetNewComplexity(
283 const AudioEncoderOpusConfig& config) {
284 RTC_DCHECK(config.IsOk());
285 const int bitrate_bps = GetBitrateBps(config);
286 if (bitrate_bps >= config.complexity_threshold_bps -
287 config.complexity_threshold_window_bps &&
288 bitrate_bps <= config.complexity_threshold_bps +
289 config.complexity_threshold_window_bps) {
290 // Within the hysteresis window; make no change.
291 return absl::nullopt;
292 } else {
293 return bitrate_bps <= config.complexity_threshold_bps
294 ? config.low_rate_complexity
295 : config.complexity;
296 }
297 }
298
GetNewBandwidth(const AudioEncoderOpusConfig & config,OpusEncInst * inst)299 absl::optional<int> AudioEncoderOpusImpl::GetNewBandwidth(
300 const AudioEncoderOpusConfig& config,
301 OpusEncInst* inst) {
302 constexpr int kMinWidebandBitrate = 8000;
303 constexpr int kMaxNarrowbandBitrate = 9000;
304 constexpr int kAutomaticThreshold = 11000;
305 RTC_DCHECK(config.IsOk());
306 const int bitrate = GetBitrateBps(config);
307 if (bitrate > kAutomaticThreshold) {
308 return absl::optional<int>(OPUS_AUTO);
309 }
310 const int bandwidth = WebRtcOpus_GetBandwidth(inst);
311 RTC_DCHECK_GE(bandwidth, 0);
312 if (bitrate > kMaxNarrowbandBitrate && bandwidth < OPUS_BANDWIDTH_WIDEBAND) {
313 return absl::optional<int>(OPUS_BANDWIDTH_WIDEBAND);
314 } else if (bitrate < kMinWidebandBitrate &&
315 bandwidth > OPUS_BANDWIDTH_NARROWBAND) {
316 return absl::optional<int>(OPUS_BANDWIDTH_NARROWBAND);
317 }
318 return absl::optional<int>();
319 }
320
321 class AudioEncoderOpusImpl::PacketLossFractionSmoother {
322 public:
PacketLossFractionSmoother()323 explicit PacketLossFractionSmoother()
324 : last_sample_time_ms_(rtc::TimeMillis()),
325 smoother_(kAlphaForPacketLossFractionSmoother) {}
326
327 // Gets the smoothed packet loss fraction.
GetAverage() const328 float GetAverage() const {
329 float value = smoother_.filtered();
330 return (value == rtc::ExpFilter::kValueUndefined) ? 0.0f : value;
331 }
332
333 // Add new observation to the packet loss fraction smoother.
AddSample(float packet_loss_fraction)334 void AddSample(float packet_loss_fraction) {
335 int64_t now_ms = rtc::TimeMillis();
336 smoother_.Apply(static_cast<float>(now_ms - last_sample_time_ms_),
337 packet_loss_fraction);
338 last_sample_time_ms_ = now_ms;
339 }
340
341 private:
342 int64_t last_sample_time_ms_;
343
344 // An exponential filter is used to smooth the packet loss fraction.
345 rtc::ExpFilter smoother_;
346 };
347
AudioEncoderOpusImpl(const AudioEncoderOpusConfig & config,int payload_type)348 AudioEncoderOpusImpl::AudioEncoderOpusImpl(const AudioEncoderOpusConfig& config,
349 int payload_type)
350 : AudioEncoderOpusImpl(
351 config,
352 payload_type,
353 [this](absl::string_view config_string, RtcEventLog* event_log) {
354 return DefaultAudioNetworkAdaptorCreator(config_string, event_log);
355 },
356 // We choose 5sec as initial time constant due to empirical data.
357 std::make_unique<SmoothingFilterImpl>(5000)) {}
358
AudioEncoderOpusImpl(const AudioEncoderOpusConfig & config,int payload_type,const AudioNetworkAdaptorCreator & audio_network_adaptor_creator,std::unique_ptr<SmoothingFilter> bitrate_smoother)359 AudioEncoderOpusImpl::AudioEncoderOpusImpl(
360 const AudioEncoderOpusConfig& config,
361 int payload_type,
362 const AudioNetworkAdaptorCreator& audio_network_adaptor_creator,
363 std::unique_ptr<SmoothingFilter> bitrate_smoother)
364 : payload_type_(payload_type),
365 use_stable_target_for_adaptation_(!webrtc::field_trial::IsDisabled(
366 "WebRTC-Audio-StableTargetAdaptation")),
367 adjust_bandwidth_(
368 webrtc::field_trial::IsEnabled("WebRTC-AdjustOpusBandwidth")),
369 bitrate_changed_(true),
370 bitrate_multipliers_(GetBitrateMultipliers()),
371 packet_loss_rate_(0.0),
372 inst_(nullptr),
373 packet_loss_fraction_smoother_(new PacketLossFractionSmoother()),
374 audio_network_adaptor_creator_(audio_network_adaptor_creator),
375 bitrate_smoother_(std::move(bitrate_smoother)),
376 consecutive_dtx_frames_(0) {
377 RTC_DCHECK(0 <= payload_type && payload_type <= 127);
378
379 // Sanity check of the redundant payload type field that we want to get rid
380 // of. See https://bugs.chromium.org/p/webrtc/issues/detail?id=7847
381 RTC_CHECK(config.payload_type == -1 || config.payload_type == payload_type);
382
383 RTC_CHECK(RecreateEncoderInstance(config));
384 SetProjectedPacketLossRate(packet_loss_rate_);
385 }
386
AudioEncoderOpusImpl(int payload_type,const SdpAudioFormat & format)387 AudioEncoderOpusImpl::AudioEncoderOpusImpl(int payload_type,
388 const SdpAudioFormat& format)
389 : AudioEncoderOpusImpl(*SdpToConfig(format), payload_type) {}
390
~AudioEncoderOpusImpl()391 AudioEncoderOpusImpl::~AudioEncoderOpusImpl() {
392 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
393 }
394
SampleRateHz() const395 int AudioEncoderOpusImpl::SampleRateHz() const {
396 return config_.sample_rate_hz;
397 }
398
NumChannels() const399 size_t AudioEncoderOpusImpl::NumChannels() const {
400 return config_.num_channels;
401 }
402
RtpTimestampRateHz() const403 int AudioEncoderOpusImpl::RtpTimestampRateHz() const {
404 return kRtpTimestampRateHz;
405 }
406
Num10MsFramesInNextPacket() const407 size_t AudioEncoderOpusImpl::Num10MsFramesInNextPacket() const {
408 return Num10msFramesPerPacket();
409 }
410
Max10MsFramesInAPacket() const411 size_t AudioEncoderOpusImpl::Max10MsFramesInAPacket() const {
412 return Num10msFramesPerPacket();
413 }
414
GetTargetBitrate() const415 int AudioEncoderOpusImpl::GetTargetBitrate() const {
416 return GetBitrateBps(config_);
417 }
418
Reset()419 void AudioEncoderOpusImpl::Reset() {
420 RTC_CHECK(RecreateEncoderInstance(config_));
421 }
422
SetFec(bool enable)423 bool AudioEncoderOpusImpl::SetFec(bool enable) {
424 if (enable) {
425 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_));
426 } else {
427 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_));
428 }
429 config_.fec_enabled = enable;
430 return true;
431 }
432
SetDtx(bool enable)433 bool AudioEncoderOpusImpl::SetDtx(bool enable) {
434 if (enable) {
435 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_));
436 } else {
437 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_));
438 }
439 config_.dtx_enabled = enable;
440 return true;
441 }
442
GetDtx() const443 bool AudioEncoderOpusImpl::GetDtx() const {
444 return config_.dtx_enabled;
445 }
446
SetApplication(Application application)447 bool AudioEncoderOpusImpl::SetApplication(Application application) {
448 auto conf = config_;
449 switch (application) {
450 case Application::kSpeech:
451 conf.application = AudioEncoderOpusConfig::ApplicationMode::kVoip;
452 break;
453 case Application::kAudio:
454 conf.application = AudioEncoderOpusConfig::ApplicationMode::kAudio;
455 break;
456 }
457 return RecreateEncoderInstance(conf);
458 }
459
SetMaxPlaybackRate(int frequency_hz)460 void AudioEncoderOpusImpl::SetMaxPlaybackRate(int frequency_hz) {
461 auto conf = config_;
462 conf.max_playback_rate_hz = frequency_hz;
463 RTC_CHECK(RecreateEncoderInstance(conf));
464 }
465
EnableAudioNetworkAdaptor(const std::string & config_string,RtcEventLog * event_log)466 bool AudioEncoderOpusImpl::EnableAudioNetworkAdaptor(
467 const std::string& config_string,
468 RtcEventLog* event_log) {
469 audio_network_adaptor_ =
470 audio_network_adaptor_creator_(config_string, event_log);
471 return audio_network_adaptor_.get() != nullptr;
472 }
473
DisableAudioNetworkAdaptor()474 void AudioEncoderOpusImpl::DisableAudioNetworkAdaptor() {
475 audio_network_adaptor_.reset(nullptr);
476 }
477
OnReceivedUplinkPacketLossFraction(float uplink_packet_loss_fraction)478 void AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction(
479 float uplink_packet_loss_fraction) {
480 if (audio_network_adaptor_) {
481 audio_network_adaptor_->SetUplinkPacketLossFraction(
482 uplink_packet_loss_fraction);
483 ApplyAudioNetworkAdaptor();
484 }
485 packet_loss_fraction_smoother_->AddSample(uplink_packet_loss_fraction);
486 float average_fraction_loss = packet_loss_fraction_smoother_->GetAverage();
487 SetProjectedPacketLossRate(average_fraction_loss);
488 }
489
OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps)490 void AudioEncoderOpusImpl::OnReceivedTargetAudioBitrate(
491 int target_audio_bitrate_bps) {
492 SetTargetBitrate(target_audio_bitrate_bps);
493 }
494
OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,absl::optional<int64_t> bwe_period_ms,absl::optional<int64_t> stable_target_bitrate_bps)495 void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth(
496 int target_audio_bitrate_bps,
497 absl::optional<int64_t> bwe_period_ms,
498 absl::optional<int64_t> stable_target_bitrate_bps) {
499 if (audio_network_adaptor_) {
500 audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps);
501 if (use_stable_target_for_adaptation_) {
502 if (stable_target_bitrate_bps)
503 audio_network_adaptor_->SetUplinkBandwidth(*stable_target_bitrate_bps);
504 } else {
505 // We give smoothed bitrate allocation to audio network adaptor as
506 // the uplink bandwidth.
507 // The BWE spikes should not affect the bitrate smoother more than 25%.
508 // To simplify the calculations we use a step response as input signal.
509 // The step response of an exponential filter is
510 // u(t) = 1 - e^(-t / time_constant).
511 // In order to limit the affect of a BWE spike within 25% of its value
512 // before
513 // the next BWE update, we would choose a time constant that fulfills
514 // 1 - e^(-bwe_period_ms / time_constant) < 0.25
515 // Then 4 * bwe_period_ms is a good choice.
516 if (bwe_period_ms)
517 bitrate_smoother_->SetTimeConstantMs(*bwe_period_ms * 4);
518 bitrate_smoother_->AddSample(target_audio_bitrate_bps);
519 }
520
521 ApplyAudioNetworkAdaptor();
522 } else {
523 if (!overhead_bytes_per_packet_) {
524 RTC_LOG(LS_INFO)
525 << "AudioEncoderOpusImpl: Overhead unknown, target audio bitrate "
526 << target_audio_bitrate_bps << " bps is ignored.";
527 return;
528 }
529 const int overhead_bps = static_cast<int>(
530 *overhead_bytes_per_packet_ * 8 * 100 / Num10MsFramesInNextPacket());
531 SetTargetBitrate(
532 std::min(AudioEncoderOpusConfig::kMaxBitrateBps,
533 std::max(AudioEncoderOpusConfig::kMinBitrateBps,
534 target_audio_bitrate_bps - overhead_bps)));
535 }
536 }
OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,absl::optional<int64_t> bwe_period_ms)537 void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth(
538 int target_audio_bitrate_bps,
539 absl::optional<int64_t> bwe_period_ms) {
540 OnReceivedUplinkBandwidth(target_audio_bitrate_bps, bwe_period_ms,
541 absl::nullopt);
542 }
543
OnReceivedUplinkAllocation(BitrateAllocationUpdate update)544 void AudioEncoderOpusImpl::OnReceivedUplinkAllocation(
545 BitrateAllocationUpdate update) {
546 OnReceivedUplinkBandwidth(update.target_bitrate.bps(), update.bwe_period.ms(),
547 update.stable_target_bitrate.bps());
548 }
549
OnReceivedRtt(int rtt_ms)550 void AudioEncoderOpusImpl::OnReceivedRtt(int rtt_ms) {
551 if (!audio_network_adaptor_)
552 return;
553 audio_network_adaptor_->SetRtt(rtt_ms);
554 ApplyAudioNetworkAdaptor();
555 }
556
OnReceivedOverhead(size_t overhead_bytes_per_packet)557 void AudioEncoderOpusImpl::OnReceivedOverhead(
558 size_t overhead_bytes_per_packet) {
559 if (audio_network_adaptor_) {
560 audio_network_adaptor_->SetOverhead(overhead_bytes_per_packet);
561 ApplyAudioNetworkAdaptor();
562 } else {
563 overhead_bytes_per_packet_ = overhead_bytes_per_packet;
564 }
565 }
566
SetReceiverFrameLengthRange(int min_frame_length_ms,int max_frame_length_ms)567 void AudioEncoderOpusImpl::SetReceiverFrameLengthRange(
568 int min_frame_length_ms,
569 int max_frame_length_ms) {
570 // Ensure that `SetReceiverFrameLengthRange` is called before
571 // `EnableAudioNetworkAdaptor`, otherwise we need to recreate
572 // `audio_network_adaptor_`, which is not a needed use case.
573 RTC_DCHECK(!audio_network_adaptor_);
574 FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms,
575 &config_.supported_frame_lengths_ms);
576 }
577
EncodeImpl(uint32_t rtp_timestamp,rtc::ArrayView<const int16_t> audio,rtc::Buffer * encoded)578 AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl(
579 uint32_t rtp_timestamp,
580 rtc::ArrayView<const int16_t> audio,
581 rtc::Buffer* encoded) {
582 MaybeUpdateUplinkBandwidth();
583
584 if (input_buffer_.empty())
585 first_timestamp_in_buffer_ = rtp_timestamp;
586
587 input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend());
588 if (input_buffer_.size() <
589 (Num10msFramesPerPacket() * SamplesPer10msFrame())) {
590 return EncodedInfo();
591 }
592 RTC_CHECK_EQ(input_buffer_.size(),
593 Num10msFramesPerPacket() * SamplesPer10msFrame());
594
595 const size_t max_encoded_bytes = SufficientOutputBufferSize();
596 EncodedInfo info;
597 info.encoded_bytes = encoded->AppendData(
598 max_encoded_bytes, [&](rtc::ArrayView<uint8_t> encoded) {
599 int status = WebRtcOpus_Encode(
600 inst_, &input_buffer_[0],
601 rtc::CheckedDivExact(input_buffer_.size(), config_.num_channels),
602 rtc::saturated_cast<int16_t>(max_encoded_bytes), encoded.data());
603
604 RTC_CHECK_GE(status, 0); // Fails only if fed invalid data.
605
606 return static_cast<size_t>(status);
607 });
608 input_buffer_.clear();
609
610 bool dtx_frame = (info.encoded_bytes <= 2);
611
612 // Will use new packet size for next encoding.
613 config_.frame_size_ms = next_frame_length_ms_;
614
615 if (adjust_bandwidth_ && bitrate_changed_) {
616 const auto bandwidth = GetNewBandwidth(config_, inst_);
617 if (bandwidth) {
618 RTC_CHECK_EQ(0, WebRtcOpus_SetBandwidth(inst_, *bandwidth));
619 }
620 bitrate_changed_ = false;
621 }
622
623 info.encoded_timestamp = first_timestamp_in_buffer_;
624 info.payload_type = payload_type_;
625 info.send_even_if_empty = true; // Allows Opus to send empty packets.
626 // After 20 DTX frames (MAX_CONSECUTIVE_DTX) Opus will send a frame
627 // coding the background noise. Avoid flagging this frame as speech
628 // (even though there is a probability of the frame being speech).
629 info.speech = !dtx_frame && (consecutive_dtx_frames_ != 20);
630 info.encoder_type = CodecType::kOpus;
631
632 // Increase or reset DTX counter.
633 consecutive_dtx_frames_ = (dtx_frame) ? (consecutive_dtx_frames_ + 1) : (0);
634
635 return info;
636 }
637
Num10msFramesPerPacket() const638 size_t AudioEncoderOpusImpl::Num10msFramesPerPacket() const {
639 return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10));
640 }
641
SamplesPer10msFrame() const642 size_t AudioEncoderOpusImpl::SamplesPer10msFrame() const {
643 return rtc::CheckedDivExact(config_.sample_rate_hz, 100) *
644 config_.num_channels;
645 }
646
SufficientOutputBufferSize() const647 size_t AudioEncoderOpusImpl::SufficientOutputBufferSize() const {
648 // Calculate the number of bytes we expect the encoder to produce,
649 // then multiply by two to give a wide margin for error.
650 const size_t bytes_per_millisecond =
651 static_cast<size_t>(GetBitrateBps(config_) / (1000 * 8) + 1);
652 const size_t approx_encoded_bytes =
653 Num10msFramesPerPacket() * 10 * bytes_per_millisecond;
654 return 2 * approx_encoded_bytes;
655 }
656
657 // If the given config is OK, recreate the Opus encoder instance with those
658 // settings, save the config, and return true. Otherwise, do nothing and return
659 // false.
RecreateEncoderInstance(const AudioEncoderOpusConfig & config)660 bool AudioEncoderOpusImpl::RecreateEncoderInstance(
661 const AudioEncoderOpusConfig& config) {
662 if (!config.IsOk())
663 return false;
664 config_ = config;
665 if (inst_)
666 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
667 input_buffer_.clear();
668 input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame());
669 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(
670 &inst_, config.num_channels,
671 config.application ==
672 AudioEncoderOpusConfig::ApplicationMode::kVoip
673 ? 0
674 : 1,
675 config.sample_rate_hz));
676 const int bitrate = GetBitrateBps(config);
677 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, bitrate));
678 RTC_LOG(LS_VERBOSE) << "Set Opus bitrate to " << bitrate << " bps.";
679 if (config.fec_enabled) {
680 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_));
681 } else {
682 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_));
683 }
684 RTC_CHECK_EQ(
685 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz));
686 // Use the default complexity if the start bitrate is within the hysteresis
687 // window.
688 complexity_ = GetNewComplexity(config).value_or(config.complexity);
689 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_));
690 bitrate_changed_ = true;
691 if (config.dtx_enabled) {
692 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_));
693 } else {
694 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_));
695 }
696 RTC_CHECK_EQ(0,
697 WebRtcOpus_SetPacketLossRate(
698 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
699 if (config.cbr_enabled) {
700 RTC_CHECK_EQ(0, WebRtcOpus_EnableCbr(inst_));
701 } else {
702 RTC_CHECK_EQ(0, WebRtcOpus_DisableCbr(inst_));
703 }
704 num_channels_to_encode_ = NumChannels();
705 next_frame_length_ms_ = config_.frame_size_ms;
706 return true;
707 }
708
SetFrameLength(int frame_length_ms)709 void AudioEncoderOpusImpl::SetFrameLength(int frame_length_ms) {
710 if (next_frame_length_ms_ != frame_length_ms) {
711 RTC_LOG(LS_VERBOSE) << "Update Opus frame length "
712 << "from " << next_frame_length_ms_ << " ms "
713 << "to " << frame_length_ms << " ms.";
714 }
715 next_frame_length_ms_ = frame_length_ms;
716 }
717
SetNumChannelsToEncode(size_t num_channels_to_encode)718 void AudioEncoderOpusImpl::SetNumChannelsToEncode(
719 size_t num_channels_to_encode) {
720 RTC_DCHECK_GT(num_channels_to_encode, 0);
721 RTC_DCHECK_LE(num_channels_to_encode, config_.num_channels);
722
723 if (num_channels_to_encode_ == num_channels_to_encode)
724 return;
725
726 RTC_CHECK_EQ(0, WebRtcOpus_SetForceChannels(inst_, num_channels_to_encode));
727 num_channels_to_encode_ = num_channels_to_encode;
728 }
729
SetProjectedPacketLossRate(float fraction)730 void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) {
731 fraction = std::min(std::max(fraction, 0.0f), kMaxPacketLossFraction);
732 if (packet_loss_rate_ != fraction) {
733 packet_loss_rate_ = fraction;
734 RTC_CHECK_EQ(
735 0, WebRtcOpus_SetPacketLossRate(
736 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
737 }
738 }
739
SetTargetBitrate(int bits_per_second)740 void AudioEncoderOpusImpl::SetTargetBitrate(int bits_per_second) {
741 const int new_bitrate = rtc::SafeClamp<int>(
742 bits_per_second, AudioEncoderOpusConfig::kMinBitrateBps,
743 AudioEncoderOpusConfig::kMaxBitrateBps);
744 if (config_.bitrate_bps && *config_.bitrate_bps != new_bitrate) {
745 config_.bitrate_bps = new_bitrate;
746 RTC_DCHECK(config_.IsOk());
747 const int bitrate = GetBitrateBps(config_);
748 RTC_CHECK_EQ(
749 0, WebRtcOpus_SetBitRate(
750 inst_, GetMultipliedBitrate(bitrate, bitrate_multipliers_)));
751 RTC_LOG(LS_VERBOSE) << "Set Opus bitrate to " << bitrate << " bps.";
752 bitrate_changed_ = true;
753 }
754
755 const auto new_complexity = GetNewComplexity(config_);
756 if (new_complexity && complexity_ != *new_complexity) {
757 complexity_ = *new_complexity;
758 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_));
759 }
760 }
761
ApplyAudioNetworkAdaptor()762 void AudioEncoderOpusImpl::ApplyAudioNetworkAdaptor() {
763 auto config = audio_network_adaptor_->GetEncoderRuntimeConfig();
764
765 if (config.bitrate_bps)
766 SetTargetBitrate(*config.bitrate_bps);
767 if (config.frame_length_ms)
768 SetFrameLength(*config.frame_length_ms);
769 if (config.enable_dtx)
770 SetDtx(*config.enable_dtx);
771 if (config.num_channels)
772 SetNumChannelsToEncode(*config.num_channels);
773 }
774
775 std::unique_ptr<AudioNetworkAdaptor>
DefaultAudioNetworkAdaptorCreator(absl::string_view config_string,RtcEventLog * event_log) const776 AudioEncoderOpusImpl::DefaultAudioNetworkAdaptorCreator(
777 absl::string_view config_string,
778 RtcEventLog* event_log) const {
779 AudioNetworkAdaptorImpl::Config config;
780 config.event_log = event_log;
781 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl(
782 config, ControllerManagerImpl::Create(
783 config_string, NumChannels(), supported_frame_lengths_ms(),
784 AudioEncoderOpusConfig::kMinBitrateBps,
785 num_channels_to_encode_, next_frame_length_ms_,
786 GetTargetBitrate(), config_.fec_enabled, GetDtx())));
787 }
788
MaybeUpdateUplinkBandwidth()789 void AudioEncoderOpusImpl::MaybeUpdateUplinkBandwidth() {
790 if (audio_network_adaptor_ && !use_stable_target_for_adaptation_) {
791 int64_t now_ms = rtc::TimeMillis();
792 if (!bitrate_smoother_last_update_time_ ||
793 now_ms - *bitrate_smoother_last_update_time_ >=
794 config_.uplink_bandwidth_update_interval_ms) {
795 absl::optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage();
796 if (smoothed_bitrate)
797 audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate);
798 bitrate_smoother_last_update_time_ = now_ms;
799 }
800 }
801 }
802
GetANAStats() const803 ANAStats AudioEncoderOpusImpl::GetANAStats() const {
804 if (audio_network_adaptor_) {
805 return audio_network_adaptor_->GetStats();
806 }
807 return ANAStats();
808 }
809
810 absl::optional<std::pair<TimeDelta, TimeDelta> >
GetFrameLengthRange() const811 AudioEncoderOpusImpl::GetFrameLengthRange() const {
812 if (audio_network_adaptor_) {
813 if (config_.supported_frame_lengths_ms.empty()) {
814 return absl::nullopt;
815 }
816 return {{TimeDelta::Millis(config_.supported_frame_lengths_ms.front()),
817 TimeDelta::Millis(config_.supported_frame_lengths_ms.back())}};
818 } else {
819 return {{TimeDelta::Millis(config_.frame_size_ms),
820 TimeDelta::Millis(config_.frame_size_ms)}};
821 }
822 }
823
824 } // namespace webrtc
825