/*
 *  Copyright (c) 2012 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 "webrtc/modules/video_coding/qm_select.h"

#include <math.h>

#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
#include "webrtc/modules/video_coding/internal_defines.h"
#include "webrtc/modules/video_coding/qm_select_data.h"
#include "webrtc/system_wrappers/include/trace.h"

namespace webrtc {

// QM-METHOD class

VCMQmMethod::VCMQmMethod()
    : content_metrics_(NULL),
      width_(0),
      height_(0),
      user_frame_rate_(0.0f),
      native_width_(0),
      native_height_(0),
      native_frame_rate_(0.0f),
      image_type_(kVGA),
      framerate_level_(kFrameRateHigh),
      init_(false) {
  ResetQM();
}

VCMQmMethod::~VCMQmMethod() {}

void VCMQmMethod::ResetQM() {
  aspect_ratio_ = 1.0f;
  motion_.Reset();
  spatial_.Reset();
  content_class_ = 0;
}

uint8_t VCMQmMethod::ComputeContentClass() {
  ComputeMotionNFD();
  ComputeSpatial();
  return content_class_ = 3 * motion_.level + spatial_.level;
}

void VCMQmMethod::UpdateContent(const VideoContentMetrics* contentMetrics) {
  content_metrics_ = contentMetrics;
}

void VCMQmMethod::ComputeMotionNFD() {
  if (content_metrics_) {
    motion_.value = content_metrics_->motion_magnitude;
  }
  // Determine motion level.
  if (motion_.value < kLowMotionNfd) {
    motion_.level = kLow;
  } else if (motion_.value > kHighMotionNfd) {
    motion_.level = kHigh;
  } else {
    motion_.level = kDefault;
  }
}

void VCMQmMethod::ComputeSpatial() {
  float spatial_err = 0.0;
  float spatial_err_h = 0.0;
  float spatial_err_v = 0.0;
  if (content_metrics_) {
    spatial_err = content_metrics_->spatial_pred_err;
    spatial_err_h = content_metrics_->spatial_pred_err_h;
    spatial_err_v = content_metrics_->spatial_pred_err_v;
  }
  // Spatial measure: take average of 3 prediction errors.
  spatial_.value = (spatial_err + spatial_err_h + spatial_err_v) / 3.0f;

  // Reduce thresholds for large scenes/higher pixel correlation.
  float scale2 = image_type_ > kVGA ? kScaleTexture : 1.0;

  if (spatial_.value > scale2 * kHighTexture) {
    spatial_.level = kHigh;
  } else if (spatial_.value < scale2 * kLowTexture) {
    spatial_.level = kLow;
  } else {
    spatial_.level = kDefault;
  }
}

ImageType VCMQmMethod::GetImageType(uint16_t width, uint16_t height) {
  // Get the image type for the encoder frame size.
  uint32_t image_size = width * height;
  if (image_size == kSizeOfImageType[kQCIF]) {
    return kQCIF;
  } else if (image_size == kSizeOfImageType[kHCIF]) {
    return kHCIF;
  } else if (image_size == kSizeOfImageType[kQVGA]) {
    return kQVGA;
  } else if (image_size == kSizeOfImageType[kCIF]) {
    return kCIF;
  } else if (image_size == kSizeOfImageType[kHVGA]) {
    return kHVGA;
  } else if (image_size == kSizeOfImageType[kVGA]) {
    return kVGA;
  } else if (image_size == kSizeOfImageType[kQFULLHD]) {
    return kQFULLHD;
  } else if (image_size == kSizeOfImageType[kWHD]) {
    return kWHD;
  } else if (image_size == kSizeOfImageType[kFULLHD]) {
    return kFULLHD;
  } else {
    // No exact match, find closet one.
    return FindClosestImageType(width, height);
  }
}

ImageType VCMQmMethod::FindClosestImageType(uint16_t width, uint16_t height) {
  float size = static_cast<float>(width * height);
  float min = size;
  int isel = 0;
  for (int i = 0; i < kNumImageTypes; ++i) {
    float dist = fabs(size - kSizeOfImageType[i]);
    if (dist < min) {
      min = dist;
      isel = i;
    }
  }
  return static_cast<ImageType>(isel);
}

FrameRateLevelClass VCMQmMethod::FrameRateLevel(float avg_framerate) {
  if (avg_framerate <= kLowFrameRate) {
    return kFrameRateLow;
  } else if (avg_framerate <= kMiddleFrameRate) {
    return kFrameRateMiddle1;
  } else if (avg_framerate <= kHighFrameRate) {
    return kFrameRateMiddle2;
  } else {
    return kFrameRateHigh;
  }
}

// RESOLUTION CLASS

VCMQmResolution::VCMQmResolution() : qm_(new VCMResolutionScale()) {
  Reset();
}

VCMQmResolution::~VCMQmResolution() {
  delete qm_;
}

void VCMQmResolution::ResetRates() {
  sum_target_rate_ = 0.0f;
  sum_incoming_framerate_ = 0.0f;
  sum_rate_MM_ = 0.0f;
  sum_rate_MM_sgn_ = 0.0f;
  sum_packet_loss_ = 0.0f;
  buffer_level_ = kInitBufferLevel * target_bitrate_;
  frame_cnt_ = 0;
  frame_cnt_delta_ = 0;
  low_buffer_cnt_ = 0;
  update_rate_cnt_ = 0;
}

void VCMQmResolution::ResetDownSamplingState() {
  state_dec_factor_spatial_ = 1.0;
  state_dec_factor_temporal_ = 1.0;
  for (int i = 0; i < kDownActionHistorySize; i++) {
    down_action_history_[i].spatial = kNoChangeSpatial;
    down_action_history_[i].temporal = kNoChangeTemporal;
  }
}

void VCMQmResolution::Reset() {
  target_bitrate_ = 0.0f;
  incoming_framerate_ = 0.0f;
  buffer_level_ = 0.0f;
  per_frame_bandwidth_ = 0.0f;
  avg_target_rate_ = 0.0f;
  avg_incoming_framerate_ = 0.0f;
  avg_ratio_buffer_low_ = 0.0f;
  avg_rate_mismatch_ = 0.0f;
  avg_rate_mismatch_sgn_ = 0.0f;
  avg_packet_loss_ = 0.0f;
  encoder_state_ = kStableEncoding;
  num_layers_ = 1;
  ResetRates();
  ResetDownSamplingState();
  ResetQM();
}

EncoderState VCMQmResolution::GetEncoderState() {
  return encoder_state_;
}

// Initialize state after re-initializing the encoder,
// i.e., after SetEncodingData() in mediaOpt.
int VCMQmResolution::Initialize(float bitrate,
                                float user_framerate,
                                uint16_t width,
                                uint16_t height,
                                int num_layers) {
  if (user_framerate == 0.0f || width == 0 || height == 0) {
    return VCM_PARAMETER_ERROR;
  }
  Reset();
  target_bitrate_ = bitrate;
  incoming_framerate_ = user_framerate;
  UpdateCodecParameters(user_framerate, width, height);
  native_width_ = width;
  native_height_ = height;
  native_frame_rate_ = user_framerate;
  num_layers_ = num_layers;
  // Initial buffer level.
  buffer_level_ = kInitBufferLevel * target_bitrate_;
  // Per-frame bandwidth.
  per_frame_bandwidth_ = target_bitrate_ / user_framerate;
  init_ = true;
  return VCM_OK;
}

void VCMQmResolution::UpdateCodecParameters(float frame_rate,
                                            uint16_t width,
                                            uint16_t height) {
  width_ = width;
  height_ = height;
  // |user_frame_rate| is the target frame rate for VPM frame dropper.
  user_frame_rate_ = frame_rate;
  image_type_ = GetImageType(width, height);
}

// Update rate data after every encoded frame.
void VCMQmResolution::UpdateEncodedSize(size_t encoded_size) {
  frame_cnt_++;
  // Convert to Kbps.
  float encoded_size_kbits = 8.0f * static_cast<float>(encoded_size) / 1000.0f;

  // Update the buffer level:
  // Note this is not the actual encoder buffer level.
  // |buffer_level_| is reset to an initial value after SelectResolution is
  // called, and does not account for frame dropping by encoder or VCM.
  buffer_level_ += per_frame_bandwidth_ - encoded_size_kbits;

  // Counter for occurrences of low buffer level:
  // low/negative values means encoder is likely dropping frames.
  if (buffer_level_ <= kPercBufferThr * kInitBufferLevel * target_bitrate_) {
    low_buffer_cnt_++;
  }
}

// Update various quantities after SetTargetRates in MediaOpt.
void VCMQmResolution::UpdateRates(float target_bitrate,
                                  float encoder_sent_rate,
                                  float incoming_framerate,
                                  uint8_t packet_loss) {
  // Sum the target bitrate: this is the encoder rate from previous update
  // (~1sec), i.e, before the update for next ~1sec.
  sum_target_rate_ += target_bitrate_;
  update_rate_cnt_++;

  // Sum the received (from RTCP reports) packet loss rates.
  sum_packet_loss_ += static_cast<float>(packet_loss / 255.0);

  // Sum the sequence rate mismatch:
  // Mismatch here is based on the difference between the target rate
  // used (in previous ~1sec) and the average actual encoding rate measured
  // at previous ~1sec.
  float diff = target_bitrate_ - encoder_sent_rate;
  if (target_bitrate_ > 0.0)
    sum_rate_MM_ += fabs(diff) / target_bitrate_;
  int sgnDiff = diff > 0 ? 1 : (diff < 0 ? -1 : 0);
  // To check for consistent under(+)/over_shooting(-) of target rate.
  sum_rate_MM_sgn_ += sgnDiff;

  // Update with the current new target and frame rate:
  // these values are ones the encoder will use for the current/next ~1sec.
  target_bitrate_ = target_bitrate;
  incoming_framerate_ = incoming_framerate;
  sum_incoming_framerate_ += incoming_framerate_;
  // Update the per_frame_bandwidth:
  // this is the per_frame_bw for the current/next ~1sec.
  per_frame_bandwidth_ = 0.0f;
  if (incoming_framerate_ > 0.0f) {
    per_frame_bandwidth_ = target_bitrate_ / incoming_framerate_;
  }
}

// Select the resolution factors: frame size and frame rate change (qm scales).
// Selection is for going down in resolution, or for going back up
// (if a previous down-sampling action was taken).

// In the current version the following constraints are imposed:
// 1) We only allow for one action, either down or up, at a given time.
// 2) The possible down-sampling actions are: spatial by 1/2x1/2, 3/4x3/4;
//    temporal/frame rate reduction by 1/2 and 2/3.
// 3) The action for going back up is the reverse of last (spatial or temporal)
//    down-sampling action. The list of down-sampling actions from the
//    Initialize() state are kept in |down_action_history_|.
// 4) The total amount of down-sampling (spatial and/or temporal) from the
//    Initialize() state (native resolution) is limited by various factors.
int VCMQmResolution::SelectResolution(VCMResolutionScale** qm) {
  if (!init_) {
    return VCM_UNINITIALIZED;
  }
  if (content_metrics_ == NULL) {
    Reset();
    *qm = qm_;
    return VCM_OK;
  }

  // Check conditions on down-sampling state.
  assert(state_dec_factor_spatial_ >= 1.0f);
  assert(state_dec_factor_temporal_ >= 1.0f);
  assert(state_dec_factor_spatial_ <= kMaxSpatialDown);
  assert(state_dec_factor_temporal_ <= kMaxTempDown);
  assert(state_dec_factor_temporal_ * state_dec_factor_spatial_ <=
         kMaxTotalDown);

  // Compute content class for selection.
  content_class_ = ComputeContentClass();
  // Compute various rate quantities for selection.
  ComputeRatesForSelection();

  // Get the encoder state.
  ComputeEncoderState();

  // Default settings: no action.
  SetDefaultAction();
  *qm = qm_;

  // Check for going back up in resolution, if we have had some down-sampling
  // relative to native state in Initialize().
  if (down_action_history_[0].spatial != kNoChangeSpatial ||
      down_action_history_[0].temporal != kNoChangeTemporal) {
    if (GoingUpResolution()) {
      *qm = qm_;
      return VCM_OK;
    }
  }

  // Check for going down in resolution.
  if (GoingDownResolution()) {
    *qm = qm_;
    return VCM_OK;
  }
  return VCM_OK;
}

void VCMQmResolution::SetDefaultAction() {
  qm_->codec_width = width_;
  qm_->codec_height = height_;
  qm_->frame_rate = user_frame_rate_;
  qm_->change_resolution_spatial = false;
  qm_->change_resolution_temporal = false;
  qm_->spatial_width_fact = 1.0f;
  qm_->spatial_height_fact = 1.0f;
  qm_->temporal_fact = 1.0f;
  action_.spatial = kNoChangeSpatial;
  action_.temporal = kNoChangeTemporal;
}

void VCMQmResolution::ComputeRatesForSelection() {
  avg_target_rate_ = 0.0f;
  avg_incoming_framerate_ = 0.0f;
  avg_ratio_buffer_low_ = 0.0f;
  avg_rate_mismatch_ = 0.0f;
  avg_rate_mismatch_sgn_ = 0.0f;
  avg_packet_loss_ = 0.0f;
  if (frame_cnt_ > 0) {
    avg_ratio_buffer_low_ =
        static_cast<float>(low_buffer_cnt_) / static_cast<float>(frame_cnt_);
  }
  if (update_rate_cnt_ > 0) {
    avg_rate_mismatch_ =
        static_cast<float>(sum_rate_MM_) / static_cast<float>(update_rate_cnt_);
    avg_rate_mismatch_sgn_ = static_cast<float>(sum_rate_MM_sgn_) /
                             static_cast<float>(update_rate_cnt_);
    avg_target_rate_ = static_cast<float>(sum_target_rate_) /
                       static_cast<float>(update_rate_cnt_);
    avg_incoming_framerate_ = static_cast<float>(sum_incoming_framerate_) /
                              static_cast<float>(update_rate_cnt_);
    avg_packet_loss_ = static_cast<float>(sum_packet_loss_) /
                       static_cast<float>(update_rate_cnt_);
  }
  // For selection we may want to weight some quantities more heavily
  // with the current (i.e., next ~1sec) rate values.
  avg_target_rate_ =
      kWeightRate * avg_target_rate_ + (1.0 - kWeightRate) * target_bitrate_;
  avg_incoming_framerate_ = kWeightRate * avg_incoming_framerate_ +
                            (1.0 - kWeightRate) * incoming_framerate_;
  // Use base layer frame rate for temporal layers: this will favor spatial.
  assert(num_layers_ > 0);
  framerate_level_ = FrameRateLevel(avg_incoming_framerate_ /
                                    static_cast<float>(1 << (num_layers_ - 1)));
}

void VCMQmResolution::ComputeEncoderState() {
  // Default.
  encoder_state_ = kStableEncoding;

  // Assign stressed state if:
  // 1) occurrences of low buffer levels is high, or
  // 2) rate mis-match is high, and consistent over-shooting by encoder.
  if ((avg_ratio_buffer_low_ > kMaxBufferLow) ||
      ((avg_rate_mismatch_ > kMaxRateMisMatch) &&
       (avg_rate_mismatch_sgn_ < -kRateOverShoot))) {
    encoder_state_ = kStressedEncoding;
  }
  // Assign easy state if:
  // 1) rate mis-match is high, and
  // 2) consistent under-shooting by encoder.
  if ((avg_rate_mismatch_ > kMaxRateMisMatch) &&
      (avg_rate_mismatch_sgn_ > kRateUnderShoot)) {
    encoder_state_ = kEasyEncoding;
  }
}

bool VCMQmResolution::GoingUpResolution() {
  // For going up, we check for undoing the previous down-sampling action.

  float fac_width = kFactorWidthSpatial[down_action_history_[0].spatial];
  float fac_height = kFactorHeightSpatial[down_action_history_[0].spatial];
  float fac_temp = kFactorTemporal[down_action_history_[0].temporal];
  // For going up spatially, we allow for going up by 3/4x3/4 at each stage.
  // So if the last spatial action was 1/2x1/2 it would be undone in 2 stages.
  // Modify the fac_width/height for this case.
  if (down_action_history_[0].spatial == kOneQuarterSpatialUniform) {
    fac_width = kFactorWidthSpatial[kOneQuarterSpatialUniform] /
                kFactorWidthSpatial[kOneHalfSpatialUniform];
    fac_height = kFactorHeightSpatial[kOneQuarterSpatialUniform] /
                 kFactorHeightSpatial[kOneHalfSpatialUniform];
  }

  // Check if we should go up both spatially and temporally.
  if (down_action_history_[0].spatial != kNoChangeSpatial &&
      down_action_history_[0].temporal != kNoChangeTemporal) {
    if (ConditionForGoingUp(fac_width, fac_height, fac_temp,
                            kTransRateScaleUpSpatialTemp)) {
      action_.spatial = down_action_history_[0].spatial;
      action_.temporal = down_action_history_[0].temporal;
      UpdateDownsamplingState(kUpResolution);
      return true;
    }
  }
  // Check if we should go up either spatially or temporally.
  bool selected_up_spatial = false;
  bool selected_up_temporal = false;
  if (down_action_history_[0].spatial != kNoChangeSpatial) {
    selected_up_spatial = ConditionForGoingUp(fac_width, fac_height, 1.0f,
                                              kTransRateScaleUpSpatial);
  }
  if (down_action_history_[0].temporal != kNoChangeTemporal) {
    selected_up_temporal =
        ConditionForGoingUp(1.0f, 1.0f, fac_temp, kTransRateScaleUpTemp);
  }
  if (selected_up_spatial && !selected_up_temporal) {
    action_.spatial = down_action_history_[0].spatial;
    action_.temporal = kNoChangeTemporal;
    UpdateDownsamplingState(kUpResolution);
    return true;
  } else if (!selected_up_spatial && selected_up_temporal) {
    action_.spatial = kNoChangeSpatial;
    action_.temporal = down_action_history_[0].temporal;
    UpdateDownsamplingState(kUpResolution);
    return true;
  } else if (selected_up_spatial && selected_up_temporal) {
    PickSpatialOrTemporal();
    UpdateDownsamplingState(kUpResolution);
    return true;
  }
  return false;
}

bool VCMQmResolution::ConditionForGoingUp(float fac_width,
                                          float fac_height,
                                          float fac_temp,
                                          float scale_fac) {
  float estimated_transition_rate_up =
      GetTransitionRate(fac_width, fac_height, fac_temp, scale_fac);
  // Go back up if:
  // 1) target rate is above threshold and current encoder state is stable, or
  // 2) encoder state is easy (encoder is significantly under-shooting target).
  if (((avg_target_rate_ > estimated_transition_rate_up) &&
       (encoder_state_ == kStableEncoding)) ||
      (encoder_state_ == kEasyEncoding)) {
    return true;
  } else {
    return false;
  }
}

bool VCMQmResolution::GoingDownResolution() {
  float estimated_transition_rate_down =
      GetTransitionRate(1.0f, 1.0f, 1.0f, 1.0f);
  float max_rate = kFrameRateFac[framerate_level_] * kMaxRateQm[image_type_];
  // Resolution reduction if:
  // (1) target rate is below transition rate, or
  // (2) encoder is in stressed state and target rate below a max threshold.
  if ((avg_target_rate_ < estimated_transition_rate_down) ||
      (encoder_state_ == kStressedEncoding && avg_target_rate_ < max_rate)) {
    // Get the down-sampling action: based on content class, and how low
    // average target rate is relative to transition rate.
    uint8_t spatial_fact =
        kSpatialAction[content_class_ +
                       9 * RateClass(estimated_transition_rate_down)];
    uint8_t temp_fact =
        kTemporalAction[content_class_ +
                        9 * RateClass(estimated_transition_rate_down)];

    switch (spatial_fact) {
      case 4: {
        action_.spatial = kOneQuarterSpatialUniform;
        break;
      }
      case 2: {
        action_.spatial = kOneHalfSpatialUniform;
        break;
      }
      case 1: {
        action_.spatial = kNoChangeSpatial;
        break;
      }
      default: { assert(false); }
    }
    switch (temp_fact) {
      case 3: {
        action_.temporal = kTwoThirdsTemporal;
        break;
      }
      case 2: {
        action_.temporal = kOneHalfTemporal;
        break;
      }
      case 1: {
        action_.temporal = kNoChangeTemporal;
        break;
      }
      default: { assert(false); }
    }
    // Only allow for one action (spatial or temporal) at a given time.
    assert(action_.temporal == kNoChangeTemporal ||
           action_.spatial == kNoChangeSpatial);

    // Adjust cases not captured in tables, mainly based on frame rate, and
    // also check for odd frame sizes.
    AdjustAction();

    // Update down-sampling state.
    if (action_.spatial != kNoChangeSpatial ||
        action_.temporal != kNoChangeTemporal) {
      UpdateDownsamplingState(kDownResolution);
      return true;
    }
  }
  return false;
}

float VCMQmResolution::GetTransitionRate(float fac_width,
                                         float fac_height,
                                         float fac_temp,
                                         float scale_fac) {
  ImageType image_type =
      GetImageType(static_cast<uint16_t>(fac_width * width_),
                   static_cast<uint16_t>(fac_height * height_));

  FrameRateLevelClass framerate_level =
      FrameRateLevel(fac_temp * avg_incoming_framerate_);
  // If we are checking for going up temporally, and this is the last
  // temporal action, then use native frame rate.
  if (down_action_history_[1].temporal == kNoChangeTemporal &&
      fac_temp > 1.0f) {
    framerate_level = FrameRateLevel(native_frame_rate_);
  }

  // The maximum allowed rate below which down-sampling is allowed:
  // Nominal values based on image format (frame size and frame rate).
  float max_rate = kFrameRateFac[framerate_level] * kMaxRateQm[image_type];

  uint8_t image_class = image_type > kVGA ? 1 : 0;
  uint8_t table_index = image_class * 9 + content_class_;
  // Scale factor for down-sampling transition threshold:
  // factor based on the content class and the image size.
  float scaleTransRate = kScaleTransRateQm[table_index];
  // Threshold bitrate for resolution action.
  return static_cast<float>(scale_fac * scaleTransRate * max_rate);
}

void VCMQmResolution::UpdateDownsamplingState(UpDownAction up_down) {
  if (up_down == kUpResolution) {
    qm_->spatial_width_fact = 1.0f / kFactorWidthSpatial[action_.spatial];
    qm_->spatial_height_fact = 1.0f / kFactorHeightSpatial[action_.spatial];
    // If last spatial action was 1/2x1/2, we undo it in two steps, so the
    // spatial scale factor in this first step is modified as (4.0/3.0 / 2.0).
    if (action_.spatial == kOneQuarterSpatialUniform) {
      qm_->spatial_width_fact = 1.0f *
                                kFactorWidthSpatial[kOneHalfSpatialUniform] /
                                kFactorWidthSpatial[kOneQuarterSpatialUniform];
      qm_->spatial_height_fact =
          1.0f * kFactorHeightSpatial[kOneHalfSpatialUniform] /
          kFactorHeightSpatial[kOneQuarterSpatialUniform];
    }
    qm_->temporal_fact = 1.0f / kFactorTemporal[action_.temporal];
    RemoveLastDownAction();
  } else if (up_down == kDownResolution) {
    ConstrainAmountOfDownSampling();
    ConvertSpatialFractionalToWhole();
    qm_->spatial_width_fact = kFactorWidthSpatial[action_.spatial];
    qm_->spatial_height_fact = kFactorHeightSpatial[action_.spatial];
    qm_->temporal_fact = kFactorTemporal[action_.temporal];
    InsertLatestDownAction();
  } else {
    // This function should only be called if either the Up or Down action
    // has been selected.
    assert(false);
  }
  UpdateCodecResolution();
  state_dec_factor_spatial_ = state_dec_factor_spatial_ *
                              qm_->spatial_width_fact *
                              qm_->spatial_height_fact;
  state_dec_factor_temporal_ = state_dec_factor_temporal_ * qm_->temporal_fact;
}

void VCMQmResolution::UpdateCodecResolution() {
  if (action_.spatial != kNoChangeSpatial) {
    qm_->change_resolution_spatial = true;
    qm_->codec_width =
        static_cast<uint16_t>(width_ / qm_->spatial_width_fact + 0.5f);
    qm_->codec_height =
        static_cast<uint16_t>(height_ / qm_->spatial_height_fact + 0.5f);
    // Size should not exceed native sizes.
    assert(qm_->codec_width <= native_width_);
    assert(qm_->codec_height <= native_height_);
    // New sizes should be multiple of 2, otherwise spatial should not have
    // been selected.
    assert(qm_->codec_width % 2 == 0);
    assert(qm_->codec_height % 2 == 0);
  }
  if (action_.temporal != kNoChangeTemporal) {
    qm_->change_resolution_temporal = true;
    // Update the frame rate based on the average incoming frame rate.
    qm_->frame_rate = avg_incoming_framerate_ / qm_->temporal_fact + 0.5f;
    if (down_action_history_[0].temporal == 0) {
      // When we undo the last temporal-down action, make sure we go back up
      // to the native frame rate. Since the incoming frame rate may
      // fluctuate over time, |avg_incoming_framerate_| scaled back up may
      // be smaller than |native_frame rate_|.
      qm_->frame_rate = native_frame_rate_;
    }
  }
}

uint8_t VCMQmResolution::RateClass(float transition_rate) {
  return avg_target_rate_ < (kFacLowRate * transition_rate)
             ? 0
             : (avg_target_rate_ >= transition_rate ? 2 : 1);
}

// TODO(marpan): Would be better to capture these frame rate adjustments by
// extending the table data (qm_select_data.h).
void VCMQmResolution::AdjustAction() {
  // If the spatial level is default state (neither low or high), motion level
  // is not high, and spatial action was selected, switch to 2/3 frame rate
  // reduction if the average incoming frame rate is high.
  if (spatial_.level == kDefault && motion_.level != kHigh &&
      action_.spatial != kNoChangeSpatial &&
      framerate_level_ == kFrameRateHigh) {
    action_.spatial = kNoChangeSpatial;
    action_.temporal = kTwoThirdsTemporal;
  }
  // If both motion and spatial level are low, and temporal down action was
  // selected, switch to spatial 3/4x3/4 if the frame rate is not above the
  // lower middle level (|kFrameRateMiddle1|).
  if (motion_.level == kLow && spatial_.level == kLow &&
      framerate_level_ <= kFrameRateMiddle1 &&
      action_.temporal != kNoChangeTemporal) {
    action_.spatial = kOneHalfSpatialUniform;
    action_.temporal = kNoChangeTemporal;
  }
  // If spatial action is selected, and there has been too much spatial
  // reduction already (i.e., 1/4), then switch to temporal action if the
  // average frame rate is not low.
  if (action_.spatial != kNoChangeSpatial &&
      down_action_history_[0].spatial == kOneQuarterSpatialUniform &&
      framerate_level_ != kFrameRateLow) {
    action_.spatial = kNoChangeSpatial;
    action_.temporal = kTwoThirdsTemporal;
  }
  // Never use temporal action if number of temporal layers is above 2.
  if (num_layers_ > 2) {
    if (action_.temporal != kNoChangeTemporal) {
      action_.spatial = kOneHalfSpatialUniform;
    }
    action_.temporal = kNoChangeTemporal;
  }
  // If spatial action was selected, we need to make sure the frame sizes
  // are multiples of two. Otherwise switch to 2/3 temporal.
  if (action_.spatial != kNoChangeSpatial && !EvenFrameSize()) {
    action_.spatial = kNoChangeSpatial;
    // Only one action (spatial or temporal) is allowed at a given time, so need
    // to check whether temporal action is currently selected.
    action_.temporal = kTwoThirdsTemporal;
  }
}

void VCMQmResolution::ConvertSpatialFractionalToWhole() {
  // If 3/4 spatial is selected, check if there has been another 3/4,
  // and if so, combine them into 1/2. 1/2 scaling is more efficient than 9/16.
  // Note we define 3/4x3/4 spatial as kOneHalfSpatialUniform.
  if (action_.spatial == kOneHalfSpatialUniform) {
    bool found = false;
    int isel = kDownActionHistorySize;
    for (int i = 0; i < kDownActionHistorySize; ++i) {
      if (down_action_history_[i].spatial == kOneHalfSpatialUniform) {
        isel = i;
        found = true;
        break;
      }
    }
    if (found) {
      action_.spatial = kOneQuarterSpatialUniform;
      state_dec_factor_spatial_ =
          state_dec_factor_spatial_ /
          (kFactorWidthSpatial[kOneHalfSpatialUniform] *
           kFactorHeightSpatial[kOneHalfSpatialUniform]);
      // Check if switching to 1/2x1/2 (=1/4) spatial is allowed.
      ConstrainAmountOfDownSampling();
      if (action_.spatial == kNoChangeSpatial) {
        // Not allowed. Go back to 3/4x3/4 spatial.
        action_.spatial = kOneHalfSpatialUniform;
        state_dec_factor_spatial_ =
            state_dec_factor_spatial_ *
            kFactorWidthSpatial[kOneHalfSpatialUniform] *
            kFactorHeightSpatial[kOneHalfSpatialUniform];
      } else {
        // Switching is allowed. Remove 3/4x3/4 from the history, and update
        // the frame size.
        for (int i = isel; i < kDownActionHistorySize - 1; ++i) {
          down_action_history_[i].spatial = down_action_history_[i + 1].spatial;
        }
        width_ = width_ * kFactorWidthSpatial[kOneHalfSpatialUniform];
        height_ = height_ * kFactorHeightSpatial[kOneHalfSpatialUniform];
      }
    }
  }
}

// Returns false if the new frame sizes, under the current spatial action,
// are not multiples of two.
bool VCMQmResolution::EvenFrameSize() {
  if (action_.spatial == kOneHalfSpatialUniform) {
    if ((width_ * 3 / 4) % 2 != 0 || (height_ * 3 / 4) % 2 != 0) {
      return false;
    }
  } else if (action_.spatial == kOneQuarterSpatialUniform) {
    if ((width_ * 1 / 2) % 2 != 0 || (height_ * 1 / 2) % 2 != 0) {
      return false;
    }
  }
  return true;
}

void VCMQmResolution::InsertLatestDownAction() {
  if (action_.spatial != kNoChangeSpatial) {
    for (int i = kDownActionHistorySize - 1; i > 0; --i) {
      down_action_history_[i].spatial = down_action_history_[i - 1].spatial;
    }
    down_action_history_[0].spatial = action_.spatial;
  }
  if (action_.temporal != kNoChangeTemporal) {
    for (int i = kDownActionHistorySize - 1; i > 0; --i) {
      down_action_history_[i].temporal = down_action_history_[i - 1].temporal;
    }
    down_action_history_[0].temporal = action_.temporal;
  }
}

void VCMQmResolution::RemoveLastDownAction() {
  if (action_.spatial != kNoChangeSpatial) {
    // If the last spatial action was 1/2x1/2 we replace it with 3/4x3/4.
    if (action_.spatial == kOneQuarterSpatialUniform) {
      down_action_history_[0].spatial = kOneHalfSpatialUniform;
    } else {
      for (int i = 0; i < kDownActionHistorySize - 1; ++i) {
        down_action_history_[i].spatial = down_action_history_[i + 1].spatial;
      }
      down_action_history_[kDownActionHistorySize - 1].spatial =
          kNoChangeSpatial;
    }
  }
  if (action_.temporal != kNoChangeTemporal) {
    for (int i = 0; i < kDownActionHistorySize - 1; ++i) {
      down_action_history_[i].temporal = down_action_history_[i + 1].temporal;
    }
    down_action_history_[kDownActionHistorySize - 1].temporal =
        kNoChangeTemporal;
  }
}

void VCMQmResolution::ConstrainAmountOfDownSampling() {
  // Sanity checks on down-sampling selection:
  // override the settings for too small image size and/or frame rate.
  // Also check the limit on current down-sampling states.

  float spatial_width_fact = kFactorWidthSpatial[action_.spatial];
  float spatial_height_fact = kFactorHeightSpatial[action_.spatial];
  float temporal_fact = kFactorTemporal[action_.temporal];
  float new_dec_factor_spatial =
      state_dec_factor_spatial_ * spatial_width_fact * spatial_height_fact;
  float new_dec_factor_temp = state_dec_factor_temporal_ * temporal_fact;

  // No spatial sampling if current frame size is too small, or if the
  // amount of spatial down-sampling is above maximum spatial down-action.
  if ((width_ * height_) <= kMinImageSize ||
      new_dec_factor_spatial > kMaxSpatialDown) {
    action_.spatial = kNoChangeSpatial;
    new_dec_factor_spatial = state_dec_factor_spatial_;
  }
  // No frame rate reduction if average frame rate is below some point, or if
  // the amount of temporal down-sampling is above maximum temporal down-action.
  if (avg_incoming_framerate_ <= kMinFrameRate ||
      new_dec_factor_temp > kMaxTempDown) {
    action_.temporal = kNoChangeTemporal;
    new_dec_factor_temp = state_dec_factor_temporal_;
  }
  // Check if the total (spatial-temporal) down-action is above maximum allowed,
  // if so, disallow the current selected down-action.
  if (new_dec_factor_spatial * new_dec_factor_temp > kMaxTotalDown) {
    if (action_.spatial != kNoChangeSpatial) {
      action_.spatial = kNoChangeSpatial;
    } else if (action_.temporal != kNoChangeTemporal) {
      action_.temporal = kNoChangeTemporal;
    } else {
      // We only allow for one action (spatial or temporal) at a given time, so
      // either spatial or temporal action is selected when this function is
      // called. If the selected action is disallowed from one of the above
      // 2 prior conditions (on spatial & temporal max down-action), then this
      // condition "total down-action > |kMaxTotalDown|" would not be entered.
      assert(false);
    }
  }
}

void VCMQmResolution::PickSpatialOrTemporal() {
  // Pick the one that has had the most down-sampling thus far.
  if (state_dec_factor_spatial_ > state_dec_factor_temporal_) {
    action_.spatial = down_action_history_[0].spatial;
    action_.temporal = kNoChangeTemporal;
  } else {
    action_.spatial = kNoChangeSpatial;
    action_.temporal = down_action_history_[0].temporal;
  }
}

// TODO(marpan): Update when we allow for directional spatial down-sampling.
void VCMQmResolution::SelectSpatialDirectionMode(float transition_rate) {
  // Default is 4/3x4/3
  // For bit rates well below transitional rate, we select 2x2.
  if (avg_target_rate_ < transition_rate * kRateRedSpatial2X2) {
    qm_->spatial_width_fact = 2.0f;
    qm_->spatial_height_fact = 2.0f;
  }
  // Otherwise check prediction errors and aspect ratio.
  float spatial_err = 0.0f;
  float spatial_err_h = 0.0f;
  float spatial_err_v = 0.0f;
  if (content_metrics_) {
    spatial_err = content_metrics_->spatial_pred_err;
    spatial_err_h = content_metrics_->spatial_pred_err_h;
    spatial_err_v = content_metrics_->spatial_pred_err_v;
  }

  // Favor 1x2 if aspect_ratio is 16:9.
  if (aspect_ratio_ >= 16.0f / 9.0f) {
    // Check if 1x2 has lowest prediction error.
    if (spatial_err_h < spatial_err && spatial_err_h < spatial_err_v) {
      qm_->spatial_width_fact = 2.0f;
      qm_->spatial_height_fact = 1.0f;
    }
  }
  // Check for 4/3x4/3 selection: favor 2x2 over 1x2 and 2x1.
  if (spatial_err < spatial_err_h * (1.0f + kSpatialErr2x2VsHoriz) &&
      spatial_err < spatial_err_v * (1.0f + kSpatialErr2X2VsVert)) {
    qm_->spatial_width_fact = 4.0f / 3.0f;
    qm_->spatial_height_fact = 4.0f / 3.0f;
  }
  // Check for 2x1 selection.
  if (spatial_err_v < spatial_err_h * (1.0f - kSpatialErrVertVsHoriz) &&
      spatial_err_v < spatial_err * (1.0f - kSpatialErr2X2VsVert)) {
    qm_->spatial_width_fact = 1.0f;
    qm_->spatial_height_fact = 2.0f;
  }
}

// ROBUSTNESS CLASS

VCMQmRobustness::VCMQmRobustness() {
  Reset();
}

VCMQmRobustness::~VCMQmRobustness() {}

void VCMQmRobustness::Reset() {
  prev_total_rate_ = 0.0f;
  prev_rtt_time_ = 0;
  prev_packet_loss_ = 0;
  prev_code_rate_delta_ = 0;
  ResetQM();
}

// Adjust the FEC rate based on the content and the network state
// (packet loss rate, total rate/bandwidth, round trip time).
// Note that packetLoss here is the filtered loss value.
float VCMQmRobustness::AdjustFecFactor(uint8_t code_rate_delta,
                                       float total_rate,
                                       float framerate,
                                       int64_t rtt_time,
                                       uint8_t packet_loss) {
  // Default: no adjustment
  float adjust_fec = 1.0f;
  if (content_metrics_ == NULL) {
    return adjust_fec;
  }
  // Compute class state of the content.
  ComputeMotionNFD();
  ComputeSpatial();

  // TODO(marpan): Set FEC adjustment factor.

  // Keep track of previous values of network state:
  // adjustment may be also based on pattern of changes in network state.
  prev_total_rate_ = total_rate;
  prev_rtt_time_ = rtt_time;
  prev_packet_loss_ = packet_loss;
  prev_code_rate_delta_ = code_rate_delta;
  return adjust_fec;
}

// Set the UEP (unequal-protection across packets) on/off for the FEC.
bool VCMQmRobustness::SetUepProtection(uint8_t code_rate_delta,
                                       float total_rate,
                                       uint8_t packet_loss,
                                       bool frame_type) {
  // Default.
  return false;
}
}  // namespace webrtc
