/*
 *  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/main/source/deflickering.h"

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

#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/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,
    VideoProcessingModule::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 (!VideoProcessingModule::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.
  VideoProcessingModule::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 VideoProcessingModule::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
