/*
 *  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 <assert.h>
#include <stdio.h>
#include <time.h>

#include <stdarg.h>
#include <sys/stat.h>  // To check for directory existence.

#ifndef S_ISDIR  // Not defined in stat.h on Windows.
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif

#include "gflags/gflags.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
#include "webrtc/modules/video_coding/codecs/test/stats.h"
#include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/modules/video_coding/include/video_coding.h"
#include "webrtc/rtc_base/format_macros.h"
#include "webrtc/test/testsupport/frame_reader.h"
#include "webrtc/test/testsupport/frame_writer.h"
#include "webrtc/test/testsupport/metrics/video_metrics.h"
#include "webrtc/test/testsupport/packet_reader.h"
#include "webrtc/test/video_codec_settings.h"

DEFINE_string(test_name, "Quality test", "The name of the test to run. ");
DEFINE_string(test_description,
              "",
              "A more detailed description about what "
              "the current test is about.");
DEFINE_string(input_filename,
              "",
              "Input file. "
              "The source video file to be encoded and decoded. Must be in "
              ".yuv format");
DEFINE_int32(width, -1, "Width in pixels of the frames in the input file.");
DEFINE_int32(height, -1, "Height in pixels of the frames in the input file.");
DEFINE_int32(framerate,
             30,
             "Frame rate of the input file, in FPS "
             "(frames-per-second). ");
DEFINE_string(output_dir,
              ".",
              "Output directory. "
              "The directory where the output file will be put. Must already "
              "exist.");
DEFINE_bool(use_single_core,
            false,
            "Force using a single core. If set to "
            "true, only one core will be used for processing. Using a single "
            "core is necessary to get a deterministic behavior for the"
            "encoded frames - using multiple cores will produce different "
            "encoded frames since multiple cores are competing to consume the "
            "byte budget for each frame in parallel. If set to false, "
            "the maximum detected number of cores will be used. ");
DEFINE_bool(disable_fixed_random_seed,
            false,
            "Set this flag to disable the"
            "usage of a fixed random seed for the random generator used "
            "for packet loss. Disabling this will cause consecutive runs "
            "loose packets at different locations, which is bad for "
            "reproducibility.");
DEFINE_string(output_filename,
              "",
              "Output file. "
              "The name of the output video file resulting of the processing "
              "of the source file. By default this is the same name as the "
              "input file with '_out' appended before the extension.");
DEFINE_int32(bitrate, 500, "Bit rate in kilobits/second.");
DEFINE_int32(keyframe_interval,
             0,
             "Forces a keyframe every Nth frame. "
             "0 means the encoder decides when to insert keyframes.  Note that "
             "the encoder may create a keyframe in other locations in addition "
             "to the interval that is set using this parameter.");
DEFINE_int32(temporal_layers,
             0,
             "The number of temporal layers to use "
             "(VP8 specific codec setting). Must be 0-4.");
DEFINE_int32(packet_size,
             1500,
             "Simulated network packet size in bytes (MTU). "
             "Used for packet loss simulation.");
DEFINE_int32(max_payload_size,
             1440,
             "Max payload size in bytes for the "
             "encoder.");
DEFINE_string(packet_loss_mode,
              "uniform",
              "Packet loss mode. Two different "
              "packet loss models are supported: uniform or burst. This "
              "setting has no effect unless packet_loss_rate is >0. ");
DEFINE_double(packet_loss_probability,
              0.0,
              "Packet loss probability. A value "
              "between 0.0 and 1.0 that defines the probability of a packet "
              "being lost. 0.1 means 10% and so on.");
DEFINE_int32(packet_loss_burst_length,
             1,
             "Packet loss burst length. Defines "
             "how many packets will be lost in a burst when a packet has been "
             "decided to be lost. Must be >=1.");
DEFINE_bool(csv,
            false,
            "CSV output. Enabling this will output all frame "
            "statistics at the end of execution. Recommended to run combined "
            "with --noverbose to avoid mixing output.");
DEFINE_bool(python,
            false,
            "Python output. Enabling this will output all frame "
            "statistics as a Python script at the end of execution. "
            "Recommended to run combine with --noverbose to avoid mixing "
            "output.");
DEFINE_bool(verbose,
            true,
            "Verbose mode. Prints a lot of debugging info. "
            "Suitable for tracking progress but not for capturing output. "
            "Disable with --noverbose flag.");

// Custom log method that only prints if the verbose flag is given.
// Supports all the standard printf parameters and formatting (just forwarded).
int Log(const char* format, ...) {
  int result = 0;
  if (FLAGS_verbose) {
    va_list args;
    va_start(args, format);
    result = vprintf(format, args);
    va_end(args);
  }
  return result;
}

// Validates the arguments given as command line flags and fills in the
// TestConfig struct with all configurations needed for video processing.
// Returns 0 if everything is OK, otherwise an exit code.
int HandleCommandLineFlags(webrtc::test::TestConfig* config) {
  // Validate the mandatory flags:
  if (FLAGS_input_filename.empty() || FLAGS_width == -1 || FLAGS_height == -1) {
    printf("%s\n", google::ProgramUsage());
    return 1;
  }
  config->name = FLAGS_test_name;
  config->description = FLAGS_test_description;

  // Verify the input file exists and is readable.
  FILE* test_file;
  test_file = fopen(FLAGS_input_filename.c_str(), "rb");
  if (test_file == NULL) {
    fprintf(stderr, "Cannot read the specified input file: %s\n",
            FLAGS_input_filename.c_str());
    return 2;
  }
  fclose(test_file);
  config->input_filename = FLAGS_input_filename;

  // Verify the output dir exists.
  struct stat dir_info;
  if (!(stat(FLAGS_output_dir.c_str(), &dir_info) == 0 &&
        S_ISDIR(dir_info.st_mode))) {
    fprintf(stderr, "Cannot find output directory: %s\n",
            FLAGS_output_dir.c_str());
    return 3;
  }
  config->output_dir = FLAGS_output_dir;

  // Manufacture an output filename if none was given.
  if (FLAGS_output_filename.empty()) {
    // Cut out the filename without extension from the given input file
    // (which may include a path)
    size_t startIndex = FLAGS_input_filename.find_last_of("/") + 1;
    if (startIndex == 0) {
      startIndex = 0;
    }
    FLAGS_output_filename =
        FLAGS_input_filename.substr(
            startIndex, FLAGS_input_filename.find_last_of(".") - startIndex) +
        "_out.yuv";
  }

  // Verify output file can be written.
  if (FLAGS_output_dir == ".") {
    config->output_filename = FLAGS_output_filename;
  } else {
    config->output_filename = FLAGS_output_dir + "/" + FLAGS_output_filename;
  }
  test_file = fopen(config->output_filename.c_str(), "wb");
  if (test_file == NULL) {
    fprintf(stderr, "Cannot write output file: %s\n",
            config->output_filename.c_str());
    return 4;
  }
  fclose(test_file);

  // Check single core flag.
  config->use_single_core = FLAGS_use_single_core;

  // Get codec specific configuration.
  webrtc::test::CodecSettings(webrtc::kVideoCodecVP8, &config->codec_settings);

  // Check the temporal layers.
  if (FLAGS_temporal_layers < 0 ||
      FLAGS_temporal_layers > webrtc::kMaxTemporalStreams) {
    fprintf(stderr, "Temporal layers number must be 0-4, was: %d\n",
            FLAGS_temporal_layers);
    return 13;
  }
  config->codec_settings.VP8()->numberOfTemporalLayers = FLAGS_temporal_layers;

  // Check the bit rate.
  if (FLAGS_bitrate <= 0) {
    fprintf(stderr, "Bit rate must be >0 kbps, was: %d\n", FLAGS_bitrate);
    return 5;
  }
  config->codec_settings.startBitrate = FLAGS_bitrate;

  // Check the keyframe interval.
  if (FLAGS_keyframe_interval < 0) {
    fprintf(stderr, "Keyframe interval must be >=0, was: %d\n",
            FLAGS_keyframe_interval);
    return 6;
  }
  config->keyframe_interval = FLAGS_keyframe_interval;

  // Check packet size and max payload size.
  if (FLAGS_packet_size <= 0) {
    fprintf(stderr, "Packet size must be >0 bytes, was: %d\n",
            FLAGS_packet_size);
    return 7;
  }
  config->networking_config.packet_size_in_bytes =
      static_cast<size_t>(FLAGS_packet_size);

  if (FLAGS_max_payload_size <= 0) {
    fprintf(stderr, "Max payload size must be >0 bytes, was: %d\n",
            FLAGS_max_payload_size);
    return 8;
  }
  config->networking_config.max_payload_size_in_bytes =
      static_cast<size_t>(FLAGS_max_payload_size);

  // Check the width and height
  if (FLAGS_width <= 0 || FLAGS_height <= 0) {
    fprintf(stderr, "Width and height must be >0.");
    return 9;
  }
  config->codec_settings.width = FLAGS_width;
  config->codec_settings.height = FLAGS_height;
  config->codec_settings.maxFramerate = FLAGS_framerate;

  // Calculate the size of each frame to read (according to YUV spec).
  config->frame_length_in_bytes =
      3 * config->codec_settings.width * config->codec_settings.height / 2;

  // Check packet loss settings
  if (FLAGS_packet_loss_mode != "uniform" &&
      FLAGS_packet_loss_mode != "burst") {
    fprintf(stderr,
            "Unsupported packet loss mode, must be 'uniform' or "
            "'burst'\n.");
    return 10;
  }
  config->networking_config.packet_loss_mode = webrtc::test::kUniform;
  if (FLAGS_packet_loss_mode == "burst") {
    config->networking_config.packet_loss_mode = webrtc::test::kBurst;
  }

  if (FLAGS_packet_loss_probability < 0.0 ||
      FLAGS_packet_loss_probability > 1.0) {
    fprintf(stderr,
            "Invalid packet loss probability. Must be 0.0 - 1.0, "
            "was: %f\n",
            FLAGS_packet_loss_probability);
    return 11;
  }
  config->networking_config.packet_loss_probability =
      FLAGS_packet_loss_probability;

  if (FLAGS_packet_loss_burst_length < 1) {
    fprintf(stderr,
            "Invalid packet loss burst length, must be >=1, "
            "was: %d\n",
            FLAGS_packet_loss_burst_length);
    return 12;
  }
  config->networking_config.packet_loss_burst_length =
      FLAGS_packet_loss_burst_length;
  config->verbose = FLAGS_verbose;
  return 0;
}

void CalculateSsimVideoMetrics(webrtc::test::TestConfig* config,
                               webrtc::test::QualityMetricsResult* result) {
  Log("Calculating SSIM...\n");
  I420SSIMFromFiles(
      config->input_filename.c_str(), config->output_filename.c_str(),
      config->codec_settings.width, config->codec_settings.height, result);
  Log("  Average: %3.2f\n", result->average);
  Log("  Min    : %3.2f (frame %d)\n", result->min, result->min_frame_number);
  Log("  Max    : %3.2f (frame %d)\n", result->max, result->max_frame_number);
}

void CalculatePsnrVideoMetrics(webrtc::test::TestConfig* config,
                               webrtc::test::QualityMetricsResult* result) {
  Log("Calculating PSNR...\n");
  I420PSNRFromFiles(
      config->input_filename.c_str(), config->output_filename.c_str(),
      config->codec_settings.width, config->codec_settings.height, result);
  Log("  Average: %3.2f\n", result->average);
  Log("  Min    : %3.2f (frame %d)\n", result->min, result->min_frame_number);
  Log("  Max    : %3.2f (frame %d)\n", result->max, result->max_frame_number);
}

void PrintConfigurationSummary(const webrtc::test::TestConfig& config) {
  Log("Quality test with parameters:\n");
  Log("  Test name        : %s\n", config.name.c_str());
  Log("  Description      : %s\n", config.description.c_str());
  Log("  Input filename   : %s\n", config.input_filename.c_str());
  Log("  Output directory : %s\n", config.output_dir.c_str());
  Log("  Output filename  : %s\n", config.output_filename.c_str());
  Log("  Frame length     : %" PRIuS " bytes\n", config.frame_length_in_bytes);
  Log("  Packet size      : %" PRIuS " bytes\n",
      config.networking_config.packet_size_in_bytes);
  Log("  Max payload size : %" PRIuS " bytes\n",
      config.networking_config.max_payload_size_in_bytes);
  Log("  Packet loss:\n");
  Log("    Mode           : %s\n",
      PacketLossModeToStr(config.networking_config.packet_loss_mode));
  Log("    Probability    : %2.1f\n",
      config.networking_config.packet_loss_probability);
  Log("    Burst length   : %d packets\n",
      config.networking_config.packet_loss_burst_length);
}

void PrintCsvOutput(const webrtc::test::Stats& stats,
                    const webrtc::test::QualityMetricsResult& ssim_result,
                    const webrtc::test::QualityMetricsResult& psnr_result) {
  Log(
      "\nCSV output (recommended to run with --noverbose to skip the "
      "above output)\n");
  printf(
      "frame_number encoding_successful decoding_successful "
      "encode_return_code decode_return_code "
      "encode_time_in_us decode_time_in_us "
      "bit_rate_in_kbps encoded_frame_length_in_bytes frame_type "
      "packets_dropped total_packets "
      "ssim psnr\n");

  for (unsigned int i = 0; i < stats.stats_.size(); ++i) {
    const webrtc::test::FrameStatistic& f = stats.stats_[i];
    const webrtc::test::FrameResult& ssim = ssim_result.frames[i];
    const webrtc::test::FrameResult& psnr = psnr_result.frames[i];
    printf("%4d, %d, %d, %2d, %2d, %6d, %6d, %5d, %7" PRIuS
           ", %d, %2d, %2" PRIuS ", %5.3f, %5.2f\n",
           f.frame_number, f.encoding_successful, f.decoding_successful,
           f.encode_return_code, f.decode_return_code, f.encode_time_in_us,
           f.decode_time_in_us, f.bit_rate_in_kbps,
           f.encoded_frame_length_in_bytes, f.frame_type, f.packets_dropped,
           f.total_packets, ssim.value, psnr.value);
  }
}

void PrintPythonOutput(const webrtc::test::TestConfig& config,
                       const webrtc::test::Stats& stats,
                       const webrtc::test::QualityMetricsResult& ssim_result,
                       const webrtc::test::QualityMetricsResult& psnr_result) {
  Log(
      "\nPython output (recommended to run with --noverbose to skip the "
      "above output)\n");
  printf(
      "test_configuration = ["
      "{'name': 'name',                      'value': '%s'},\n"
      "{'name': 'description',               'value': '%s'},\n"
      "{'name': 'test_number',               'value': '%d'},\n"
      "{'name': 'input_filename',            'value': '%s'},\n"
      "{'name': 'output_filename',           'value': '%s'},\n"
      "{'name': 'output_dir',                'value': '%s'},\n"
      "{'name': 'packet_size_in_bytes',      'value': '%" PRIuS
      "'},\n"
      "{'name': 'max_payload_size_in_bytes', 'value': '%" PRIuS
      "'},\n"
      "{'name': 'packet_loss_mode',          'value': '%s'},\n"
      "{'name': 'packet_loss_probability',   'value': '%f'},\n"
      "{'name': 'packet_loss_burst_length',  'value': '%d'},\n"
      "{'name': 'exclude_frame_types',       'value': '%s'},\n"
      "{'name': 'frame_length_in_bytes',     'value': '%" PRIuS
      "'},\n"
      "{'name': 'use_single_core',           'value': '%s'},\n"
      "{'name': 'keyframe_interval;',        'value': '%d'},\n"
      "{'name': 'video_codec_type',          'value': '%s'},\n"
      "{'name': 'width',                     'value': '%d'},\n"
      "{'name': 'height',                    'value': '%d'},\n"
      "{'name': 'bit_rate_in_kbps',          'value': '%d'},\n"
      "]\n",
      config.name.c_str(), config.description.c_str(), config.test_number,
      config.input_filename.c_str(), config.output_filename.c_str(),
      config.output_dir.c_str(), config.networking_config.packet_size_in_bytes,
      config.networking_config.max_payload_size_in_bytes,
      PacketLossModeToStr(config.networking_config.packet_loss_mode),
      config.networking_config.packet_loss_probability,
      config.networking_config.packet_loss_burst_length,
      ExcludeFrameTypesToStr(config.exclude_frame_types),
      config.frame_length_in_bytes, config.use_single_core ? "True " : "False",
      config.keyframe_interval,
      CodecTypeToPayloadName(config.codec_settings.codecType)
          .value_or("Unknown"),
      config.codec_settings.width, config.codec_settings.height,
      config.codec_settings.startBitrate);
  printf(
      "frame_data_types = {"
      "'frame_number': ('number', 'Frame number'),\n"
      "'encoding_successful': ('boolean', 'Encoding successful?'),\n"
      "'decoding_successful': ('boolean', 'Decoding successful?'),\n"
      "'encode_time': ('number', 'Encode time (us)'),\n"
      "'decode_time': ('number', 'Decode time (us)'),\n"
      "'encode_return_code': ('number', 'Encode return code'),\n"
      "'decode_return_code': ('number', 'Decode return code'),\n"
      "'bit_rate': ('number', 'Bit rate (kbps)'),\n"
      "'encoded_frame_length': "
      "('number', 'Encoded frame length (bytes)'),\n"
      "'frame_type': ('string', 'Frame type'),\n"
      "'packets_dropped': ('number', 'Packets dropped'),\n"
      "'total_packets': ('number', 'Total packets'),\n"
      "'ssim': ('number', 'SSIM'),\n"
      "'psnr': ('number', 'PSNR (dB)'),\n"
      "}\n");
  printf("frame_data = [");
  for (unsigned int i = 0; i < stats.stats_.size(); ++i) {
    const webrtc::test::FrameStatistic& f = stats.stats_[i];
    const webrtc::test::FrameResult& ssim = ssim_result.frames[i];
    const webrtc::test::FrameResult& psnr = psnr_result.frames[i];
    printf(
        "{'frame_number': %d, "
        "'encoding_successful': %s, 'decoding_successful': %s, "
        "'encode_time': %d, 'decode_time': %d, "
        "'encode_return_code': %d, 'decode_return_code': %d, "
        "'bit_rate': %d, 'encoded_frame_length': %" PRIuS
        ", "
        "'frame_type': %s, 'packets_dropped': %d, "
        "'total_packets': %" PRIuS ", 'ssim': %f, 'psnr': %f},\n",
        f.frame_number, f.encoding_successful ? "True " : "False",
        f.decoding_successful ? "True " : "False", f.encode_time_in_us,
        f.decode_time_in_us, f.encode_return_code, f.decode_return_code,
        f.bit_rate_in_kbps, f.encoded_frame_length_in_bytes,
        f.frame_type == webrtc::kVideoFrameDelta ? "'Delta'" : "'Other'",
        f.packets_dropped, f.total_packets, ssim.value, psnr.value);
  }
  printf("]\n");
}

// Runs a quality measurement on the input file supplied to the program.
// The input file must be in YUV format.
int main(int argc, char* argv[]) {
  std::string program_name = argv[0];
  std::string usage =
      "Quality test application for video comparisons.\n"
      "Run " +
      program_name +
      " --helpshort for usage.\n"
      "Example usage:\n" +
      program_name +
      " --input_filename=filename.yuv --width=352 --height=288\n";
  google::SetUsageMessage(usage);

  google::ParseCommandLineFlags(&argc, &argv, true);

  // Create TestConfig.
  webrtc::test::TestConfig config;

  int return_code = HandleCommandLineFlags(&config);
  // Exit if an invalid argument is supplied.
  if (return_code != 0) {
    return return_code;
  }

  PrintConfigurationSummary(config);

  webrtc::VP8Encoder* encoder = webrtc::VP8Encoder::Create();
  webrtc::VP8Decoder* decoder = webrtc::VP8Decoder::Create();
  webrtc::test::Stats stats;
  webrtc::test::YuvFrameReaderImpl frame_reader(config.input_filename,
                                                config.codec_settings.width,
                                                config.codec_settings.height);
  webrtc::test::YuvFrameWriterImpl frame_writer(config.output_filename,
                                                config.codec_settings.width,
                                                config.codec_settings.height);
  frame_reader.Init();
  frame_writer.Init();
  webrtc::test::PacketReader packet_reader;

  webrtc::test::PacketManipulatorImpl packet_manipulator(
      &packet_reader, config.networking_config, config.verbose);
  // By default the packet manipulator is seeded with a fixed random.
  // If disabled we must generate a new seed.
  if (FLAGS_disable_fixed_random_seed) {
    packet_manipulator.InitializeRandomSeed(time(NULL));
  }
  webrtc::test::VideoProcessor* processor = new webrtc::test::VideoProcessor(
      encoder, decoder, &frame_reader, &frame_writer, &packet_manipulator,
      config, &stats, nullptr /* encoded_frame_writer */,
      nullptr /* decoded_frame_writer */);
  processor->Init();

  const int num_frames = frame_reader.NumberOfFrames();
  int frame_number = 0;
  while (frame_number < num_frames) {
    processor->ProcessFrame(frame_number);
    if (frame_number % 80 == 0) {
      Log("\n");  // make the output a bit nicer.
    }
    Log(".");
    frame_number++;
  }
  Log("\n");
  Log("Processed %d frames\n", frame_number);

  // Release encoder and decoder to make sure they have finished processing.
  processor->Release();

  // Verify statistics are correct:
  assert(frame_number == static_cast<int>(stats.stats_.size()));

  // Close the files before we start using them for SSIM/PSNR calculations.
  frame_reader.Close();
  frame_writer.Close();

  stats.PrintSummary();

  webrtc::test::QualityMetricsResult ssim_result;
  CalculateSsimVideoMetrics(&config, &ssim_result);
  webrtc::test::QualityMetricsResult psnr_result;
  CalculatePsnrVideoMetrics(&config, &psnr_result);

  if (FLAGS_csv) {
    PrintCsvOutput(stats, ssim_result, psnr_result);
  }
  if (FLAGS_python) {
    PrintPythonOutput(config, stats, ssim_result, psnr_result);
  }
  delete processor;
  delete encoder;
  delete decoder;
  Log("Quality test finished!");
  return 0;
}
