/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "modules/video_coding/codecs/av1/libaom_av1_encoder.h"

#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
#include "api/environment/environment.h"
#include "api/field_trials_view.h"
#include "api/scoped_refptr.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_image.h"
#include "api/video/render_resolution.h"
#include "api/video/video_codec_constants.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_content_type.h"
#include "api/video/video_frame.h"
#include "api/video/video_frame_buffer.h"
#include "api/video/video_frame_type.h"
#include "api/video/video_timing.h"
#include "api/video_codecs/encoder_speed_controller.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "common_video/generic_frame_descriptor/generic_frame_info.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/video_coding/codecs/av1/libaom_speed_config_factory.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "modules/video_coding/utility/frame_sampler.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/encoder_info_settings.h"
#include "rtc_base/experiments/encoder_speed_experiment.h"
#include "rtc_base/experiments/psnr_experiment.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/clock.h"
#include "third_party/libaom/source/libaom/aom/aom_codec.h"
#include "third_party/libaom/source/libaom/aom/aom_encoder.h"
#include "third_party/libaom/source/libaom/aom/aom_image.h"
#include "third_party/libaom/source/libaom/aom/aomcx.h"

#if (defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64)) && \
    (defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS))
#define MOBILE_ARM
#endif

#ifndef AOM_EFLAG_CALCULATE_PSNR
#define AOM_EFLAG_CALCULATE_PSNR (1 << 3)
#endif

#if defined(WEBRTC_ENCODER_PSNR_STATS)
constexpr bool kEnablePsnrStats = true;
#else
constexpr bool kEnablePsnrStats = false;
#endif

#define SET_ENCODER_PARAM_OR_RETURN_ERROR(param_id, param_value) \
  do {                                                           \
    if (!SetEncoderControlParameters(param_id, param_value)) {   \
      return WEBRTC_VIDEO_CODEC_ERROR;                           \
    }                                                            \
  } while (0)

namespace webrtc {
namespace {

// Encoder configuration parameters
constexpr int kMinQp = 10;
constexpr int kMinQindex = 40;  // Min qindex corresponding to kMinQp.
constexpr int kUsageProfile = AOM_USAGE_REALTIME;
constexpr int kLowQindex = 145;   // Low qindex threshold for QP scaling.
constexpr int kHighQindex = 205;  // High qindex threshold for QP scaling.
constexpr int kBitDepth = 8;
constexpr int kLagInFrames = 0;  // No look ahead.
constexpr double kMinFrameRateFps = 1.0;

aom_superblock_size_t GetSuperblockSize(int width, int height, int threads) {
  int resolution = width * height;
  if (threads >= 4 && resolution >= 960 * 540 && resolution < 1920 * 1080)
    return AOM_SUPERBLOCK_SIZE_64X64;
  else
    return AOM_SUPERBLOCK_SIZE_DYNAMIC;
}

void PopulateEncodedImageFromVideoFrame(const VideoFrame& frame,
                                        EncodedImage& encoded_image) {
  encoded_image.SetRtpTimestamp(frame.rtp_timestamp());
  encoded_image.SetPresentationTimestamp(frame.presentation_timestamp());
  encoded_image.capture_time_ms_ = frame.render_time_ms();
  encoded_image.rotation_ = frame.rotation();
  encoded_image.SetColorSpace(frame.color_space());
}

struct EncodeResult {
  aom_codec_err_t status_code = AOM_CODEC_OK;
  std::optional<EncodedImage> encoded_image;
  TimeDelta encode_time = TimeDelta::Zero();
};

EncoderSpeedController::EncodeResults ToSpeedControllerEncodeResult(
    const EncodeResult& encode_result,
    const EncoderSpeedController::FrameEncodingInfo& frame_info,
    int speed) {
  RTC_DCHECK(encode_result.encoded_image.has_value());
  const EncodedImage& image = *encode_result.encoded_image;
  return EncoderSpeedController::EncodeResults{
      .speed = speed,
      .encode_time = encode_result.encode_time,
      .qp = image.qp_ / 4,  // Use [0, 63] range instead of [0, 255].
      .psnr = image.psnr().has_value() ? std::optional<double>(image.psnr()->y)
                                       : std::nullopt,
      .frame_info = frame_info};
}

class LibaomAv1Encoder final : public VideoEncoder {
 public:
  LibaomAv1Encoder(const Environment& env, LibaomAv1EncoderSettings settings);
  ~LibaomAv1Encoder() override;

  int InitEncode(const VideoCodec* codec_settings,
                 const Settings& settings) override;

  int32_t RegisterEncodeCompleteCallback(
      EncodedImageCallback* encoded_image_callback) override;

  int32_t Release() override;

  int32_t Encode(const VideoFrame& frame,
                 const std::vector<VideoFrameType>* frame_types) override;

  void SetRates(const RateControlParameters& parameters) override;

  EncoderInfo GetEncoderInfo() const override;

 private:
  template <typename P>
  bool SetEncoderControlParameters(int param_id, P param_value);

  // Get value to be used for encoder cpu_speed setting
  int GetCpuSpeed(int width, int height);

  // Determine number of encoder threads to use.
  int NumberOfThreads(int width, int height, int number_of_cores);

  bool SvcEnabled() const { return svc_params_.has_value(); }
  // Fills svc_params_ memeber value. Returns false on error.
  bool SetSvcParams(ScalableVideoController::StreamLayersConfig svc_config,
                    const aom_codec_enc_cfg_t& encoder_config);
  // Configures the encoder with layer for the next frame.
  void SetSvcLayerId(
      const ScalableVideoController::LayerFrameConfig& layer_frame);
  // Configures the encoder which buffers next frame updates and can
  // reference.
  void SetSvcRefFrameConfig(
      const ScalableVideoController::LayerFrameConfig& layer_frame);
  // If pixel format doesn't match, then reallocate.
  void MaybeRewrapImgWithFormat(const aom_img_fmt_t fmt,
                                unsigned int width,
                                unsigned int height);

  // Adjust sclaing factors assuming that the top active SVC layer
  // will be the input resolution.
  void AdjustScalingFactorsForTopActiveLayer();

  EncoderSpeedController::ReferenceClass AsSpeedControllerFrameType(
      const ScalableVideoController::LayerFrameConfig& layer_frame) const;

  // Returns frame interval, compensated for relative pixel count allocation.
  TimeDelta GetFrameInterval(int spatial_index) const;

  // Duration is specified in ticks based on aom_codec_enc_cfg_t::g_timebase,
  // in practice that that is kVideoPayloadTypeFrequency (90kHz).
  EncodeResult DoEncode(uint32_t duration,
                        aom_enc_frame_flags_t flags,
                        ScalableVideoController::LayerFrameConfig* layer_frame);

