/*
 *  Copyright (c) 2011 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_processing/deflickering.h"

#include <math.h>
#include <stdlib.h>

#include "webrtc/base/logging.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/system_wrappers/include/sort.h"

namespace webrtc {

// Detection constants
// (Q4) Maximum allowed deviation for detection.
enum { kFrequencyDeviation = 39 };
// (Q4) Minimum frequency that can be detected.
enum { kMinFrequencyToDetect = 32 };
// Number of flickers before we accept detection
enum { kNumFlickerBeforeDetect = 2 };
enum { kmean_valueScaling = 4 };  // (Q4) In power of 2
// Dead-zone region in terms of pixel values
enum { kZeroCrossingDeadzone = 10 };
// Deflickering constants.
// Compute the quantiles over 1 / DownsamplingFactor of the image.
enum { kDownsamplingFactor = 8 };
enum { kLog2OfDownsamplingFactor = 3 };

// To generate in Matlab:
// >> probUW16 = round(2^11 *
//     [0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.95,0.97]);
// >> fprintf('%d, ', probUW16)
// Resolution reduced to avoid overflow when multiplying with the
// (potentially) large number of pixels.
const uint16_t VPMDeflickering::prob_uw16_[kNumProbs] = {
    102,  205,  410,  614,  819,  1024,
    1229, 1434, 1638, 1843, 1946, 1987};  // <Q11>

// To generate in Matlab:
// >> numQuants = 14; maxOnlyLength = 5;
// >> weightUW16 = round(2^15 *
//    [linspace(0.5, 1.0, numQuants - maxOnlyLength)]);
// >> fprintf('%d, %d,\n ', weightUW16);
const uint16_t VPMDeflickering::weight_uw16_[kNumQuants - kMaxOnlyLength] = {
    16384, 18432, 20480, 22528, 24576, 26624, 28672, 30720, 32768};  // <Q15>

VPMDeflickering::VPMDeflickering() {
  Reset();
}

VPMDeflickering::~VPMDeflickering() {}

void VPMDeflickering::Reset() {
  mean_buffer_length_ = 0;
  detection_state_ = 0;
  frame_rate_ = 0;

  memset(mean_buffer_, 0, sizeof(int32_t) * kMeanBufferLength);
  memset(timestamp_buffer_, 0, sizeof(int32_t) * kMeanBufferLength);

  // Initialize the history with a uniformly distributed histogram.
  quant_hist_uw8_[0][0] = 0;
  quant_hist_uw8_[0][kNumQuants - 1] = 255;
  for (int32_t i = 0; i < kNumProbs; i++) {
    // Unsigned round. <Q0>
    quant_hist_uw8_[0][i + 1] =
        static_cast<uint8_t>((prob_uw16_[i] * 255 + (1 << 10)) >> 11);
  }

  for (int32_t i = 1; i < kFrameHistory_size; i++) {
    memcpy(quant_hist_uw8_[i], quant_hist_uw8_[0],
           sizeof(uint8_t) * kNumQuants);
  }
}

int32_t VPMDeflickering::ProcessFrame(VideoFrame* frame,
                                      VideoProcessing::FrameStats* stats) {
  assert(frame);
  uint32_t frame_memory;
  uint8_t quant_uw8[kNumQuants];
  uint8_t maxquant_uw8[kNumQuants];
  uint8_t minquant_uw8[kNumQuants];
  uint16_t target_quant_uw16[kNumQuants];
  uint16_t increment_uw16;
  uint8_t map_uw8[256];

  uint16_t tmp_uw16;
  uint32_t tmp_uw32;
  int width = frame->width();
  int height = frame->height();

  if (frame->IsZeroSize()) {
    return VPM_GENERAL_ERROR;
  }

  // Stricter height check due to subsampling size calculation below.
  if (height < 2) {
    LOG(LS_ERROR) << "Invalid frame size.";
    return VPM_GENERAL_ERROR;
  }

  if (!VideoProcessing::ValidFrameStats(*stats)) {
    return VPM_GENERAL_ERROR;
  }

  if (PreDetection(frame->timestamp(), *stats) == -1)
    return VPM_GENERAL_ERROR;

  // Flicker detection
  int32_t det_flicker = DetectFlicker();
  if (det_flicker < 0) {
    return VPM_GENERAL_ERROR;
  } else if (det_flicker != 1) {
    return 0;
  }

  // Size of luminance component.
  const uint32_t y_size = height * width;

  const uint32_t y_sub_size =
      width * (((height - 1) >> kLog2OfDownsamplingFactor) + 1);
  uint8_t* y_sorted = new uint8_t[y_sub_size];
  uint32_t sort_row_idx = 0;
  for (int i = 0; i < height; i += kDownsamplingFactor) {
    memcpy(y_sorted + sort_row_idx * width, frame->buffer(kYPlane) + i * width,
           width);
    sort_row_idx++;
  }

  webrtc::Sort(y_sorted, y_sub_size, webrtc::TYPE_UWord8);

  uint32_t prob_idx_uw32 = 0;
  quant_uw8[0] = 0;
  quant_uw8[kNumQuants - 1] = 255;

  // Ensure we won't get an overflow below.
  // In practice, the number of subsampled pixels will not become this large.
  if (y_sub_size > (1 << 21) - 1) {
    LOG(LS_ERROR) << "Subsampled number of pixels too large.";
    return -1;
  }

  for (int32_t i = 0; i < kNumProbs; i++) {
    // <Q0>.
    prob_idx_uw32 = WEBRTC_SPL_UMUL_32_16(y_sub_size, prob_uw16_[i]) >> 11;
    quant_uw8[i + 1] = y_sorted[prob_idx_uw32];
  }

  delete[] y_sorted;
  y_sorted = NULL;

  // Shift history for new frame.
  memmove(quant_hist_uw8_[1], quant_hist_uw8_[0],
          (kFrameHistory_size - 1) * kNumQuants * sizeof(uint8_t));
  // Store current frame in history.
  memcpy(quant_hist_uw8_[0], quant_uw8, kNumQuants * sizeof(uint8_t));

  // We use a frame memory equal to the ceiling of half the frame rate to
  // ensure we capture an entire period of flicker.
  frame_memory = (frame_rate_ + (1 << 5)) >> 5;  // Unsigned ceiling. <Q0>
                                                 // frame_rate_ in Q4.
  if (frame_memory > kFrameHistory_size) {
    frame_memory = kFrameHistory_size;
  }

  // Get maximum and minimum.
  for (int32_t i = 0; i < kNumQuants; i++) {
    maxquant_uw8[i] = 0;
    minquant_uw8[i] = 255;
    for (uint32_t j = 0; j < frame_memory; j++) {
      if (quant_hist_uw8_[j][i] > maxquant_uw8[i]) {
        maxquant_uw8[i] = quant_hist_uw8_[j][i];
      }

      if (quant_hist_uw8_[j][i] < minquant_uw8[i]) {
        minquant_uw8[i] = quant_hist_uw8_[j][i];
      }
    }
  }

  // Get target quantiles.
  for (int32_t i = 0; i < kNumQuants - kMaxOnlyLength; i++) {
    // target = w * maxquant_uw8 + (1 - w) * minquant_uw8
    // Weights w = |weight_uw16_| are in Q15, hence the final output has to be
    // right shifted by 8 to end up in Q7.
    target_quant_uw16[i] = static_cast<uint16_t>(
        (weight_uw16_[i] * maxquant_uw8[i] +
         ((1 << 15) - weight_uw16_[i]) * minquant_uw8[i]) >>
        8);  // <Q7>
  }

  for (int32_t i = kNumQuants - kMaxOnlyLength; i < kNumQuants; i++) {
    target_quant_uw16[i] = ((uint16_t)maxquant_uw8[i]) << 7;
  }

  // Compute the map from input to output pixels.
  uint16_t mapUW16;  // <Q7>
  for (int32_t i = 1; i < kNumQuants; i++) {
    // As quant and targetQuant are limited to UWord8, it's safe to use Q7 here.
    tmp_uw32 =
        static_cast<uint32_t>(target_quant_uw16[i] - target_quant_uw16[i - 1]);
    tmp_uw16 = static_cast<uint16_t>(quant_uw8[i] - quant_uw8[i - 1]);  // <Q0>

    if (tmp_uw16 > 0) {
      increment_uw16 =
          static_cast<uint16_t>(WebRtcSpl_DivU32U16(tmp_uw32,
                                                    tmp_uw16));  // <Q7>
    } else {
      // The value is irrelevant; the loop below will only iterate once.
      increment_uw16 = 0;
    }

    mapUW16 = target_quant_uw16[i - 1];
    for (uint32_t j = quant_uw8[i - 1]; j < (uint32_t)(quant_uw8[i] + 1); j++) {
      // Unsigned round. <Q0>
      map_uw8[j] = (uint8_t)((mapUW16 + (1 << 6)) >> 7);
      mapUW16 += increment_uw16;
    }
  }

  // Map to the output frame.
  uint8_t* buffer = frame->buffer(kYPlane);
  for (uint32_t i = 0; i < y_size; i++) {
    buffer[i] = map_uw8[buffer[i]];
  }

  // Frame was altered, so reset stats.
  VideoProcessing::ClearFrameStats(stats);

  return VPM_OK;
}

/**
   Performs some pre-detection operations. Must be called before
   DetectFlicker().

   \param[in] timestamp Timestamp of the current frame.
   \param[in] stats     Statistics of the current frame.

   \return 0: Success\n
           2: Detection not possible due to flickering frequency too close to
              zero.\n
          -1: Error
*/
int32_t VPMDeflickering::PreDetection(
    const uint32_t timestamp,
    const VideoProcessing::FrameStats& stats) {
  int32_t mean_val;  // Mean value of frame (Q4)
  uint32_t frame_rate = 0;
  int32_t meanBufferLength;  // Temp variable.

  mean_val = ((stats.sum << kmean_valueScaling) / stats.num_pixels);
  // Update mean value buffer.
  // This should be done even though we might end up in an unreliable detection.
  memmove(mean_buffer_ + 1, mean_buffer_,
          (kMeanBufferLength - 1) * sizeof(int32_t));
  mean_buffer_[0] = mean_val;

  // Update timestamp buffer.
  // This should be done even though we might end up in an unreliable detection.
  memmove(timestamp_buffer_ + 1, timestamp_buffer_,
          (kMeanBufferLength - 1) * sizeof(uint32_t));
  timestamp_buffer_[0] = timestamp;

  /* Compute current frame rate (Q4) */
  if (timestamp_buffer_[kMeanBufferLength - 1] != 0) {
    frame_rate = ((90000 << 4) * (kMeanBufferLength - 1));
    frame_rate /=
        (timestamp_buffer_[0] - timestamp_buffer_[kMeanBufferLength - 1]);
  } else if (timestamp_buffer_[1] != 0) {
    frame_rate = (90000 << 4) / (timestamp_buffer_[0] - timestamp_buffer_[1]);
  }

  /* Determine required size of mean value buffer (mean_buffer_length_) */
  if (frame_rate == 0) {
    meanBufferLength = 1;
  } else {
    meanBufferLength =
        (kNumFlickerBeforeDetect * frame_rate) / kMinFrequencyToDetect;
  }
  /* Sanity check of buffer length */
  if (meanBufferLength >= kMeanBufferLength) {
    /* Too long buffer. The flickering frequency is too close to zero, which
     * makes the estimation unreliable.
     */
    mean_buffer_length_ = 0;
    return 2;
  }
  mean_buffer_length_ = meanBufferLength;

  if ((timestamp_buffer_[mean_buffer_length_ - 1] != 0) &&
      (mean_buffer_length_ != 1)) {
    frame_rate = ((90000 << 4) * (mean_buffer_length_ - 1));
    frame_rate /=
        (timestamp_buffer_[0] - timestamp_buffer_[mean_buffer_length_ - 1]);
  } else if (timestamp_buffer_[1] != 0) {
    frame_rate = (90000 << 4) / (timestamp_buffer_[0] - timestamp_buffer_[1]);
  }
  frame_rate_ = frame_rate;

  return VPM_OK;
}

