/*
 *  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/tools/frame_analyzer/video_quality_analysis.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <string>

#define STATS_LINE_LENGTH 32
#define Y4M_FILE_HEADER_MAX_SIZE 200
#define Y4M_FRAME_DELIMITER "FRAME"
#define Y4M_FRAME_HEADER_SIZE 6

namespace webrtc {
namespace test {

using std::string;

ResultsContainer::ResultsContainer() {}
ResultsContainer::~ResultsContainer() {}

int GetI420FrameSize(int width, int height) {
  int half_width = (width + 1) >> 1;
  int half_height = (height + 1) >> 1;

  int y_plane = width * height;  // I420 Y plane.
  int u_plane = half_width * half_height;  // I420 U plane.
  int v_plane = half_width * half_height;  // I420 V plane.

  return y_plane + u_plane + v_plane;
}

int ExtractFrameSequenceNumber(std::string line) {
  size_t space_position = line.find(' ');
  if (space_position == string::npos) {
    return -1;
  }
  std::string frame = line.substr(0, space_position);

  size_t underscore_position = frame.find('_');
  if (underscore_position == string::npos) {
    return -1;
  }
  std::string frame_number = frame.substr(underscore_position + 1);

  return strtol(frame_number.c_str(), NULL, 10);
}

int ExtractDecodedFrameNumber(std::string line) {
  size_t space_position = line.find(' ');
  if (space_position == string::npos) {
    return -1;
  }
  std::string decoded_number = line.substr(space_position + 1);

  return strtol(decoded_number.c_str(), NULL, 10);
}

bool IsThereBarcodeError(std::string line) {
  size_t barcode_error_position = line.find("Barcode error");
  if (barcode_error_position != string::npos) {
    return true;
  }
  return false;
}

bool GetNextStatsLine(FILE* stats_file, char* line) {
  int chars = 0;
  char buf = 0;

  while (buf != '\n') {
    size_t chars_read = fread(&buf, 1, 1, stats_file);
    if (chars_read != 1 || feof(stats_file)) {
      return false;
    }
    line[chars] = buf;
    ++chars;
  }
  line[chars-1] = '\0';  // Strip the trailing \n and put end of string.
  return true;
}

bool ExtractFrameFromYuvFile(const char* i420_file_name,
                             int width,
                             int height,
                             int frame_number,
                             uint8_t* result_frame) {
  int frame_size = GetI420FrameSize(width, height);
  int offset = frame_number * frame_size;  // Calculate offset for the frame.
  bool errors = false;

  FILE* input_file = fopen(i420_file_name, "rb");
  if (input_file == NULL) {
    fprintf(stderr, "Couldn't open input file for reading: %s\n",
            i420_file_name);
    return false;
  }

  // Change stream pointer to new offset.
  fseek(input_file, offset, SEEK_SET);

  size_t bytes_read = fread(result_frame, 1, frame_size, input_file);
  if (bytes_read != static_cast<size_t>(frame_size) &&
      ferror(input_file)) {
    fprintf(stdout, "Error while reading frame no %d from file %s\n",
            frame_number, i420_file_name);
    errors = true;
  }
  fclose(input_file);
  return !errors;
}

bool ExtractFrameFromY4mFile(const char* y4m_file_name,
                             int width,
                             int height,
                             int frame_number,
                             uint8_t* result_frame) {
  int frame_size = GetI420FrameSize(width, height);
  int frame_offset = frame_number * frame_size;
  bool errors = false;

  FILE* input_file = fopen(y4m_file_name, "rb");
  if (input_file == NULL) {
    fprintf(stderr, "Couldn't open input file for reading: %s\n",
            y4m_file_name);
    return false;
  }

  // YUV4MPEG2, a.k.a. Y4M File format has a file header and a frame header. The
  // file header has the aspect: "YUV4MPEG2 C420 W640 H360 Ip F30:1 A1:1".
  // Skip the header if this is the first frame of the file.
  if (frame_number == 0) {
    char frame_header[Y4M_FILE_HEADER_MAX_SIZE];
    size_t bytes_read =
        fread(frame_header, 1, Y4M_FILE_HEADER_MAX_SIZE, input_file);
    if (bytes_read != static_cast<size_t>(frame_size) && ferror(input_file)) {
      fprintf(stdout, "Error while reading first frame from file %s\n",
          y4m_file_name);
      fclose(input_file);
      return false;
    }
    std::string header_contents(frame_header);
    std::size_t found = header_contents.find(Y4M_FRAME_DELIMITER);
    if (found == std::string::npos) {
      fprintf(stdout, "Corrupted Y4M header, could not find \"FRAME\" in %s\n",
          header_contents.c_str());
      fclose(input_file);
      return false;
    }
    frame_offset = static_cast<int>(found);
  }

  // Change stream pointer to new offset, skipping the frame header as well.
  fseek(input_file, frame_offset + Y4M_FRAME_HEADER_SIZE, SEEK_SET);

  size_t bytes_read = fread(result_frame, 1, frame_size, input_file);
  if (bytes_read != static_cast<size_t>(frame_size) &&
      ferror(input_file)) {
    fprintf(stdout, "Error while reading frame no %d from file %s\n",
            frame_number, y4m_file_name);
    errors = true;
  }

  fclose(input_file);
  return !errors;
}

double CalculateMetrics(VideoAnalysisMetricsType video_metrics_type,
                        const uint8_t* ref_frame,
                        const uint8_t* test_frame,
                        int width,
                        int height) {
  if (!ref_frame || !test_frame)
    return -1;
  else if (height < 0 || width < 0)
    return -1;
  int half_width = (width + 1) >> 1;
  int half_height = (height + 1) >> 1;
  const uint8_t* src_y_a = ref_frame;
  const uint8_t* src_u_a = src_y_a + width * height;
  const uint8_t* src_v_a = src_u_a + half_width * half_height;
  const uint8_t* src_y_b = test_frame;
  const uint8_t* src_u_b = src_y_b + width * height;
  const uint8_t* src_v_b = src_u_b + half_width * half_height;

  int stride_y = width;
  int stride_uv = half_width;

  double result = 0.0;

  switch (video_metrics_type) {
    case kPSNR:
      // In the following: stride is determined by width.
      result = libyuv::I420Psnr(src_y_a, width, src_u_a, half_width,
                                src_v_a, half_width, src_y_b, width,
                                src_u_b, half_width, src_v_b, half_width,
                                width, height);
      // LibYuv sets the max psnr value to 128, we restrict it to 48.
      // In case of 0 mse in one frame, 128 can skew the results significantly.
      result = (result > 48.0) ? 48.0 : result;
      break;
    case kSSIM:
      result = libyuv::I420Ssim(src_y_a, stride_y, src_u_a, stride_uv,
                                src_v_a, stride_uv, src_y_b, stride_y,
                                src_u_b, stride_uv, src_v_b, stride_uv,
                                width, height);
      break;
    default:
      assert(false);
  }

  return result;
}

void RunAnalysis(const char* reference_file_name, const char* test_file_name,
                 const char* stats_file_name, int width, int height,
                 ResultsContainer* results) {
  // Check if the reference_file_name ends with "y4m".
  bool y4m_mode = false;
  if (std::string(reference_file_name).find("y4m") != std::string::npos){
    y4m_mode = true;
  }

  int size = GetI420FrameSize(width, height);
  FILE* stats_file = fopen(stats_file_name, "r");

  // String buffer for the lines in the stats file.
  char line[STATS_LINE_LENGTH];

  // Allocate buffers for test and reference frames.
  uint8_t* test_frame = new uint8_t[size];
  uint8_t* reference_frame = new uint8_t[size];
  int previous_frame_number = -1;

  // While there are entries in the stats file.
  while (GetNextStatsLine(stats_file, line)) {
    int extracted_test_frame = ExtractFrameSequenceNumber(line);
    int decoded_frame_number = ExtractDecodedFrameNumber(line);

    // If there was problem decoding the barcode in this frame or the frame has
    // been duplicated, continue.
    if (IsThereBarcodeError(line) ||
        decoded_frame_number == previous_frame_number) {
      continue;
    }

    assert(extracted_test_frame != -1);
    assert(decoded_frame_number != -1);

    ExtractFrameFromYuvFile(test_file_name, width, height, extracted_test_frame,
                            test_frame);
    if (y4m_mode) {
      ExtractFrameFromY4mFile(reference_file_name, width, height,
                              decoded_frame_number, reference_frame);
    } else {
      ExtractFrameFromYuvFile(reference_file_name, width, height,
                              decoded_frame_number, reference_frame);
    }

    // Calculate the PSNR and SSIM.
    double result_psnr = CalculateMetrics(kPSNR, reference_frame, test_frame,
                                          width, height);
    double result_ssim = CalculateMetrics(kSSIM, reference_frame, test_frame,
                                          width, height);

    previous_frame_number = decoded_frame_number;

    // Fill in the result struct.
    AnalysisResult result;
    result.frame_number = decoded_frame_number;
    result.psnr_value = result_psnr;
    result.ssim_value = result_ssim;

    results->frames.push_back(result);
  }

  // Cleanup.
  fclose(stats_file);
  delete[] test_frame;
  delete[] reference_frame;
}

void PrintMaxRepeatedAndSkippedFrames(const std::string& label,
                                      const std::string& stats_file_name) {
  PrintMaxRepeatedAndSkippedFrames(stdout, label, stats_file_name);
}

void PrintMaxRepeatedAndSkippedFrames(FILE* output, const std::string& label,
                                      const std::string& stats_file_name) {
  FILE* stats_file = fopen(stats_file_name.c_str(), "r");
  if (stats_file == NULL) {
    fprintf(stderr, "Couldn't open stats file for reading: %s\n",
            stats_file_name.c_str());
    return;
  }
  char line[STATS_LINE_LENGTH];

  int repeated_frames = 1;
  int max_repeated_frames = 1;
  int max_skipped_frames = 1;
  int previous_frame_number = -1;

  while (GetNextStatsLine(stats_file, line)) {
    int decoded_frame_number = ExtractDecodedFrameNumber(line);

    if (decoded_frame_number == -1) {
      continue;
    }

    // Calculate how many frames a cluster of repeated frames contains.
    if (decoded_frame_number == previous_frame_number) {
      ++repeated_frames;
      if (repeated_frames > max_repeated_frames) {
        max_repeated_frames = repeated_frames;
      }
    } else {
      repeated_frames = 1;
    }

    // Calculate how much frames have been skipped.
    if (decoded_frame_number != 0 && previous_frame_number != -1) {
      int skipped_frames = decoded_frame_number - previous_frame_number - 1;
      if (skipped_frames > max_skipped_frames) {
        max_skipped_frames = skipped_frames;
      }
    }
    previous_frame_number = decoded_frame_number;
  }
  fprintf(output, "RESULT Max_repeated: %s= %d\n", label.c_str(),
          max_repeated_frames);
  fprintf(output, "RESULT Max_skipped: %s= %d\n", label.c_str(),
          max_skipped_frames);
  fclose(stats_file);
}

void PrintAnalysisResults(const std::string& label, ResultsContainer* results) {
  PrintAnalysisResults(stdout, label, results);
}

void PrintAnalysisResults(FILE* output, const std::string& label,
                          ResultsContainer* results) {
  std::vector<AnalysisResult>::iterator iter;

  fprintf(output, "RESULT Unique_frames_count: %s= %u\n", label.c_str(),
          static_cast<unsigned int>(results->frames.size()));

  if (results->frames.size() > 0u) {
    fprintf(output, "RESULT PSNR: %s= [", label.c_str());
    for (iter = results->frames.begin(); iter != results->frames.end() - 1;
         ++iter) {
      fprintf(output, "%f,", iter->psnr_value);
    }
    fprintf(output, "%f] dB\n", iter->psnr_value);

    fprintf(output, "RESULT SSIM: %s= [", label.c_str());
    for (iter = results->frames.begin(); iter != results->frames.end() - 1;
         ++iter) {
      fprintf(output, "%f,", iter->ssim_value);
    }
    fprintf(output, "%f] score\n", iter->ssim_value);
  }
}

}  // namespace test
}  // namespace webrtc