  CodecSpecificInfo CreateCodecSpecificInfo(
      const EncodedImage& image,
      const ScalableVideoController::LayerFrameConfig& layer_frame);

  std::unique_ptr<ScalableVideoController> svc_controller_;
  std::optional<ScalabilityMode> scalability_mode_;
  // Original scaling factors for all configured layers active and inactive.
  // `svc_params_` stores factors ignoring top inactive layers.
  std::vector<int> scaling_factors_num_;
  std::vector<int> scaling_factors_den_;
  int last_active_layer_ = 0;

  bool inited_;
  bool rates_configured_;
  std::optional<aom_svc_params_t> svc_params_;
  VideoCodec encoder_settings_;
  LibaomAv1EncoderSettings settings_;
  aom_image_t* frame_for_encode_;
  aom_codec_ctx_t ctx_;
  aom_codec_enc_cfg_t cfg_;
  EncodedImageCallback* encoded_image_callback_;
  double framerate_fps_;  // Current target frame rate.
  int64_t timestamp_;
  const Environment& env_;
  const LibaomAv1EncoderInfoSettings encoder_info_override_;
  // TODO(webrtc:351644568): Remove this kill-switch after the feature is fully
  // deployed.
  const bool post_encode_frame_drop_;

  // Determine whether the frame should be sampled for PSNR.
  // TODO(webrtc:388070060): Remove after rollout.
  const PsnrExperiment psnr_experiment_;
  FrameSampler psnr_frame_sampler_;
  const bool drop_repeat_frames_on_enhancement_layers_;
  std::map<int, uint32_t> last_encoded_timestamp_by_sid_;

  const EncoderSpeedExperiment encoder_speed_experiment_;
  // One speed controller per spatial layer.
  std::vector<std::unique_ptr<webrtc::EncoderSpeedController>>
      speed_controllers_;
  // Don't use when setting input frame timestamps!
  Clock* const realtime_clock_;
};

int32_t VerifyCodecSettings(const VideoCodec& codec_settings) {
  if (codec_settings.width < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codec_settings.height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  // maxBitrate == 0 represents an unspecified maxBitRate.
  if (codec_settings.maxBitrate > 0 &&
      codec_settings.minBitrate > codec_settings.maxBitrate) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codec_settings.maxBitrate > 0 &&
      codec_settings.startBitrate > codec_settings.maxBitrate) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codec_settings.startBitrate < codec_settings.minBitrate) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codec_settings.maxFramerate < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codec_settings.qpMax < kMinQp || codec_settings.qpMax > 63) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

LibaomAv1Encoder::LibaomAv1Encoder(const Environment& env,
                                   LibaomAv1EncoderSettings settings)
    : inited_(false),
      rates_configured_(false),
      settings_(std::move(settings)),
      frame_for_encode_(nullptr),
      encoded_image_callback_(nullptr),
      framerate_fps_(0),
      timestamp_(0),
      env_(env),
      encoder_info_override_(env_.field_trials()),
      post_encode_frame_drop_(!env_.field_trials().IsDisabled(
          "WebRTC-LibaomAv1Encoder-PostEncodeFrameDrop")),
      psnr_experiment_(env.field_trials()),
      psnr_frame_sampler_(psnr_experiment_.SamplingInterval()),
      drop_repeat_frames_on_enhancement_layers_(env.field_trials().IsEnabled(
          "WebRTC-LibaomAv1Encoder-DropRepeatFramesOnEnhancementLayers")),
      encoder_speed_experiment_(env.field_trials()),
      realtime_clock_(Clock::GetRealTimeClock()) {}

LibaomAv1Encoder::~LibaomAv1Encoder() {
  Release();
}

int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings,
                                 const Settings& settings) {
  if (codec_settings == nullptr) {
    RTC_LOG(LS_WARNING) << "No codec settings provided to "
                           "LibaomAv1Encoder.";
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (settings.number_of_cores < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (inited_) {
    RTC_LOG(LS_WARNING) << "Initing LibaomAv1Encoder without first releasing.";
    Release();
  }
  encoder_settings_ = *codec_settings;

  // Sanity checks for encoder configuration.
  const int32_t result = VerifyCodecSettings(encoder_settings_);
  if (result < 0) {
    RTC_LOG(LS_WARNING) << "Incorrect codec settings provided to "
                           "LibaomAv1Encoder.";
    return result;
  }
  if (encoder_settings_.numberOfSimulcastStreams > 1) {
    RTC_LOG(LS_WARNING) << "Simulcast is not implemented by LibaomAv1Encoder.";
    return result;
  }
  scalability_mode_ = encoder_settings_.GetScalabilityMode();
  if (!scalability_mode_.has_value()) {
    RTC_LOG(LS_WARNING) << "Scalability mode is not set, using 'L1T1'.";
    scalability_mode_ = ScalabilityMode::kL1T1;
  }
  svc_controller_ = CreateScalabilityStructure(*scalability_mode_);
  if (svc_controller_ == nullptr) {
    RTC_LOG(LS_WARNING) << "Failed to set scalability mode "
                        << static_cast<int>(*scalability_mode_);
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }

  // Initialize encoder configuration structure with default values
  aom_codec_err_t ret =
      aom_codec_enc_config_default(aom_codec_av1_cx(), &cfg_, kUsageProfile);
  if (ret != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret
                        << " on aom_codec_enc_config_default.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  // Overwrite default config with input encoder settings & RTC-relevant values.
  cfg_.g_w = encoder_settings_.width;
  cfg_.g_h = encoder_settings_.height;
  cfg_.g_threads =
      NumberOfThreads(cfg_.g_w, cfg_.g_h, settings.number_of_cores);
  cfg_.g_timebase.num = 1;
  cfg_.g_timebase.den = kVideoPayloadTypeFrequency;
  cfg_.rc_target_bitrate = encoder_settings_.startBitrate;  // kilobits/sec.
  cfg_.rc_dropframe_thresh = encoder_settings_.GetFrameDropEnabled() ? 30 : 0;
  cfg_.g_input_bit_depth = kBitDepth;
  cfg_.kf_mode = AOM_KF_DISABLED;
  cfg_.rc_min_quantizer = kMinQp;
  cfg_.rc_max_quantizer = encoder_settings_.qpMax;
  cfg_.rc_undershoot_pct = 50;
  cfg_.rc_overshoot_pct = 50;
  cfg_.rc_buf_initial_sz = 600;
  cfg_.rc_buf_optimal_sz = 600;
  cfg_.rc_buf_sz = 1000;
  cfg_.g_usage = kUsageProfile;
  cfg_.g_error_resilient = 0;
  // Low-latency settings.
  cfg_.rc_end_usage = AOM_CBR;          // Constant Bit Rate (CBR) mode
  cfg_.g_pass = AOM_RC_ONE_PASS;        // One-pass rate control
  cfg_.g_lag_in_frames = kLagInFrames;  // No look ahead when lag equals 0.

  if (frame_for_encode_ != nullptr) {
    aom_img_free(frame_for_encode_);
    frame_for_encode_ = nullptr;
  }

  // Flag options: AOM_EFLAG_CALCULATE_PSNR and AOM_CODEC_USE_HIGHBITDEPTH
  aom_codec_flags_t flags = 0;

  // Initialize an encoder instance.
  ret = aom_codec_enc_init(&ctx_, aom_codec_av1_cx(), &cfg_, flags);
  if (ret != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::EncodeInit returned " << ret
                        << " on aom_codec_enc_init.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  if (!SetSvcParams(svc_controller_->StreamConfig(), cfg_)) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  inited_ = true;

  // Set control parameters
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AOME_SET_CPUUSED,
                                    GetCpuSpeed(cfg_.g_w, cfg_.g_h));
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_CDEF, 1);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_TPL_MODEL, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_DELTAQ_MODE, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_ORDER_HINT, 0);
  // AQ_MODE = 3 enables cyclic refresh.
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_AQ_MODE, 3);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AOME_SET_MAX_INTRA_BITRATE_PCT, 300);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_COEFF_COST_UPD_FREQ, 3);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_MODE_COST_UPD_FREQ, 3);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_MV_COST_UPD_FREQ, 3);

  if (codec_settings->mode == VideoCodecMode::kScreensharing) {
    SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_TUNE_CONTENT,
                                      AOM_CONTENT_SCREEN);
    SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_PALETTE, 1);
  } else {
    SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_PALETTE, 0);
  }

  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_AUTO_TILES, 1);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ROW_MT, 1);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_OBMC, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_NOISE_SENSITIVITY, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_WARPED_MOTION, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_GLOBAL_MOTION, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_REF_FRAME_MVS, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(
      AV1E_SET_SUPERBLOCK_SIZE,
      GetSuperblockSize(cfg_.g_w, cfg_.g_h, cfg_.g_threads));
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_CFL_INTRA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_SMOOTH_INTRA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_ANGLE_DELTA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_FILTER_INTRA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_DISABLE_TRELLIS_QUANT, 1);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_DIST_WTD_COMP, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_DIFF_WTD_COMP, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_DUAL_FILTER, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_INTERINTRA_COMP, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_INTRABC, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_MASKED_COMP, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_PAETH_INTRA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_QM, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_RECT_PARTITIONS, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_RESTORATION, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_TX64, 0);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_MAX_REFERENCE_FRAMES, 3);
  SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_MAX_CONSEC_FRAME_DROP_MS_CBR, 250);

  if (post_encode_frame_drop_) {
    SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_POSTENCODE_DROP_RTC, 1);
  }

  if (encoder_speed_experiment_.IsDynamicSpeedEnabled()) {
    LibaomSpeedConfigFactory speed_config_factory(
        codec_settings->GetVideoEncoderComplexity(), codec_settings->mode);
    RTC_DCHECK(speed_controllers_.empty());

    if (SvcEnabled()) {
      for (int si = 0; si < svc_params_->number_spatial_layers; ++si) {
        EncoderSpeedController::Config speed_config =
            speed_config_factory.GetSpeedConfig(
                encoder_settings_.spatialLayers[si].width,
                encoder_settings_.spatialLayers[si].height,
                svc_controller_->StreamConfig().num_temporal_layers,
                env_.field_trials());

        speed_controllers_.push_back(
            EncoderSpeedController::Create(speed_config, GetFrameInterval(si)));
      }
    } else {
      EncoderSpeedController::Config speed_config =
          speed_config_factory.GetSpeedConfig(
              encoder_settings_.width, encoder_settings_.height,
              /*num_temporal_layers=*/1, env_.field_trials());
      speed_controllers_.push_back(EncoderSpeedController::Create(
          speed_config, GetFrameInterval(/*spatial_index=*/0)));
    }
  }

  return WEBRTC_VIDEO_CODEC_OK;
}

