/*
 *  Copyright 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 "video/adaptation/bitrate_constraint.h"

#include <utility>
#include <vector>

#include "api/sequence_checker.h"
#include "call/adaptation/video_stream_adapter.h"
#include "video/adaptation/video_stream_encoder_resource_manager.h"

namespace webrtc {

BitrateConstraint::BitrateConstraint()
    : encoder_settings_(absl::nullopt),
      encoder_target_bitrate_bps_(absl::nullopt) {
  sequence_checker_.Detach();
}

void BitrateConstraint::OnEncoderSettingsUpdated(
    absl::optional<EncoderSettings> encoder_settings) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  encoder_settings_ = std::move(encoder_settings);
}

void BitrateConstraint::OnEncoderTargetBitrateUpdated(
    absl::optional<uint32_t> encoder_target_bitrate_bps) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  encoder_target_bitrate_bps_ = std::move(encoder_target_bitrate_bps);
}

// Checks if resolution is allowed to adapt up based on the current bitrate and
// ResolutionBitrateLimits.min_start_bitrate_bps for the next higher resolution.
// Bitrate limits usage is restricted to a single active stream/layer (e.g. when
// quality scaling is enabled).
bool BitrateConstraint::IsAdaptationUpAllowed(
    const VideoStreamInputState& input_state,
    const VideoSourceRestrictions& restrictions_before,
    const VideoSourceRestrictions& restrictions_after) const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  // Make sure bitrate limits are not violated.
  if (DidIncreaseResolution(restrictions_before, restrictions_after)) {
    if (!encoder_settings_.has_value()) {
      return true;
    }

    uint32_t bitrate_bps = encoder_target_bitrate_bps_.value_or(0);
    if (bitrate_bps == 0) {
      return true;
    }

    if (VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers(
            encoder_settings_->encoder_config(),
            encoder_settings_->video_codec())) {
      // Resolution bitrate limits usage is restricted to singlecast.
      return true;
    }

    absl::optional<int> current_frame_size_px =
        input_state.single_active_stream_pixels();
    if (!current_frame_size_px.has_value()) {
      return true;
    }

    absl::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
        encoder_settings_->encoder_info().GetEncoderBitrateLimitsForResolution(
            // Need some sort of expected resulting pixels to be used
            // instead of unrestricted.
            GetHigherResolutionThan(*current_frame_size_px));

    if (bitrate_limits.has_value()) {
      RTC_DCHECK_GE(bitrate_limits->frame_size_pixels, *current_frame_size_px);
      return bitrate_bps >=
             static_cast<uint32_t>(bitrate_limits->min_start_bitrate_bps);
    }
  }
  return true;
}

}  // namespace webrtc
