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

#include <algorithm>  // min_element, max_element

#include "webrtc/base/format_macros.h"

namespace webrtc {
namespace test {

FrameStatistic::FrameStatistic()
    : encoding_successful(false),
      decoding_successful(false),
      encode_return_code(0),
      decode_return_code(0),
      encode_time_in_us(0),
      decode_time_in_us(0),
      frame_number(0),
      packets_dropped(0),
      total_packets(0),
      bit_rate_in_kbps(0),
      encoded_frame_length_in_bytes(0),
      frame_type(kVideoFrameDelta) {}

Stats::Stats() {}

Stats::~Stats() {}

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;
}

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

void Stats::PrintSummary() {
  printf("Processing summary:\n");
  if (stats_.size() == 0) {
    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;
  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 nbr_keyframes = 0;
  size_t nbr_nonkeyframes = 0;

  for (FrameStatisticsIterator it = stats_.begin();
      it != stats_.end(); ++it) {
    total_encoding_time_in_us += it->encode_time_in_us;
    total_decoding_time_in_us += it->decode_time_in_us;
    total_encoded_frames_lengths += it->encoded_frame_length_in_bytes;
    if (it->frame_type == webrtc::kVideoFrameKey) {
      total_encoded_key_frames_lengths += it->encoded_frame_length_in_bytes;
      nbr_keyframes++;
    } else {
      total_encoded_nonkey_frames_lengths += it->encoded_frame_length_in_bytes;
      nbr_nonkeyframes++;
    }
  }

  FrameStatisticsIterator frame;

  // ENCODING
  printf("Encoding time:\n");
  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
  printf("Decoding time:\n");
  // only consider frames that were successfully decoded (packet loss may cause
  // failures)
  std::vector<FrameStatistic> decoded_frames;
  for (std::vector<FrameStatistic>::iterator it = stats_.begin();
      it != stats_.end(); ++it) {
    if (it->decoding_successful) {
      decoded_frames.push_back(*it);
    }
  }
  if (decoded_frames.size() == 0) {
    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()));
  }

  // SIZE
  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 (nbr_keyframes > 0) {
    printf("  Average key frame size    : %7" PRIuS " bytes (%" PRIuS
           " keyframes)\n",
           total_encoded_key_frames_lengths / nbr_keyframes, nbr_keyframes);
  }
  if (nbr_nonkeyframes > 0) {
    printf("  Average non-key frame size: %7" PRIuS " bytes (%" PRIuS
           " frames)\n",
           total_encoded_nonkey_frames_lengths / nbr_nonkeyframes,
           nbr_nonkeyframes);
  }

  // BIT RATE
  printf("Bit rates:\n");
  frame = std::min_element(stats_.begin(),
                      stats_.end(), LessForBitRate);
  printf("  Min bit rate: %7d kbps (frame %d)\n",
         frame->bit_rate_in_kbps, frame->frame_number);

  frame = std::max_element(stats_.begin(),
                      stats_.end(), LessForBitRate);
  printf("  Max bit rate: %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);
}

}  // namespace test
}  // namespace webrtc
