/*
 *  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/base/format_macros.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/main/interface/video_coding.h"
#include "webrtc/system_wrappers/include/trace.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"

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)
    int 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::VideoCodingModule::Codec(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->codecSpecific.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,
         webrtc::test::VideoCodecTypeToStr(config.codec_settings->codecType),
         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 and codec settings struct.
  webrtc::test::TestConfig config;
  webrtc::VideoCodec codec_settings;
  config.codec_settings = &codec_settings;

  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::FrameReaderImpl frame_reader(config.input_filename,
                                             config.frame_length_in_bytes);
  webrtc::test::FrameWriterImpl frame_writer(config.output_filename,
                                             config.frame_length_in_bytes);
  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::VideoProcessorImpl(encoder, decoder,
                                           &frame_reader,
                                           &frame_writer,
                                           &packet_manipulator,
                                           config, &stats);
  processor->Init();

  int frame_number = 0;
  while (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.
  encoder->Release();
  decoder->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;
}
