/*
 *  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_processing/test/video_processing_unittest.h"

#include <gflags/gflags.h>

#include <memory>
#include <string>

#include "webrtc/base/keep_ref_until_done.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace webrtc {

namespace {

// Define command line flag 'gen_files' (default value: false).
DEFINE_bool(gen_files, false, "Output files for visual inspection.");

}  // namespace

static void PreprocessFrameAndVerify(const VideoFrame& source,
                                     int target_width,
                                     int target_height,
                                     VideoProcessing* vpm,
                                     const VideoFrame* out_frame);
rtc::scoped_refptr<VideoFrameBuffer> CropBuffer(
    const rtc::scoped_refptr<VideoFrameBuffer>& source_buffer,
    int source_width,
    int source_height,
    int offset_x,
    int offset_y,
    int cropped_width,
    int cropped_height);
// The |source_data| is cropped and scaled to |target_width| x |target_height|,
// and then scaled back to the expected cropped size. |expected_psnr| is used to
// verify basic quality, and is set to be ~0.1/0.05dB lower than actual PSNR
// verified under the same conditions.
static void TestSize(
    const VideoFrame& source_frame,
    const rtc::scoped_refptr<VideoFrameBuffer>& cropped_source_buffer,
    int target_width,
    int target_height,
    double expected_psnr,
    VideoProcessing* vpm);
static void WriteProcessedFrameForVisualInspection(const VideoFrame& source,
                                                   const VideoFrame& processed);

VideoProcessingTest::VideoProcessingTest()
    : vp_(NULL),
      source_file_(NULL),
      width_(352),
      half_width_((width_ + 1) / 2),
      height_(288),
      size_y_(width_ * height_),
      size_uv_(half_width_ * ((height_ + 1) / 2)),
      frame_length_(CalcBufferSize(kI420, width_, height_)) {}

void VideoProcessingTest::SetUp() {
  vp_ = VideoProcessing::Create();
  ASSERT_TRUE(vp_ != NULL);

  const std::string video_file =
      webrtc::test::ResourcePath("foreman_cif", "yuv");
  source_file_ = fopen(video_file.c_str(), "rb");
  ASSERT_TRUE(source_file_ != NULL)
      << "Cannot read source file: " + video_file + "\n";
}

void VideoProcessingTest::TearDown() {
  if (source_file_ != NULL) {
    ASSERT_EQ(0, fclose(source_file_));
  }
  source_file_ = NULL;
  delete vp_;
  vp_ = NULL;
}

#if defined(WEBRTC_IOS)
TEST_F(VideoProcessingTest, DISABLED_PreprocessorLogic) {
#else
TEST_F(VideoProcessingTest, PreprocessorLogic) {
#endif
  // Disable temporal sampling (frame dropping).
  vp_->EnableTemporalDecimation(false);
  int resolution = 100;
  EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 15));
  EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 30));
  // Disable spatial sampling.
  vp_->SetInputFrameResampleMode(kNoRescaling);
  EXPECT_EQ(VPM_OK, vp_->SetTargetResolution(resolution, resolution, 30));
  VideoFrame* out_frame = NULL;
  // Set rescaling => output frame != NULL.
  vp_->SetInputFrameResampleMode(kFastRescaling);

  rtc::scoped_refptr<webrtc::I420Buffer> buffer =
      I420Buffer::Create(width_, height_, width_, half_width_, half_width_);

  // Clear video frame so DrMemory/Valgrind will allow reads of the buffer.
  buffer->InitializeData();
  VideoFrame video_frame(buffer, 0, 0, webrtc::kVideoRotation_0);

  PreprocessFrameAndVerify(video_frame, resolution, resolution, vp_, out_frame);
  // No rescaling=> output frame = NULL.
  vp_->SetInputFrameResampleMode(kNoRescaling);
  EXPECT_TRUE(vp_->PreprocessFrame(video_frame) != nullptr);
}

#if defined(WEBRTC_IOS)
TEST_F(VideoProcessingTest, DISABLED_Resampler) {
#else
TEST_F(VideoProcessingTest, Resampler) {
#endif
  enum { NumRuns = 1 };

  int64_t min_runtime = 0;
  int64_t total_runtime = 0;

  rewind(source_file_);
  ASSERT_TRUE(source_file_ != NULL) << "Cannot read input file \n";

  // no temporal decimation
  vp_->EnableTemporalDecimation(false);

  // Reading test frame
  rtc::scoped_refptr<webrtc::I420Buffer> buffer =
      I420Buffer::Create(width_, height_, width_, half_width_, half_width_);

  ASSERT_EQ(static_cast<size_t>(size_y_),
            fread(buffer->MutableDataY(), 1, size_y_, source_file_));
  ASSERT_EQ(static_cast<size_t>(size_uv_),
            fread(buffer->MutableDataU(), 1, size_uv_, source_file_));
  ASSERT_EQ(static_cast<size_t>(size_uv_),
            fread(buffer->MutableDataV(), 1, size_uv_, source_file_));

  for (uint32_t run_idx = 0; run_idx < NumRuns; run_idx++) {
    // Initiate test timer.
    const int64_t time_start = rtc::TimeNanos();

    // Init the sourceFrame with a timestamp.
    int64_t time_start_ms = time_start / rtc::kNumNanosecsPerMillisec;
    VideoFrame video_frame(buffer, time_start_ms * 90, time_start_ms,
                           webrtc::kVideoRotation_0);

    // Test scaling to different sizes: source is of |width|/|height| = 352/288.
    // Pure scaling:
    TestSize(video_frame, buffer, width_ / 4, height_ / 4, 25.2, vp_);
    TestSize(video_frame, buffer, width_ / 2, height_ / 2, 28.1, vp_);
    // No resampling:
    TestSize(video_frame, buffer, width_, height_, -1, vp_);
    TestSize(video_frame, buffer, 2 * width_, 2 * height_, 32.2, vp_);

    // Scaling and cropping. The cropped source frame is the largest center
    // aligned region that can be used from the source while preserving aspect
    // ratio.
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 56, 352, 176),
             100, 50, 24.0, vp_);
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 30, 352, 225),
             400, 256, 31.3, vp_);
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 68, 0, 216, 288),
             480, 640, 32.15, vp_);
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 12, 352, 264),
             960, 720, 32.2, vp_);
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 44, 352, 198),
             1280, 720, 32.15, vp_);

    // Upsampling to odd size.
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 26, 352, 233),
             501, 333, 32.05, vp_);
    // Downsample to odd size.
    TestSize(video_frame, CropBuffer(buffer, width_, height_, 0, 34, 352, 219),
             281, 175, 29.3, vp_);

    // Stop timer.
    const int64_t runtime =
        (rtc::TimeNanos() - time_start) / rtc::kNumNanosecsPerMicrosec;
    if (runtime < min_runtime || run_idx == 0) {
      min_runtime = runtime;
    }
    total_runtime += runtime;
  }

  printf("\nAverage run time = %d us / frame\n",
         static_cast<int>(total_runtime));
  printf("Min run time = %d us / frame\n\n", static_cast<int>(min_runtime));
}

void PreprocessFrameAndVerify(const VideoFrame& source,
                              int target_width,
                              int target_height,
                              VideoProcessing* vpm,
                              const VideoFrame* out_frame) {
  ASSERT_EQ(VPM_OK, vpm->SetTargetResolution(target_width, target_height, 30));
  out_frame = vpm->PreprocessFrame(source);
  EXPECT_TRUE(out_frame != nullptr);

  // If no resizing is needed, expect the original frame.
  if (target_width == source.width() && target_height == source.height()) {
    EXPECT_EQ(&source, out_frame);
    return;
  }

  // Verify the resampled frame.
  EXPECT_TRUE(out_frame != NULL);
  EXPECT_EQ(source.render_time_ms(), (out_frame)->render_time_ms());
  EXPECT_EQ(source.timestamp(), (out_frame)->timestamp());
  EXPECT_EQ(target_width, (out_frame)->width());
  EXPECT_EQ(target_height, (out_frame)->height());
}

rtc::scoped_refptr<VideoFrameBuffer> CropBuffer(
    const rtc::scoped_refptr<VideoFrameBuffer>& source_buffer,
    int source_width,
    int source_height,
    int offset_x,
    int offset_y,
    int cropped_width,
    int cropped_height) {
  // Force even.
  offset_x &= 1;
  offset_y &= 1;

  size_t y_start = offset_x + offset_y * source_buffer->StrideY();
  size_t u_start = (offset_x / 2) + (offset_y / 2) * source_buffer->StrideU();
  size_t v_start = (offset_x / 2) + (offset_y / 2) * source_buffer->StrideU();

  return rtc::scoped_refptr<VideoFrameBuffer>(
      new rtc::RefCountedObject<WrappedI420Buffer>(
          cropped_width, cropped_height, source_buffer->DataY() + y_start,
          source_buffer->StrideY(), source_buffer->DataU() + u_start,
          source_buffer->StrideU(), source_buffer->DataV() + v_start,
          source_buffer->StrideV(), rtc::KeepRefUntilDone(source_buffer)));
}

void TestSize(const VideoFrame& source_frame,
              const rtc::scoped_refptr<VideoFrameBuffer>& cropped_source_buffer,
              int target_width,
              int target_height,
              double expected_psnr,
              VideoProcessing* vpm) {
  // Resample source_frame to out_frame.
  VideoFrame* out_frame = NULL;
  vpm->SetInputFrameResampleMode(kBox);
  PreprocessFrameAndVerify(source_frame, target_width, target_height, vpm,
                           out_frame);
  if (out_frame == NULL)
    return;
  WriteProcessedFrameForVisualInspection(source_frame, *out_frame);

  // Scale |resampled_source_frame| back to the source scale.
  VideoFrame resampled_source_frame;
  resampled_source_frame.CopyFrame(*out_frame);
  PreprocessFrameAndVerify(resampled_source_frame,
                           cropped_source_buffer->width(),
                           cropped_source_buffer->height(), vpm, out_frame);
  WriteProcessedFrameForVisualInspection(resampled_source_frame, *out_frame);

  // Compute PSNR against the cropped source frame and check expectation.
  double psnr =
      I420PSNR(*cropped_source_buffer, *out_frame->video_frame_buffer());
  EXPECT_GT(psnr, expected_psnr);
  printf(
      "PSNR: %f. PSNR is between source of size %d %d, and a modified "
      "source which is scaled down/up to: %d %d, and back to source size \n",
      psnr, source_frame.width(), source_frame.height(), target_width,
      target_height);
}

void WriteProcessedFrameForVisualInspection(const VideoFrame& source,
                                            const VideoFrame& processed) {
  // Skip if writing to files is not enabled.
  if (!FLAGS_gen_files)
    return;
  // Write the processed frame to file for visual inspection.
  std::ostringstream filename;
  filename << webrtc::test::OutputPath() << "Resampler_from_" << source.width()
           << "x" << source.height() << "_to_" << processed.width() << "x"
           << processed.height() << "_30Hz_P420.yuv";
  std::cout << "Watch " << filename.str() << " and verify that it is okay."
            << std::endl;
  FILE* stand_alone_file = fopen(filename.str().c_str(), "wb");
  if (PrintVideoFrame(processed, stand_alone_file) < 0)
    std::cerr << "Failed to write: " << filename.str() << std::endl;
  if (stand_alone_file)
    fclose(stand_alone_file);
}

}  // namespace webrtc
