/*
 *  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_coding/codecs/test/stats.h"

#include <stdio.h>

#include <algorithm>  // min_element, max_element

#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/format_macros.h"

namespace webrtc {
namespace test {
namespace {
bool LessForEncodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
  return s1.encode_time_in_us < s2.encode_time_in_us;
}

bool LessForDecodeTime(const FrameStatistic& s1, const FrameStatistic& s2) {
  return s1.decode_time_in_us < s2.decode_time_in_us;
}

bool LessForEncodedSize(const FrameStatistic& s1, const FrameStatistic& s2) {
  return s1.encoded_frame_length_in_bytes < s2.encoded_frame_length_in_bytes;
}

bool LessForBitRate(const FrameStatistic& s1, const FrameStatistic& s2) {
  return s1.bit_rate_in_kbps < s2.bit_rate_in_kbps;
}
}  // namespace

Stats::Stats() {}

Stats::~Stats() {}

FrameStatistic& Stats::NewFrame(int frame_number) {
  RTC_DCHECK_GE(frame_number, 0);
  FrameStatistic stat;
  stat.frame_number = frame_number;
  stats_.push_back(stat);
  return stats_[frame_number];
}

void Stats::PrintSummary() {
  if (stats_.empty()) {
    printf("No frame statistics have been logged yet.\n");
    return;
  }

  // Calculate min, max, average and total encoding time.
  int total_encoding_time_in_us = 0;
  int total_decoding_time_in_us = 0;
  int total_qp = 0;
  int total_qp_count = 0;
  size_t total_encoded_frames_lengths = 0;
  size_t total_encoded_key_frames_lengths = 0;
  size_t total_encoded_nonkey_frames_lengths = 0;
  size_t num_keyframes = 0;
  size_t num_nonkeyframes = 0;

  for (const FrameStatistic& stat : stats_) {
    total_encoding_time_in_us += stat.encode_time_in_us;
    total_decoding_time_in_us += stat.decode_time_in_us;
    total_encoded_frames_lengths += stat.encoded_frame_length_in_bytes;
    if (stat.frame_type == webrtc::kVideoFrameKey) {
      total_encoded_key_frames_lengths += stat.encoded_frame_length_in_bytes;
      ++num_keyframes;
    } else {
      total_encoded_nonkey_frames_lengths += stat.encoded_frame_length_in_bytes;
      ++num_nonkeyframes;
    }
    if (stat.qp >= 0) {
      total_qp += stat.qp;
      ++total_qp_count;
    }
  }

  // Encoding stats.
  printf("Encoding time:\n");
  FrameStatisticsIterator frame;
  frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodeTime);
  printf("  Min     : %7d us (frame %d)\n", frame->encode_time_in_us,
         frame->frame_number);
  frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodeTime);
  printf("  Max     : %7d us (frame %d)\n", frame->encode_time_in_us,
         frame->frame_number);
  printf("  Average : %7d us\n",
         static_cast<int>(total_encoding_time_in_us / stats_.size()));

  // Decoding stats.
  printf("Decoding time:\n");
  // Only consider successfully decoded frames (packet loss may cause failures).
  std::vector<FrameStatistic> decoded_frames;
  for (const FrameStatistic& stat : stats_) {
    if (stat.decoding_successful) {
      decoded_frames.push_back(stat);
    }
  }
  if (decoded_frames.empty()) {
    printf("No successfully decoded frames exist in this statistics.\n");
  } else {
    frame = std::min_element(decoded_frames.begin(), decoded_frames.end(),
                             LessForDecodeTime);
    printf("  Min     : %7d us (frame %d)\n", frame->decode_time_in_us,
           frame->frame_number);
    frame = std::max_element(decoded_frames.begin(), decoded_frames.end(),
                             LessForDecodeTime);
    printf("  Max     : %7d us (frame %d)\n", frame->decode_time_in_us,
           frame->frame_number);
    printf("  Average : %7d us\n",
           static_cast<int>(total_decoding_time_in_us / decoded_frames.size()));
    printf("  Failures: %d frames failed to decode.\n",
           static_cast<int>(stats_.size() - decoded_frames.size()));
  }

  // Frame size stats.
  printf("Frame sizes:\n");
  frame = std::min_element(stats_.begin(), stats_.end(), LessForEncodedSize);
  printf("  Min     : %7" PRIuS " bytes (frame %d)\n",
         frame->encoded_frame_length_in_bytes, frame->frame_number);
  frame = std::max_element(stats_.begin(), stats_.end(), LessForEncodedSize);
  printf("  Max     : %7" PRIuS " bytes (frame %d)\n",
         frame->encoded_frame_length_in_bytes, frame->frame_number);
  printf("  Average : %7" PRIuS " bytes\n",
         total_encoded_frames_lengths / stats_.size());
  if (num_keyframes > 0) {
    printf("  Average key frame size    : %7" PRIuS " bytes (%" PRIuS
           " keyframes)\n",
           total_encoded_key_frames_lengths / num_keyframes, num_keyframes);
  }
  if (num_nonkeyframes > 0) {
    printf("  Average non-key frame size: %7" PRIuS " bytes (%" PRIuS
           " frames)\n",
           total_encoded_nonkey_frames_lengths / num_nonkeyframes,
           num_nonkeyframes);
  }

  // Bitrate stats.
  printf("Bitrates:\n");
  frame = std::min_element(stats_.begin(), stats_.end(), LessForBitRate);
  printf("  Min bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps,
         frame->frame_number);
  frame = std::max_element(stats_.begin(), stats_.end(), LessForBitRate);
  printf("  Max bitrate: %7d kbps (frame %d)\n", frame->bit_rate_in_kbps,
         frame->frame_number);

  printf("\n");
  printf("Total encoding time  : %7d ms.\n", total_encoding_time_in_us / 1000);
  printf("Total decoding time  : %7d ms.\n", total_decoding_time_in_us / 1000);
  printf("Total processing time: %7d ms.\n",
         (total_encoding_time_in_us + total_decoding_time_in_us) / 1000);

  int avg_qp = (total_qp_count > 0) ? (total_qp / total_qp_count) : -1;
  printf("Average QP: %d\n", avg_qp);
}

}  // namespace test
}  // namespace webrtc
