/*
 *  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/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,
    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
