/*
 *  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/content_metrics_processing.h"

#include <math.h>

#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/video_coding/include/video_coding_defines.h"

namespace webrtc {
//////////////////////////////////
/// VCMContentMetricsProcessing //
//////////////////////////////////

VCMContentMetricsProcessing::VCMContentMetricsProcessing()
    : recursive_avg_factor_(1 / 150.0f),  // matched to  30fps.
      frame_cnt_uniform_avg_(0),
      avg_motion_level_(0.0f),
      avg_spatial_level_(0.0f) {
  recursive_avg_ = new VideoContentMetrics();
  uniform_avg_ = new VideoContentMetrics();
}

VCMContentMetricsProcessing::~VCMContentMetricsProcessing() {
  delete recursive_avg_;
  delete uniform_avg_;
}

int VCMContentMetricsProcessing::Reset() {
  recursive_avg_->Reset();
  uniform_avg_->Reset();
  frame_cnt_uniform_avg_ = 0;
  avg_motion_level_ = 0.0f;
  avg_spatial_level_ = 0.0f;
  return VCM_OK;
}

void VCMContentMetricsProcessing::UpdateFrameRate(uint32_t frameRate) {
  if (frameRate == 0)
    frameRate = 1;
  // Update factor for recursive averaging.
  recursive_avg_factor_ = static_cast<float>(1000.0f) /
                          static_cast<float>(frameRate * kQmMinIntervalMs);
}

VideoContentMetrics* VCMContentMetricsProcessing::LongTermAvgData() {
  return recursive_avg_;
}

VideoContentMetrics* VCMContentMetricsProcessing::ShortTermAvgData() {
  if (frame_cnt_uniform_avg_ == 0) {
    return NULL;
  }
  // Two metrics are used: motion and spatial level.
  uniform_avg_->motion_magnitude =
      avg_motion_level_ / static_cast<float>(frame_cnt_uniform_avg_);
  uniform_avg_->spatial_pred_err =
      avg_spatial_level_ / static_cast<float>(frame_cnt_uniform_avg_);
  return uniform_avg_;
}

void VCMContentMetricsProcessing::ResetShortTermAvgData() {
  // Reset.
  avg_motion_level_ = 0.0f;
  avg_spatial_level_ = 0.0f;
  frame_cnt_uniform_avg_ = 0;
}

int VCMContentMetricsProcessing::UpdateContentData(
    const VideoContentMetrics* contentMetrics) {
  if (contentMetrics == NULL) {
    return VCM_OK;
  }
  return ProcessContent(contentMetrics);
}

int VCMContentMetricsProcessing::ProcessContent(
    const VideoContentMetrics* contentMetrics) {
  // Update the recursive averaged metrics: average is over longer window
  // of time: over QmMinIntervalMs ms.
  UpdateRecursiveAvg(contentMetrics);
  // Update the uniform averaged metrics: average is over shorter window
  // of time: based on ~RTCP reports.
  UpdateUniformAvg(contentMetrics);
  return VCM_OK;
}

void VCMContentMetricsProcessing::UpdateUniformAvg(
    const VideoContentMetrics* contentMetrics) {
  // Update frame counter.
  frame_cnt_uniform_avg_ += 1;
  // Update averaged metrics: motion and spatial level are used.
  avg_motion_level_ += contentMetrics->motion_magnitude;
  avg_spatial_level_ += contentMetrics->spatial_pred_err;
  return;
}

void VCMContentMetricsProcessing::UpdateRecursiveAvg(
    const VideoContentMetrics* contentMetrics) {
  // Spatial metrics: 2x2, 1x2(H), 2x1(V).
  recursive_avg_->spatial_pred_err =
      (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err +
      recursive_avg_factor_ * contentMetrics->spatial_pred_err;

  recursive_avg_->spatial_pred_err_h =
      (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_h +
      recursive_avg_factor_ * contentMetrics->spatial_pred_err_h;

  recursive_avg_->spatial_pred_err_v =
      (1 - recursive_avg_factor_) * recursive_avg_->spatial_pred_err_v +
      recursive_avg_factor_ * contentMetrics->spatial_pred_err_v;

  // Motion metric: Derived from NFD (normalized frame difference).
  recursive_avg_->motion_magnitude =
      (1 - recursive_avg_factor_) * recursive_avg_->motion_magnitude +
      recursive_avg_factor_ * contentMetrics->motion_magnitude;
}
}  // namespace webrtc