/**
   This function detects flicker in the video stream. As a side effect the
   mean value buffer is updated with the new mean value.

   \return 0: No flickering detected\n
           1: Flickering detected\n
           2: Detection not possible due to unreliable frequency interval
          -1: Error
*/
int32_t VPMDeflickering::DetectFlicker() {
  uint32_t i;
  int32_t freqEst;  // (Q4) Frequency estimate to base detection upon
  int32_t ret_val = -1;

  /* Sanity check for mean_buffer_length_ */
  if (mean_buffer_length_ < 2) {
    /* Not possible to estimate frequency */
    return 2;
  }
  // Count zero crossings with a dead zone to be robust against noise. If the
  // noise std is 2 pixel this corresponds to about 95% confidence interval.
  int32_t deadzone = (kZeroCrossingDeadzone << kmean_valueScaling);  // Q4
  int32_t meanOfBuffer = 0;  // Mean value of mean value buffer.
  int32_t numZeros = 0;      // Number of zeros that cross the dead-zone.
  int32_t cntState = 0;      // State variable for zero crossing regions.
  int32_t cntStateOld = 0;   // Previous state for zero crossing regions.

  for (i = 0; i < mean_buffer_length_; i++) {
    meanOfBuffer += mean_buffer_[i];
  }
  meanOfBuffer += (mean_buffer_length_ >> 1);  // Rounding, not truncation.
  meanOfBuffer /= mean_buffer_length_;

  // Count zero crossings.
  cntStateOld = (mean_buffer_[0] >= (meanOfBuffer + deadzone));
  cntStateOld -= (mean_buffer_[0] <= (meanOfBuffer - deadzone));
  for (i = 1; i < mean_buffer_length_; i++) {
    cntState = (mean_buffer_[i] >= (meanOfBuffer + deadzone));
    cntState -= (mean_buffer_[i] <= (meanOfBuffer - deadzone));
    if (cntStateOld == 0) {
      cntStateOld = -cntState;
    }
    if (((cntState + cntStateOld) == 0) && (cntState != 0)) {
      numZeros++;
      cntStateOld = cntState;
    }
  }
  // END count zero crossings.

  /* Frequency estimation according to:
  * freqEst = numZeros * frame_rate / 2 / mean_buffer_length_;
  *
  * Resolution is set to Q4
  */
  freqEst = ((numZeros * 90000) << 3);
  freqEst /=
      (timestamp_buffer_[0] - timestamp_buffer_[mean_buffer_length_ - 1]);

  /* Translate frequency estimate to regions close to 100 and 120 Hz */
  uint8_t freqState = 0;  // Current translation state;
                          // (0) Not in interval,
                          // (1) Within valid interval,
                          // (2) Out of range
  int32_t freqAlias = freqEst;
  if (freqEst > kMinFrequencyToDetect) {
    uint8_t aliasState = 1;
    while (freqState == 0) {
      /* Increase frequency */
      freqAlias += (aliasState * frame_rate_);
      freqAlias += ((freqEst << 1) * (1 - (aliasState << 1)));
      /* Compute state */
      freqState = (abs(freqAlias - (100 << 4)) <= kFrequencyDeviation);
      freqState += (abs(freqAlias - (120 << 4)) <= kFrequencyDeviation);
      freqState += 2 * (freqAlias > ((120 << 4) + kFrequencyDeviation));
      /* Switch alias state */
      aliasState++;
      aliasState &= 0x01;
    }
  }
  /* Is frequency estimate within detection region? */
  if (freqState == 1) {
    ret_val = 1;
  } else if (freqState == 0) {
    ret_val = 2;
  } else {
    ret_val = 0;
  }
  return ret_val;
}

}  // namespace webrtc