template <typename P>
bool LibaomAv1Encoder::SetEncoderControlParameters(int param_id,
                                                   P param_value) {
  aom_codec_err_t error_code = aom_codec_control(&ctx_, param_id, param_value);
  if (error_code != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING)
        << "LibaomAv1Encoder::SetEncoderControlParameters returned "
        << error_code << " on id:  " << param_id << ".";
  }
  return error_code == AOM_CODEC_OK;
}

// Only positive speeds, range for real-time coding currently is: 6 - 10.
// Speed 11 is used for screen sharing.
// Lower means slower/better quality, higher means fastest/lower quality.
// Note: not used if dynamic speed controller is enabled.
int LibaomAv1Encoder::GetCpuSpeed(int width, int height) {
  if (!settings_.max_pixel_count_to_cpu_speed.empty()) {
    if (auto it =
            settings_.max_pixel_count_to_cpu_speed.lower_bound(width * height);
        it != settings_.max_pixel_count_to_cpu_speed.end()) {
      return it->second;
    }

    return 10;
  } else {
    if (encoder_settings_.mode == VideoCodecMode::kScreensharing) {
      return 11;
    }
    // For smaller resolutions, use lower speed setting (get some coding gain at
    // the cost of increased encoding complexity).
    switch (encoder_settings_.GetVideoEncoderComplexity()) {
      case VideoCodecComplexity::kComplexityHigh:
        if (width * height <= 320 * 180)
          return 8;
        else if (width * height <= 640 * 360)
          return 9;
        else
          return 10;
      case VideoCodecComplexity::kComplexityHigher:
        if (width * height <= 320 * 180)
          return 7;
        else if (width * height <= 640 * 360)
          return 8;
        else if (width * height <= 1280 * 720)
          return 9;
        else
          return 10;
      case VideoCodecComplexity::kComplexityMax:
        if (width * height <= 320 * 180)
          return 6;
        else if (width * height <= 640 * 360)
          return 7;
        else if (width * height <= 1280 * 720)
          return 8;
        else
          return 9;
      default:
        return 10;
    }
  }
}

int LibaomAv1Encoder::NumberOfThreads(int width,
                                      int height,
                                      int number_of_cores) {
  // Keep the number of encoder threads equal to the possible number of
  // column/row tiles, which is (1, 2, 4, 8). See comments below for
  // AV1E_SET_TILE_COLUMNS/ROWS.
  if (width * height > 1280 * 720 && number_of_cores > 8) {
    return 8;
  } else if (width * height >= 640 * 360 && number_of_cores > 4) {
    return 4;
  } else if (width * height >= 320 * 180 && number_of_cores > 2) {
    return 2;
  } else {
// Use 2 threads for low res on ARM.
#ifdef MOBILE_ARM
    if (width * height >= 320 * 180 && number_of_cores > 2) {
      return 2;
    }
#endif
    // 1 thread less than VGA.
    return 1;
  }
}

