• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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