tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_encoder_opus.cc (29882B)


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