bool LibaomAv1Encoder::SetSvcParams(
    ScalableVideoController::StreamLayersConfig svc_config,
    const aom_codec_enc_cfg_t& encoder_config) {
  bool svc_enabled =
      svc_config.num_spatial_layers > 1 || svc_config.num_temporal_layers > 1;
  if (!svc_enabled) {
    svc_params_ = std::nullopt;
    return true;
  }
  if (svc_config.num_spatial_layers < 1 || svc_config.num_spatial_layers > 4) {
    RTC_LOG(LS_WARNING) << "Av1 supports up to 4 spatial layers. "
                        << svc_config.num_spatial_layers << " configured.";
    return false;
  }
  if (svc_config.num_temporal_layers < 1 ||
      svc_config.num_temporal_layers > 8) {
    RTC_LOG(LS_WARNING) << "Av1 supports up to 8 temporal layers. "
                        << svc_config.num_temporal_layers << " configured.";
    return false;
  }
  aom_svc_params_t& svc_params = svc_params_.emplace();
  svc_params.number_spatial_layers = svc_config.num_spatial_layers;
  svc_params.number_temporal_layers = svc_config.num_temporal_layers;

  int num_layers =
      svc_config.num_spatial_layers * svc_config.num_temporal_layers;
  for (int i = 0; i < num_layers; ++i) {
    svc_params.min_quantizers[i] = encoder_config.rc_min_quantizer;
    svc_params.max_quantizers[i] = encoder_config.rc_max_quantizer;
  }

  // Assume each temporal layer doubles framerate.
  for (int tid = 0; tid < svc_config.num_temporal_layers; ++tid) {
    svc_params.framerate_factor[tid] =
        1 << (svc_config.num_temporal_layers - tid - 1);
  }

  scaling_factors_den_.resize(svc_config.num_spatial_layers);
  scaling_factors_num_.resize(svc_config.num_spatial_layers);
  for (int sid = 0; sid < svc_config.num_spatial_layers; ++sid) {
    scaling_factors_num_[sid] = svc_config.scaling_factor_num[sid];
    svc_params.scaling_factor_num[sid] = svc_config.scaling_factor_num[sid];
    scaling_factors_den_[sid] = svc_config.scaling_factor_den[sid];
    svc_params.scaling_factor_den[sid] = svc_config.scaling_factor_den[sid];
    encoder_settings_.spatialLayers[sid].width = encoder_settings_.width *
                                                 scaling_factors_num_[sid] /
                                                 scaling_factors_den_[sid];
    encoder_settings_.spatialLayers[sid].height = encoder_settings_.height *
                                                  scaling_factors_num_[sid] /
                                                  scaling_factors_den_[sid];
  }

  // svc_params.layer_target_bitrate is set in SetRates() before svc_params is
  // passed to SetEncoderControlParameters(AV1E_SET_SVC_PARAMS).

  return true;
}

void LibaomAv1Encoder::SetSvcLayerId(
    const ScalableVideoController::LayerFrameConfig& layer_frame) {
  aom_svc_layer_id_t layer_id = {};
  layer_id.spatial_layer_id = layer_frame.SpatialId();
  layer_id.temporal_layer_id = layer_frame.TemporalId();
  SetEncoderControlParameters(AV1E_SET_SVC_LAYER_ID, &layer_id);
}

void LibaomAv1Encoder::SetSvcRefFrameConfig(
    const ScalableVideoController::LayerFrameConfig& layer_frame) {
  // Buffer name to use for each layer_frame.buffers position. In particular
  // when there are 2 buffers are referenced, prefer name them last and golden,
  // because av1 bitstream format has dedicated fields for these two names.
  // See last_frame_idx and golden_frame_idx in the av1 spec
  // https://aomediacodec.github.io/av1-spec/av1-spec.pdf
  static constexpr int kPreferedSlotName[] = {0,  // Last
                                              3,  // Golden
                                              1, 2, 4, 5, 6};
  static constexpr int kAv1NumBuffers = 8;

  aom_svc_ref_frame_config_t ref_frame_config = {};
  RTC_CHECK_LE(layer_frame.Buffers().size(), std::size(kPreferedSlotName));
  for (size_t i = 0; i < layer_frame.Buffers().size(); ++i) {
    const CodecBufferUsage& buffer = layer_frame.Buffers()[i];
    int slot_name = kPreferedSlotName[i];
    RTC_CHECK_GE(buffer.id, 0);
    RTC_CHECK_LT(buffer.id, kAv1NumBuffers);
    ref_frame_config.ref_idx[slot_name] = buffer.id;
    if (buffer.referenced) {
      ref_frame_config.reference[slot_name] = 1;
    }
    if (buffer.updated) {
      ref_frame_config.refresh[buffer.id] = 1;
    }
  }

  SetEncoderControlParameters(AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config);
}

int32_t LibaomAv1Encoder::RegisterEncodeCompleteCallback(
    EncodedImageCallback* encoded_image_callback) {
  encoded_image_callback_ = encoded_image_callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t LibaomAv1Encoder::Release() {
  if (frame_for_encode_ != nullptr) {
    aom_img_free(frame_for_encode_);
    frame_for_encode_ = nullptr;
  }
  if (inited_) {
    if (aom_codec_destroy(&ctx_)) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    inited_ = false;
  }
  speed_controllers_.clear();
  rates_configured_ = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

void LibaomAv1Encoder::MaybeRewrapImgWithFormat(const aom_img_fmt_t fmt,
                                                unsigned int width,
                                                unsigned int height) {
  if (!frame_for_encode_) {
    RTC_LOG(LS_INFO) << "Configuring AV1 encoder pixel format to "
                     << (fmt == AOM_IMG_FMT_NV12 ? "NV12" : "I420") << " "
                     << width << "x" << height;
    frame_for_encode_ = aom_img_wrap(nullptr, fmt, width, height, 1, nullptr);
  } else if (frame_for_encode_->fmt != fmt || frame_for_encode_->d_w != width ||
             frame_for_encode_->d_h != height) {
    RTC_LOG(LS_INFO) << "Switching AV1 encoder pixel format to "
                     << (fmt == AOM_IMG_FMT_NV12 ? "NV12" : "I420") << " "
                     << width << "x" << height;
    aom_img_free(frame_for_encode_);
    frame_for_encode_ = aom_img_wrap(nullptr, fmt, width, height, 1, nullptr);
  }
  // else no-op since the image is already in the right format.
}

void LibaomAv1Encoder::AdjustScalingFactorsForTopActiveLayer() {
  if (!SvcEnabled())
    return;
  last_active_layer_ = svc_params_->number_spatial_layers - 1;
  for (int sid = 0; sid < svc_params_->number_spatial_layers; ++sid) {
    for (int tid = 0; tid < svc_params_->number_temporal_layers; ++tid) {
      int layer_index = sid * svc_params_->number_temporal_layers + tid;
      if (svc_params_->layer_target_bitrate[layer_index] > 0) {
        last_active_layer_ = sid;
      }
    }
  }
  if (static_cast<int>(cfg_.g_w) ==
      encoder_settings_.spatialLayers[last_active_layer_].width) {
    return;
  }

  cfg_.g_w = encoder_settings_.spatialLayers[last_active_layer_].width;
  cfg_.g_h = encoder_settings_.spatialLayers[last_active_layer_].height;

  // Recalculate scaling factors ignoring top inactive layers.
  // Divide all by scaling factor of the last active layer.
  for (int i = 0; i <= last_active_layer_; ++i) {
    int n = scaling_factors_num_[i] * scaling_factors_den_[last_active_layer_];
    int d = scaling_factors_den_[i] * scaling_factors_num_[last_active_layer_];
    int gcd = std::gcd(n, d);
    svc_params_->scaling_factor_num[i] = n / gcd;
    svc_params_->scaling_factor_den[i] = d / gcd;
  }
  for (int i = last_active_layer_ + 1; i < svc_params_->number_spatial_layers;
       ++i) {
    svc_params_->scaling_factor_num[i] = 1;
    svc_params_->scaling_factor_den[i] = 1;
  }
}

EncoderSpeedController::ReferenceClass
LibaomAv1Encoder::AsSpeedControllerFrameType(
    const ScalableVideoController::LayerFrameConfig& layer_frame) const {
  if (layer_frame.IsKeyframe()) {
    return EncoderSpeedController::ReferenceClass::kKey;
  }

  int tid = layer_frame.TemporalId();
  if (tid == 0) {
    return EncoderSpeedController::ReferenceClass::kMain;
  } else if (svc_params_ && tid == svc_params_->number_temporal_layers - 1) {
    return EncoderSpeedController::ReferenceClass::kNoneReference;
  }
  return EncoderSpeedController::ReferenceClass::kIntermediate;
}

TimeDelta LibaomAv1Encoder::GetFrameInterval(int spatial_index) const {
  TimeDelta frame_interval =
      TimeDelta::Seconds(1) /
      (framerate_fps_ == 0 ? encoder_settings_.maxFramerate : framerate_fps_);

  if (!SvcEnabled()) {
    return frame_interval;
  }

  RTC_DCHECK_LT(spatial_index, svc_params_->number_spatial_layers);

  // Allocate a time slice for each spatial layer, proportional to the
  // fraction of pixels allocated for that layer.
  // E.g. if QVGA + VGA is used, 20% of the encoder time will be allocated
  // for QVGA + 80% for VGA - since VGA has 4x the number of pixels.
  int pixel_count_sum = 0;
  for (int si = 0; si < svc_params_->number_spatial_layers; ++si) {
    pixel_count_sum += encoder_settings_.spatialLayers[si].width *
                       encoder_settings_.spatialLayers[si].height;
  }

  double pixel_count_fraction =
      static_cast<double>(
          encoder_settings_.spatialLayers[spatial_index].width *
          encoder_settings_.spatialLayers[spatial_index].height) /
      pixel_count_sum;
  return frame_interval * pixel_count_fraction;
}

int32_t LibaomAv1Encoder::Encode(
    const VideoFrame& frame,
    const std::vector<VideoFrameType>* frame_types) {
  if (!inited_ || encoded_image_callback_ == nullptr || !rates_configured_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  bool keyframe_required =
      frame_types != nullptr &&
      absl::c_linear_search(*frame_types, VideoFrameType::kVideoFrameKey);

  std::vector<ScalableVideoController::LayerFrameConfig> layer_frames =
      svc_controller_->NextFrameConfig(keyframe_required);

  if (layer_frames.empty()) {
    RTC_LOG(LS_ERROR) << "SVCController returned no configuration for a frame.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  if (drop_repeat_frames_on_enhancement_layers_ && frame.is_repeat_frame()) {
    bool all_layers_droppable = !layer_frames.empty();
    for (const auto& layer_frame : layer_frames) {
      if (layer_frame.TemporalId() == 0) {
        all_layers_droppable = false;
        break;
      }
      if (auto it =
              last_encoded_timestamp_by_sid_.find(layer_frame.SpatialId());
          it != last_encoded_timestamp_by_sid_.end()) {
        // Get the time since the last encoded frame for this spatial layer.
        // Don't drop enhancement layer repeat frame if last encode was more
        // than one second ago.
        if ((frame.rtp_timestamp() - it->second) > kVideoPayloadTypeFrequency) {
          all_layers_droppable = false;
          break;
        }
      }
    }

    if (all_layers_droppable) {
      RTC_LOG(LS_VERBOSE) << "Dropping repeat frame on enhancement layers.";
      for (const auto& layer_frame : layer_frames) {
        svc_controller_->OnEncodeDone(layer_frame);
      }
      return WEBRTC_VIDEO_CODEC_OK;  // Frame dropped
    }
  }

  scoped_refptr<VideoFrameBuffer> buffer = frame.video_frame_buffer();
  absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
      supported_formats = {VideoFrameBuffer::Type::kI420,
                           VideoFrameBuffer::Type::kNV12};

  scoped_refptr<VideoFrameBuffer> scaled_image;
  if (!SvcEnabled() ||
      last_active_layer_ + 1 == svc_params_->number_spatial_layers) {
    scaled_image = buffer;
  } else {
    scaled_image = buffer->Scale(
        encoder_settings_.spatialLayers[last_active_layer_].width,
        encoder_settings_.spatialLayers[last_active_layer_].height);
  }

  scoped_refptr<VideoFrameBuffer> mapped_buffer;
  if (scaled_image->type() != VideoFrameBuffer::Type::kNative) {
    // `buffer` is already mapped.
    mapped_buffer = scaled_image;
  } else {
    // Attempt to map to one of the supported formats.
    mapped_buffer = scaled_image->GetMappedFrameBuffer(supported_formats);
  }

  // Convert input frame to I420, if needed.
  if (!mapped_buffer ||
      (absl::c_find(supported_formats, mapped_buffer->type()) ==
           supported_formats.end() &&
       mapped_buffer->type() != VideoFrameBuffer::Type::kI420A)) {
    scoped_refptr<I420BufferInterface> converted_buffer(buffer->ToI420());
    if (!converted_buffer) {
      RTC_LOG(LS_ERROR) << "Failed to convert "
                        << VideoFrameBufferTypeToString(
                               frame.video_frame_buffer()->type())
                        << " image to I420. Can't encode frame.";
      return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
    }
    RTC_CHECK(converted_buffer->type() == VideoFrameBuffer::Type::kI420 ||
              converted_buffer->type() == VideoFrameBuffer::Type::kI420A);

    mapped_buffer = converted_buffer;
  }

  switch (mapped_buffer->type()) {
    case VideoFrameBuffer::Type::kI420:
    case VideoFrameBuffer::Type::kI420A: {
      // Set frame_for_encode_ data pointers and strides.
      MaybeRewrapImgWithFormat(AOM_IMG_FMT_I420, mapped_buffer->width(),
                               mapped_buffer->height());
      auto i420_buffer = mapped_buffer->GetI420();
      RTC_DCHECK(i420_buffer);

      // TODO: crbug.com/492213293 - Remove once the root cause is fixed.
      if (i420_buffer->StrideU() != i420_buffer->StrideV()) {
        RTC_LOG(LS_ERROR) << "Libaom requires the U and V strides to be equal.";
        return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
      }

      RTC_CHECK_EQ(i420_buffer->width(), frame_for_encode_->d_w);
      RTC_CHECK_EQ(i420_buffer->height(), frame_for_encode_->d_h);
      frame_for_encode_->planes[AOM_PLANE_Y] =
          const_cast<unsigned char*>(i420_buffer->DataY());
      frame_for_encode_->planes[AOM_PLANE_U] =
          const_cast<unsigned char*>(i420_buffer->DataU());
      frame_for_encode_->planes[AOM_PLANE_V] =
          const_cast<unsigned char*>(i420_buffer->DataV());
      frame_for_encode_->stride[AOM_PLANE_Y] = i420_buffer->StrideY();
      frame_for_encode_->stride[AOM_PLANE_U] = i420_buffer->StrideU();
      frame_for_encode_->stride[AOM_PLANE_V] = i420_buffer->StrideV();
      break;
    }
    case VideoFrameBuffer::Type::kNV12: {
      MaybeRewrapImgWithFormat(AOM_IMG_FMT_NV12, mapped_buffer->width(),
                               mapped_buffer->height());
      const NV12BufferInterface* nv12_buffer = mapped_buffer->GetNV12();
      RTC_DCHECK(nv12_buffer);
      RTC_CHECK_EQ(nv12_buffer->width(), frame_for_encode_->d_w);
      RTC_CHECK_EQ(nv12_buffer->height(), frame_for_encode_->d_h);
      frame_for_encode_->planes[AOM_PLANE_Y] =
          const_cast<unsigned char*>(nv12_buffer->DataY());
      frame_for_encode_->planes[AOM_PLANE_U] =
          const_cast<unsigned char*>(nv12_buffer->DataUV());
      frame_for_encode_->planes[AOM_PLANE_V] = nullptr;
      frame_for_encode_->stride[AOM_PLANE_Y] = nv12_buffer->StrideY();
      frame_for_encode_->stride[AOM_PLANE_U] = nv12_buffer->StrideUV();
      frame_for_encode_->stride[AOM_PLANE_V] = 0;
      break;
    }
    default:
      return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
  }

  const uint32_t duration = kVideoPayloadTypeFrequency / framerate_fps_;
  timestamp_ += duration;

  const size_t num_spatial_layers =
      svc_params_ ? svc_params_->number_spatial_layers : 1;
  auto next_layer_frame = layer_frames.begin();
  std::vector<std::pair<EncodedImage, CodecSpecificInfo>> encoded_images;
  // Index into `encoded_images` indicating the last active layer which produced
  // an encoded image. Used to correctly set `end_of_picture`.
  std::optional<size_t> last_encoded_image_index;
  for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
    // The libaom AV1 encoder requires that `aom_codec_encode` is called for
    // every spatial layer, even if the configured bitrate for that layer is
    // zero. For zero bitrate spatial layers no frames will be produced.
    std::optional<ScalableVideoController::LayerFrameConfig>
        non_encoded_layer_frame;
    ScalableVideoController::LayerFrameConfig* layer_frame;
    if (next_layer_frame != layer_frames.end() &&
        next_layer_frame->SpatialId() == static_cast<int>(sid)) {
      layer_frame = &*next_layer_frame;
      ++next_layer_frame;
    } else {
      // For layers that are not encoded only the spatial id matters.
      non_encoded_layer_frame.emplace().S(sid);
      layer_frame = &*non_encoded_layer_frame;
    }

    aom_enc_frame_flags_t flags =
        layer_frame->IsKeyframe() ? AOM_EFLAG_FORCE_KF : 0;

    if (SvcEnabled()) {
      SetSvcLayerId(*layer_frame);
      SetSvcRefFrameConfig(*layer_frame);
    }

    EncodeResult output;
    if (!speed_controllers_.empty()) {
      RTC_DCHECK_GT(speed_controllers_.size(), sid);
      EncoderSpeedController& speed_controller = *speed_controllers_[sid];

      EncoderSpeedController::FrameEncodingInfo frame_info{
          .reference_type = AsSpeedControllerFrameType(*layer_frame),
          .is_repeat_frame = frame.is_repeat_frame(),
          .timestamp = Timestamp::Millis(frame.render_time_ms())};
      EncoderSpeedController::EncodeSettings settings =
          speed_controller.GetEncodeSettings(frame_info);

      if (settings.calculate_psnr && kEnablePsnrStats) {
        flags |= AOM_EFLAG_CALCULATE_PSNR;
      }

      // Encode with baseline settings in case a speed control probe is
      // requested.
      std::optional<EncodeResult> baseline_output;
      if (settings.baseline_comparison_speed.has_value()) {
        // Configure the desired speed setting.
        SET_ENCODER_PARAM_OR_RETURN_ERROR(AOME_SET_CPUUSED,
                                          *settings.baseline_comparison_speed);

        // Encode the frame, with the encoder internal state frozen - so that
        // rate control etc is not updated.
        baseline_output = DoEncode(
            duration, flags | AOM_EFLAG_FREEZE_INTERNAL_STATE, layer_frame);

        if (baseline_output->status_code != AOM_CODEC_OK) {
          RTC_LOG(LS_WARNING)
              << "LibaomAv1Encoder::Encode returned error: '"
              << aom_codec_err_to_string(baseline_output->status_code) << "'.";
          return WEBRTC_VIDEO_CODEC_ERROR;
        }

        if (!baseline_output->encoded_image.has_value()) {
          // Frame dropped, no point in trying to encode a second time.
          continue;
        }
      }

      SET_ENCODER_PARAM_OR_RETURN_ERROR(AOME_SET_CPUUSED, settings.speed);
      output = DoEncode(duration, flags, layer_frame);
      if (output.status_code != AOM_CODEC_OK) {
        RTC_LOG(LS_WARNING)
            << "LibaomAv1Encoder::Encode returned error: '"
            << aom_codec_err_to_string(output.status_code) << "'.";
        return WEBRTC_VIDEO_CODEC_ERROR;
      }

      if (non_encoded_layer_frame || !output.encoded_image.has_value()) {
        // Frame dropped, presumably by rate controller. This is not an error.
        if (baseline_output.has_value() &&
            baseline_output->encoded_image.has_value()) {
          // Second encoding dropped frame, but not the first. This is
          // unexpected. Use baseline encoding as main frame instead.
          output = *baseline_output;
          baseline_output.reset();
          RTC_LOG(LS_WARNING) << "AV1 Encoder unexpectedly dropped frame on "
                              << "second encoding of PSNR probe.";
        } else {
          EncodedImage dropped_image;
          dropped_image.SetSpatialIndex(sid);
          dropped_image.set_end_of_temporal_unit(sid == num_spatial_layers - 1);
          encoded_images.emplace_back(std::move(dropped_image),
                                      CodecSpecificInfo());
          continue;
        }
      }

      speed_controller.OnEncodedFrame(
          ToSpeedControllerEncodeResult(output, frame_info, settings.speed),
          baseline_output.has_value()
              ? std::optional<EncoderSpeedController::EncodeResults>(
                    ToSpeedControllerEncodeResult(
                        *baseline_output, frame_info,
                        *settings.baseline_comparison_speed))
              : std::nullopt);

    } else {
      // No speed controller used.

      if (kEnablePsnrStats && psnr_experiment_.IsEnabled() &&
          psnr_frame_sampler_.ShouldBeSampled(frame)) {
        flags |= AOM_EFLAG_CALCULATE_PSNR;
      }

      output = DoEncode(duration, flags, layer_frame);
      if (output.status_code != AOM_CODEC_OK) {
        RTC_LOG(LS_WARNING)
            << "LibaomAv1Encoder::Encode returned error: '"
            << aom_codec_err_to_string(output.status_code) << "'.";
        return WEBRTC_VIDEO_CODEC_ERROR;
      }
      if (non_encoded_layer_frame || !output.encoded_image.has_value()) {
        // Frame dropped, presumably by rate controller. This is not an error.
        EncodedImage dropped_image;
        dropped_image.SetSpatialIndex(sid);
        dropped_image.set_end_of_temporal_unit(sid == num_spatial_layers - 1);
        encoded_images.emplace_back(std::move(dropped_image),
                                    CodecSpecificInfo());
        continue;
      }
    }

    RTC_DCHECK(output.encoded_image.has_value());
    RTC_DCHECK_GT(output.encoded_image->size(), 0u);

    PopulateEncodedImageFromVideoFrame(frame, *output.encoded_image);
    CodecSpecificInfo codec_specifics =
        CreateCodecSpecificInfo(*output.encoded_image, *layer_frame);

    output.encoded_image->set_end_of_temporal_unit(sid ==
                                                   num_spatial_layers - 1);
    last_encoded_image_index = encoded_images.size();
    encoded_images.emplace_back(std::move(*output.encoded_image),
                                std::move(codec_specifics));
  }

  for (size_t i = 0; i < encoded_images.size(); ++i) {
    auto& [encoded_image, codec_specifics] = encoded_images[i];
    codec_specifics.end_of_picture = i == last_encoded_image_index;
    if (encoded_image.size() > 0) {
      encoded_image_callback_->OnEncodedImage(encoded_image, &codec_specifics);
      if (encoded_image.SpatialIndex().has_value()) {
        last_encoded_timestamp_by_sid_[*encoded_image.SpatialIndex()] =
            frame.rtp_timestamp();
      }
      continue;
    }
    // Size 0 indicates a dropped frame (inserted above).
    encoded_image_callback_->OnFrameDropped(
        frame.rtp_timestamp(), *encoded_image.SpatialIndex(),
        *encoded_image.is_end_of_temporal_unit());
  }

  return WEBRTC_VIDEO_CODEC_OK;
}

EncodeResult LibaomAv1Encoder::DoEncode(
    uint32_t duration,
    aom_enc_frame_flags_t flags,
    ScalableVideoController::LayerFrameConfig* layer_frame) {
  // Encode a frame. The presentation timestamp `pts` should not use real
  // timestamps from frames or the wall clock, as that can cause the rate
  // controller to misbehave.
  EncodeResult output;

  Timestamp start_time = realtime_clock_->CurrentTime();
  output.status_code =
      aom_codec_encode(&ctx_, frame_for_encode_, timestamp_, duration, flags);
  output.encode_time = realtime_clock_->CurrentTime() - start_time;

  if (output.status_code != AOM_CODEC_OK) {
    return output;
  }

  // Get encoded image data.
  aom_codec_iter_t iter = nullptr;
  int data_pkt_count = 0;
  output.encoded_image.emplace();
  EncodedImage& encoded_image = *output.encoded_image;
  const aom_codec_cx_pkt_t* pkt = nullptr;
  while ((pkt = aom_codec_get_cx_data(&ctx_, &iter)) != nullptr) {
    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT && pkt->data.frame.sz > 0) {
      if (data_pkt_count > 0) {
        RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::Encoder returned more than "
                               "one data packet for an input video frame.";
        Release();
        output.status_code = AOM_CODEC_ERROR;
        return output;
      }
      encoded_image.SetEncodedData(EncodedImageBuffer::Create(
          /*data=*/static_cast<const uint8_t*>(pkt->data.frame.buf),
          /*size=*/pkt->data.frame.sz));

      if ((pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0) {
        layer_frame->Keyframe();
      }

      encoded_image.set_frame_type(layer_frame->IsKeyframe()
                                       ? VideoFrameType::kVideoFrameKey
                                       : VideoFrameType::kVideoFrameDelta);

      encoded_image.content_type_ = VideoContentType::UNSPECIFIED;
      // If encoded image width/height info are added to aom_codec_cx_pkt_t,
      // use those values in lieu of the values in frame.
      if (svc_params_) {
        int n = scaling_factors_num_[layer_frame->SpatialId()];
        int d = scaling_factors_den_[layer_frame->SpatialId()];
        encoded_image._encodedWidth = encoder_settings_.width * n / d;
        encoded_image._encodedHeight = encoder_settings_.height * n / d;
        encoded_image.SetSpatialIndex(layer_frame->SpatialId());
        encoded_image.SetTemporalIndex(layer_frame->TemporalId());
      } else {
        encoded_image._encodedWidth = cfg_.g_w;
        encoded_image._encodedHeight = cfg_.g_h;
      }
      encoded_image.timing_.flags = VideoSendTiming::kInvalid;

      if (!SetEncoderControlParameters(AOME_GET_LAST_QUANTIZER,
                                       &encoded_image.qp_)) {
        RTC_LOG(LS_WARNING) << "Unable to fetch QP for frame.";
        output.status_code = AOM_CODEC_ERROR;
        return output;
      }

      ++data_pkt_count;
    } else if (pkt->kind == AOM_CODEC_PSNR_PKT) {
      // PSNR index: 0: total, 1: Y, 2: U, 3: V
      encoded_image.set_psnr(EncodedImage::Psnr({.y = pkt->data.psnr.psnr[1],
                                                 .u = pkt->data.psnr.psnr[2],
                                                 .v = pkt->data.psnr.psnr[3]}));
    }
  }

  if (encoded_image.size() == 0) {
    // Encode success, but no image produced. Frame as just dropped.
    output.encoded_image.reset();
  }

  return output;
}

CodecSpecificInfo LibaomAv1Encoder::CreateCodecSpecificInfo(
    const EncodedImage& image,
    const ScalableVideoController::LayerFrameConfig& layer_frame) {
  CodecSpecificInfo codec_specific_info;
  codec_specific_info.codecType = kVideoCodecAV1;
  codec_specific_info.scalability_mode = scalability_mode_;
  bool is_keyframe = layer_frame.IsKeyframe();
  codec_specific_info.generic_frame_info =
      svc_controller_->OnEncodeDone(layer_frame);
  if (is_keyframe && codec_specific_info.generic_frame_info) {
    codec_specific_info.template_structure =
        svc_controller_->DependencyStructure();
    auto& resolutions = codec_specific_info.template_structure->resolutions;
    if (SvcEnabled()) {
      resolutions.resize(svc_params_->number_spatial_layers);
      for (int sid = 0; sid < svc_params_->number_spatial_layers; ++sid) {
        int n = scaling_factors_num_[sid];
        int d = scaling_factors_den_[sid];
        resolutions[sid] = RenderResolution(encoder_settings_.width * n / d,
                                            encoder_settings_.height * n / d);
      }
    } else {
      resolutions = {RenderResolution(cfg_.g_w, cfg_.g_h)};
    }
  }
  return codec_specific_info;
}

void LibaomAv1Encoder::SetRates(const RateControlParameters& parameters) {
  if (!inited_) {
    RTC_LOG(LS_WARNING) << "SetRates() while encoder is not initialized";
    return;
  }
  if (parameters.framerate_fps < kMinFrameRateFps) {
    RTC_LOG(LS_WARNING) << "Unsupported framerate (must be >= "
                        << kMinFrameRateFps
                        << " ): " << parameters.framerate_fps;
    return;
  }
  if (parameters.bitrate.get_sum_bps() == 0) {
    RTC_LOG(LS_WARNING) << "Attempt to set target bit rate to zero";
    return;
  }

  // The bitrates caluclated internally in libaom when `AV1E_SET_SVC_PARAMS` is
  // called depends on the currently configured `rc_target_bitrate`. If the
  // total target bitrate is not updated first a division by zero could happen.
  svc_controller_->OnRatesUpdated(parameters.bitrate);
  cfg_.rc_target_bitrate = parameters.bitrate.get_sum_kbps();

  if (SvcEnabled()) {
    for (int sid = 0; sid < svc_params_->number_spatial_layers; ++sid) {
      // libaom bitrate for spatial id S and temporal id T means bitrate
      // of frames with spatial_id=S and temporal_id<=T.
      for (int tid = 0; tid < svc_params_->number_temporal_layers; ++tid) {
        int layer_index = sid * svc_params_->number_temporal_layers + tid;
        // `svc_params_->layer_target_bitrate` expects bitrate in kbps.
        svc_params_->layer_target_bitrate[layer_index] =
            parameters.bitrate.GetTemporalLayerSum(sid, tid) / 1000;
      }
    }
    AdjustScalingFactorsForTopActiveLayer();
    SetEncoderControlParameters(AV1E_SET_SVC_PARAMS, &*svc_params_);
  }

  // AdjustScalingFactorsForTopActiveLayer() may update `cfg_`.
  aom_codec_err_t error_code = aom_codec_enc_config_set(&ctx_, &cfg_);
  if (error_code != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING) << "Error configuring encoder, error code: "
                        << error_code;
  }

  framerate_fps_ = parameters.framerate_fps;
  for (size_t si = 0; si < speed_controllers_.size(); ++si) {
    speed_controllers_[si]->SetFrameInterval(GetFrameInterval(si));
  }

  rates_configured_ = true;
}

VideoEncoder::EncoderInfo LibaomAv1Encoder::GetEncoderInfo() const {
  EncoderInfo info;
  info.supports_native_handle = false;
  info.implementation_name = "libaom";
  info.has_trusted_rate_controller = true;
  info.is_hardware_accelerated = false;
  info.scaling_settings =
      (inited_ && !encoder_settings_.AV1().automatic_resize_on)
          ? VideoEncoder::ScalingSettings::kOff
          : VideoEncoder::ScalingSettings(kLowQindex, kHighQindex);
  info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420,
                                  VideoFrameBuffer::Type::kNV12};
  if (inited_) {
    info.mapped_resolution = VideoEncoder::Resolution(cfg_.g_w, cfg_.g_h);
  }
  if (SvcEnabled()) {
    for (int sid = 0; sid < svc_params_->number_spatial_layers; ++sid) {
      info.fps_allocation[sid].resize(svc_params_->number_temporal_layers);
      for (int tid = 0; tid < svc_params_->number_temporal_layers; ++tid) {
        info.fps_allocation[sid][tid] = EncoderInfo::kMaxFramerateFraction /
                                        svc_params_->framerate_factor[tid];
      }
    }
  }
  if (!encoder_info_override_.resolution_bitrate_limits().empty()) {
    info.resolution_bitrate_limits =
        encoder_info_override_.resolution_bitrate_limits();
  }

  info.min_qp = kMinQindex;
  return info;
}

}  // namespace

absl_nonnull std::unique_ptr<VideoEncoder> CreateLibaomAv1Encoder(
    const Environment& env,
    LibaomAv1EncoderSettings settings) {
  return std::make_unique<LibaomAv1Encoder>(env, std::move(settings));
}

}  // namespace webrtc
