/*
 *  Copyright (c) 2017 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 "modules/video_coding/codecs/test/videoprocessor_integrationtest.h"

#include <algorithm>
#include <utility>

#if defined(WEBRTC_ANDROID)
#include "modules/video_coding/codecs/test/android_test_initializer.h"
#include "sdk/android/src/jni/class_loader.h"
#include "sdk/android/src/jni/videodecoderfactorywrapper.h"
#include "sdk/android/src/jni/videoencoderfactorywrapper.h"
#elif defined(WEBRTC_IOS)
#include "modules/video_coding/codecs/test/objc_codec_h264_test.h"
#endif

#include "common_types.h"  // NOLINT(build/include)
#include "media/base/h264_profile_level_id.h"
#include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
#include "media/engine/videoencodersoftwarefallbackwrapper.h"
#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_coding.h"
#include "rtc_base/checks.h"
#include "rtc_base/cpu_time.h"
#include "rtc_base/event.h"
#include "rtc_base/file.h"
#include "rtc_base/ptr_util.h"
#include "system_wrappers/include/sleep.h"
#include "test/statistics.h"
#include "test/testsupport/fileutils.h"
#include "test/testsupport/metrics/video_metrics.h"

namespace webrtc {
namespace test {

namespace {

const int kRtpClockRateHz = 90000;

const int kMaxBitrateMismatchPercent = 20;

bool RunEncodeInRealTime(const TestConfig& config) {
  if (config.measure_cpu) {
    return true;
  }
#if defined(WEBRTC_ANDROID)
  // In order to not overwhelm the OpenMAX buffers in the Android MediaCodec.
  return (config.hw_encoder || config.hw_decoder);
#else
  return false;
#endif
}

SdpVideoFormat CreateSdpVideoFormat(const TestConfig& config) {
  switch (config.codec_settings.codecType) {
    case kVideoCodecVP8:
      return SdpVideoFormat(cricket::kVp8CodecName);

    case kVideoCodecVP9:
      return SdpVideoFormat(cricket::kVp9CodecName);

    case kVideoCodecH264: {
      const char* packetization_mode =
          config.h264_codec_settings.packetization_mode ==
                  H264PacketizationMode::NonInterleaved
              ? "1"
              : "0";
      return SdpVideoFormat(
          cricket::kH264CodecName,
          {{cricket::kH264FmtpProfileLevelId,
            *H264::ProfileLevelIdToString(H264::ProfileLevelId(
                config.h264_codec_settings.profile, H264::kLevel3_1))},
           {cricket::kH264FmtpPacketizationMode, packetization_mode}});
    }
    default:
      RTC_NOTREACHED();
      return SdpVideoFormat("");
  }
}

}  // namespace

void VideoProcessorIntegrationTest::H264KeyframeChecker::CheckEncodedFrame(
    webrtc::VideoCodecType codec,
    const EncodedImage& encoded_frame) const {
  EXPECT_EQ(kVideoCodecH264, codec);
  bool contains_sps = false;
  bool contains_pps = false;
  bool contains_idr = false;
  const std::vector<webrtc::H264::NaluIndex> nalu_indices =
      webrtc::H264::FindNaluIndices(encoded_frame._buffer,
                                    encoded_frame._length);
  for (const webrtc::H264::NaluIndex& index : nalu_indices) {
    webrtc::H264::NaluType nalu_type = webrtc::H264::ParseNaluType(
        encoded_frame._buffer[index.payload_start_offset]);
    if (nalu_type == webrtc::H264::NaluType::kSps) {
      contains_sps = true;
    } else if (nalu_type == webrtc::H264::NaluType::kPps) {
      contains_pps = true;
    } else if (nalu_type == webrtc::H264::NaluType::kIdr) {
      contains_idr = true;
    }
  }
  if (encoded_frame._frameType == kVideoFrameKey) {
    EXPECT_TRUE(contains_sps) << "Keyframe should contain SPS.";
    EXPECT_TRUE(contains_pps) << "Keyframe should contain PPS.";
    EXPECT_TRUE(contains_idr) << "Keyframe should contain IDR.";
  } else if (encoded_frame._frameType == kVideoFrameDelta) {
    EXPECT_FALSE(contains_sps) << "Delta frame should not contain SPS.";
    EXPECT_FALSE(contains_pps) << "Delta frame should not contain PPS.";
    EXPECT_FALSE(contains_idr) << "Delta frame should not contain IDR.";
  } else {
    RTC_NOTREACHED();
  }
}

class VideoProcessorIntegrationTest::CpuProcessTime final {
 public:
  explicit CpuProcessTime(const TestConfig& config) : config_(config) {}
  ~CpuProcessTime() {}

  void Start() {
    if (config_.measure_cpu) {
      cpu_time_ -= rtc::GetProcessCpuTimeNanos();
      wallclock_time_ -= rtc::SystemTimeNanos();
    }
  }
  void Stop() {
    if (config_.measure_cpu) {
      cpu_time_ += rtc::GetProcessCpuTimeNanos();
      wallclock_time_ += rtc::SystemTimeNanos();
    }
  }
  void Print() const {
    if (config_.measure_cpu) {
      printf("CPU usage %%: %f\n", GetUsagePercent() / config_.NumberOfCores());
      printf("\n");
    }
  }

 private:
  double GetUsagePercent() const {
    return static_cast<double>(cpu_time_) / wallclock_time_ * 100.0;
  }

  const TestConfig config_;
  int64_t cpu_time_ = 0;
  int64_t wallclock_time_ = 0;
};

VideoProcessorIntegrationTest::VideoProcessorIntegrationTest() {
#if defined(WEBRTC_ANDROID)
  InitializeAndroidObjects();
#endif
}

VideoProcessorIntegrationTest::~VideoProcessorIntegrationTest() = default;

// Processes all frames in the clip and verifies the result.
void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
    const std::vector<RateProfile>& rate_profiles,
    const std::vector<RateControlThresholds>* rc_thresholds,
    const std::vector<QualityThresholds>* quality_thresholds,
    const BitstreamThresholds* bs_thresholds,
    const VisualizationParams* visualization_params) {
  RTC_DCHECK(!rate_profiles.empty());
  // The Android HW codec needs to be run on a task queue, so we simply always
  // run the test on a task queue.
  rtc::TaskQueue task_queue("VidProc TQ");

  SetUpAndInitObjects(
      &task_queue, static_cast<const int>(rate_profiles[0].target_kbps),
      static_cast<const int>(rate_profiles[0].input_fps), visualization_params);
  PrintSettings();

  ProcessAllFrames(&task_queue, rate_profiles);

  ReleaseAndCloseObjects(&task_queue);

  AnalyzeAllFrames(rate_profiles, rc_thresholds, quality_thresholds,
                   bs_thresholds);
}

void VideoProcessorIntegrationTest::ProcessAllFrames(
    rtc::TaskQueue* task_queue,
    const std::vector<RateProfile>& rate_profiles) {
  // Process all frames.
  size_t rate_update_index = 0;

  // Set initial rates.
  task_queue->PostTask([this, &rate_profiles, rate_update_index] {
    processor_->SetRates(rate_profiles[rate_update_index].target_kbps,
                         rate_profiles[rate_update_index].input_fps);
  });

  cpu_process_time_->Start();

  for (size_t frame_number = 0; frame_number < config_.num_frames;
       ++frame_number) {
    if (frame_number ==
        rate_profiles[rate_update_index].frame_index_rate_update) {
      ++rate_update_index;
      RTC_DCHECK_GT(rate_profiles.size(), rate_update_index);

      task_queue->PostTask([this, &rate_profiles, rate_update_index] {
        processor_->SetRates(rate_profiles[rate_update_index].target_kbps,
                             rate_profiles[rate_update_index].input_fps);
      });
    }

    task_queue->PostTask([this] { processor_->ProcessFrame(); });

    if (RunEncodeInRealTime(config_)) {
      // Roughly pace the frames.
      size_t frame_duration_ms =
          rtc::kNumMillisecsPerSec / rate_profiles[rate_update_index].input_fps;
      SleepMs(static_cast<int>(frame_duration_ms));
    }
  }

  rtc::Event sync_event(false, false);
  task_queue->PostTask([&sync_event] { sync_event.Set(); });
  sync_event.Wait(rtc::Event::kForever);

  // Give the VideoProcessor pipeline some time to process the last frame,
  // and then release the codecs.
  if (config_.hw_encoder || config_.hw_decoder) {
    SleepMs(1 * rtc::kNumMillisecsPerSec);
  }

  cpu_process_time_->Stop();
}

void VideoProcessorIntegrationTest::AnalyzeAllFrames(
    const std::vector<RateProfile>& rate_profiles,
    const std::vector<RateControlThresholds>* rc_thresholds,
    const std::vector<QualityThresholds>* quality_thresholds,
    const BitstreamThresholds* bs_thresholds) {
  const bool is_svc = config_.NumberOfSpatialLayers() > 1;
  const size_t number_of_simulcast_or_spatial_layers =
      std::max(std::size_t{1},
               std::max(config_.NumberOfSpatialLayers(),
                        static_cast<size_t>(
                            config_.codec_settings.numberOfSimulcastStreams)));
  const size_t number_of_temporal_layers = config_.NumberOfTemporalLayers();
  printf("Rate control statistics\n==\n");
  for (size_t rate_update_index = 0; rate_update_index < rate_profiles.size();
       ++rate_update_index) {
    const size_t first_frame_number =
        (rate_update_index == 0)
            ? 0
            : rate_profiles[rate_update_index - 1].frame_index_rate_update;
    const size_t last_frame_number =
        rate_profiles[rate_update_index].frame_index_rate_update - 1;
    RTC_CHECK(last_frame_number >= first_frame_number);
    const size_t number_of_frames = last_frame_number - first_frame_number + 1;
    const float input_duration_sec =
        1.0 * number_of_frames / rate_profiles[rate_update_index].input_fps;

    std::vector<FrameStatistic> overall_stats =
        ExtractLayerStats(number_of_simulcast_or_spatial_layers - 1,
                          number_of_temporal_layers - 1, first_frame_number,
                          last_frame_number, true);

    printf("Rate update #%zu:\n", rate_update_index);

    const RateControlThresholds* rc_threshold =
        rc_thresholds ? &(*rc_thresholds)[rate_update_index] : nullptr;
    const QualityThresholds* quality_threshold =
        quality_thresholds ? &(*quality_thresholds)[rate_update_index]
                           : nullptr;
    AnalyzeAndPrintStats(
        overall_stats, rate_profiles[rate_update_index].target_kbps,
        rate_profiles[rate_update_index].input_fps, input_duration_sec,
        rc_threshold, quality_threshold, bs_thresholds);

    if (config_.print_frame_level_stats) {
      PrintFrameLevelStats(overall_stats);
    }

    for (size_t spatial_layer_number = 0;
         spatial_layer_number < number_of_simulcast_or_spatial_layers;
         ++spatial_layer_number) {
      for (size_t temporal_layer_number = 0;
           temporal_layer_number < number_of_temporal_layers;
           ++temporal_layer_number) {
        std::vector<FrameStatistic> layer_stats =
            ExtractLayerStats(spatial_layer_number, temporal_layer_number,
                              first_frame_number, last_frame_number, is_svc);

        const size_t target_bitrate_kbps = layer_stats[0].target_bitrate_kbps;
        const float target_framerate_fps =
            1.0 * rate_profiles[rate_update_index].input_fps /
            (1 << (number_of_temporal_layers - temporal_layer_number - 1));

        printf("Spatial %zu temporal %zu:\n", spatial_layer_number,
               temporal_layer_number);
        AnalyzeAndPrintStats(layer_stats, target_bitrate_kbps,
                             target_framerate_fps, input_duration_sec, nullptr,
                             nullptr, nullptr);

        if (config_.print_frame_level_stats) {
          PrintFrameLevelStats(layer_stats);
        }
      }
    }
  }

  cpu_process_time_->Print();
}

std::vector<FrameStatistic> VideoProcessorIntegrationTest::ExtractLayerStats(
    size_t target_spatial_layer_number,
    size_t target_temporal_layer_number,
    size_t first_frame_number,
    size_t last_frame_number,
    bool combine_layers_stats) {
  size_t target_bitrate_kbps = 0;
  std::vector<FrameStatistic> layer_stats;

  for (size_t frame_number = first_frame_number;
       frame_number <= last_frame_number; ++frame_number) {
    // TODO(ssilkin): Add layering support
    // FrameStatistic superframe_stat =
    // *stats_[target_spatial_layer_number].GetFrame(frame_number);
    FrameStatistic superframe_stat = *stats_.GetFrame(frame_number);
    const size_t tl_idx = superframe_stat.temporal_layer_idx;
    if (tl_idx <= target_temporal_layer_number) {
      if (combine_layers_stats) {
        for (size_t spatial_layer_number = 0;
             spatial_layer_number < target_spatial_layer_number;
             ++spatial_layer_number) {
          // TODO(ssilkin): Add layering support
          // const FrameStatistic* frame_stat =
          //    stats_[spatial_layer_number].GetFrame(frame_number);
          const FrameStatistic* frame_stat = stats_.GetFrame(frame_number);
          superframe_stat.encoded_frame_size_bytes +=
              frame_stat->encoded_frame_size_bytes;
          superframe_stat.encode_time_us = std::max(
              superframe_stat.encode_time_us, frame_stat->encode_time_us);
          superframe_stat.decode_time_us = std::max(
              superframe_stat.decode_time_us, frame_stat->decode_time_us);
        }
      }

      target_bitrate_kbps =
          std::max(target_bitrate_kbps, superframe_stat.target_bitrate_kbps);

      if (superframe_stat.encoding_successful) {
        RTC_CHECK(superframe_stat.target_bitrate_kbps <= target_bitrate_kbps ||
                  tl_idx == target_temporal_layer_number);
        RTC_CHECK(superframe_stat.target_bitrate_kbps == target_bitrate_kbps ||
                  tl_idx < target_temporal_layer_number);
      }

      layer_stats.push_back(superframe_stat);
    }
  }

  for (auto& frame_stat : layer_stats) {
    frame_stat.target_bitrate_kbps = target_bitrate_kbps;
  }

  return layer_stats;
}

void VideoProcessorIntegrationTest::CreateEncoderAndDecoder() {
  std::unique_ptr<VideoEncoderFactory> encoder_factory;
  if (config_.hw_encoder) {
#if defined(WEBRTC_ANDROID)
    JNIEnv* env = jni::AttachCurrentThreadIfNeeded();
    jni::ScopedJavaLocalRef<jclass> factory_class =
        jni::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
    jmethodID factory_constructor = env->GetMethodID(
        factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
    jni::ScopedJavaLocalRef<jobject> factory_object(
        env, env->NewObject(factory_class.obj(), factory_constructor,
                            nullptr /* shared_context */,
                            false /* enable_intel_vp8_encoder */,
                            true /* enable_h264_high_profile */));
    encoder_factory = rtc::MakeUnique<webrtc::jni::VideoEncoderFactoryWrapper>(
        env, factory_object);
#elif defined(WEBRTC_IOS)
    EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType)
        << "iOS HW codecs only support H264.";
    encoder_factory = CreateObjCEncoderFactory();
#else
    RTC_NOTREACHED() << "Only support HW encoder on Android and iOS.";
#endif
  } else {
    encoder_factory = rtc::MakeUnique<InternalEncoderFactory>();
  }

  std::unique_ptr<VideoDecoderFactory> decoder_factory;
  if (config_.hw_decoder) {
#if defined(WEBRTC_ANDROID)
    JNIEnv* env = jni::AttachCurrentThreadIfNeeded();
    jni::ScopedJavaLocalRef<jclass> factory_class =
        jni::GetClass(env, "org/webrtc/HardwareVideoDecoderFactory");
    jmethodID factory_constructor = env->GetMethodID(
        factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
    jni::ScopedJavaLocalRef<jobject> factory_object(
        env, env->NewObject(factory_class.obj(), factory_constructor,
                            nullptr /* shared_context */));
    decoder_factory = rtc::MakeUnique<webrtc::jni::VideoDecoderFactoryWrapper>(
        env, factory_object);
#elif defined(WEBRTC_IOS)
    EXPECT_EQ(kVideoCodecH264, config_.codec_settings.codecType)
        << "iOS HW codecs only support H264.";
    decoder_factory = CreateObjCDecoderFactory();
#else
    RTC_NOTREACHED() << "Only support HW decoder on Android and iOS.";
#endif
  } else {
    decoder_factory = rtc::MakeUnique<InternalDecoderFactory>();
  }

  const SdpVideoFormat format = CreateSdpVideoFormat(config_);
  encoder_ = encoder_factory->CreateVideoEncoder(format);
  decoder_ = decoder_factory->CreateVideoDecoder(format);

  if (config_.sw_fallback_encoder) {
    encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>(
        InternalEncoderFactory().CreateVideoEncoder(format),
        std::move(encoder_));
  }
  if (config_.sw_fallback_decoder) {
    decoder_ = rtc::MakeUnique<VideoDecoderSoftwareFallbackWrapper>(
        InternalDecoderFactory().CreateVideoDecoder(format),
        std::move(decoder_));
  }

  EXPECT_TRUE(encoder_) << "Encoder not successfully created.";
  EXPECT_TRUE(decoder_) << "Decoder not successfully created.";
}

void VideoProcessorIntegrationTest::DestroyEncoderAndDecoder() {
  encoder_.reset();
  decoder_.reset();
}

void VideoProcessorIntegrationTest::SetUpAndInitObjects(
    rtc::TaskQueue* task_queue,
    const int initial_bitrate_kbps,
    const int initial_framerate_fps,
    const VisualizationParams* visualization_params) {
  CreateEncoderAndDecoder();

  config_.codec_settings.minBitrate = 0;
  config_.codec_settings.startBitrate = initial_bitrate_kbps;
  config_.codec_settings.maxFramerate = initial_framerate_fps;

  // Create file objects for quality analysis.
  analysis_frame_reader_.reset(new YuvFrameReaderImpl(
      config_.input_filename, config_.codec_settings.width,
      config_.codec_settings.height));
  analysis_frame_writer_.reset(new YuvFrameWriterImpl(
      config_.output_filename, config_.codec_settings.width,
      config_.codec_settings.height));
  EXPECT_TRUE(analysis_frame_reader_->Init());
  EXPECT_TRUE(analysis_frame_writer_->Init());

  if (visualization_params) {
    const std::string output_filename_base =
        OutputPath() + config_.FilenameWithParams();
    if (visualization_params->save_encoded_ivf) {
      rtc::File post_encode_file =
          rtc::File::Create(output_filename_base + ".ivf");
      encoded_frame_writer_ =
          IvfFileWriter::Wrap(std::move(post_encode_file), 0);
    }
    if (visualization_params->save_decoded_y4m) {
      decoded_frame_writer_.reset(new Y4mFrameWriterImpl(
          output_filename_base + ".y4m", config_.codec_settings.width,
          config_.codec_settings.height, initial_framerate_fps));
      EXPECT_TRUE(decoded_frame_writer_->Init());
    }
  }

  cpu_process_time_.reset(new CpuProcessTime(config_));

  rtc::Event sync_event(false, false);
  task_queue->PostTask([this, &sync_event]() {
    processor_ = rtc::MakeUnique<VideoProcessor>(
        encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), config_,
        &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
    sync_event.Set();
  });
  sync_event.Wait(rtc::Event::kForever);
}

void VideoProcessorIntegrationTest::ReleaseAndCloseObjects(
    rtc::TaskQueue* task_queue) {
  rtc::Event sync_event(false, false);
  task_queue->PostTask([this, &sync_event]() {
    processor_.reset();
    sync_event.Set();
  });
  sync_event.Wait(rtc::Event::kForever);

  // The VideoProcessor must be destroyed before the codecs.
  DestroyEncoderAndDecoder();

  analysis_frame_reader_->Close();

  // Close visualization files.
  if (encoded_frame_writer_) {
    EXPECT_TRUE(encoded_frame_writer_->Close());
  }
  if (decoded_frame_writer_) {
    decoded_frame_writer_->Close();
  }
}

void VideoProcessorIntegrationTest::PrintSettings() const {
  printf("VideoProcessor settings\n==\n");
  printf(" Total # of frames      : %d",
         analysis_frame_reader_->NumberOfFrames());
  printf("%s\n", config_.ToString().c_str());

  printf("VideoProcessorIntegrationTest settings\n==\n");
  const char* encoder_name = encoder_->ImplementationName();
  printf(" Encoder implementation name: %s\n", encoder_name);
  const char* decoder_name = decoder_->ImplementationName();
  printf(" Decoder implementation name: %s\n", decoder_name);
  if (strcmp(encoder_name, decoder_name) == 0) {
    printf(" Codec implementation name  : %s_%s\n", config_.CodecName().c_str(),
           encoder_name);
  }
  printf("\n");
}

void VideoProcessorIntegrationTest::AnalyzeAndPrintStats(
    const std::vector<FrameStatistic>& stats,
    const float target_bitrate_kbps,
    const float target_framerate_fps,
    const float input_duration_sec,
    const RateControlThresholds* rc_thresholds,
    const QualityThresholds* quality_thresholds,
    const BitstreamThresholds* bs_thresholds) {
  const size_t num_input_frames = stats.size();
  size_t num_dropped_frames = 0;
  size_t num_decoded_frames = 0;
  size_t num_spatial_resizes = 0;
  size_t num_key_frames = 0;
  size_t max_nalu_size_bytes = 0;

  size_t encoded_bytes = 0;
  float buffer_level_kbits = 0.0;
  float time_to_reach_target_bitrate_sec = -1.0;

  Statistics buffer_level_sec;
  Statistics key_frame_size_bytes;
  Statistics delta_frame_size_bytes;

  Statistics encoding_time_us;
  Statistics decoding_time_us;
  Statistics psnr;
  Statistics ssim;

  Statistics qp;

  FrameStatistic last_successfully_decoded_frame(0, 0);
  for (size_t frame_idx = 0; frame_idx < stats.size(); ++frame_idx) {
    const FrameStatistic& frame_stat = stats[frame_idx];

    const float time_since_first_input_sec =
        frame_idx == 0
            ? 0.0
            : 1.0 * (frame_stat.rtp_timestamp - stats[0].rtp_timestamp) /
                  kRtpClockRateHz;
    const float time_since_last_input_sec =
        frame_idx == 0 ? 0.0
                       : 1.0 *
                             (frame_stat.rtp_timestamp -
                              stats[frame_idx - 1].rtp_timestamp) /
                             kRtpClockRateHz;

    // Testing framework uses constant input framerate. This guarantees even
    // sampling, which is important, of buffer level.
    buffer_level_kbits -= time_since_last_input_sec * target_bitrate_kbps;
    buffer_level_kbits = std::max(0.0f, buffer_level_kbits);
    buffer_level_kbits += 8.0 * frame_stat.encoded_frame_size_bytes / 1000;
    buffer_level_sec.AddSample(buffer_level_kbits / target_bitrate_kbps);

    encoded_bytes += frame_stat.encoded_frame_size_bytes;
    if (frame_stat.encoded_frame_size_bytes == 0) {
      ++num_dropped_frames;
    } else {
      if (frame_stat.frame_type == kVideoFrameKey) {
        key_frame_size_bytes.AddSample(frame_stat.encoded_frame_size_bytes);
        ++num_key_frames;
      } else {
        delta_frame_size_bytes.AddSample(frame_stat.encoded_frame_size_bytes);
      }

      encoding_time_us.AddSample(frame_stat.encode_time_us);
      qp.AddSample(frame_stat.qp);

      max_nalu_size_bytes =
          std::max(max_nalu_size_bytes, frame_stat.max_nalu_size_bytes);
    }

    if (frame_stat.decoding_successful) {
      psnr.AddSample(frame_stat.psnr);
      ssim.AddSample(frame_stat.ssim);
      if (num_decoded_frames > 0) {
        if (last_successfully_decoded_frame.decoded_width !=
                frame_stat.decoded_width ||
            last_successfully_decoded_frame.decoded_height !=
                frame_stat.decoded_height) {
          ++num_spatial_resizes;
        }
      }
      decoding_time_us.AddSample(frame_stat.decode_time_us);
      last_successfully_decoded_frame = frame_stat;
      ++num_decoded_frames;
    }

    if (time_to_reach_target_bitrate_sec < 0 && frame_idx > 0) {
      const float curr_bitrate_kbps =
          (8.0 * encoded_bytes / 1000) / time_since_first_input_sec;
      const float bitrate_mismatch_percent =
          100 * std::fabs(curr_bitrate_kbps - target_bitrate_kbps) /
          target_bitrate_kbps;
      if (bitrate_mismatch_percent < kMaxBitrateMismatchPercent) {
        time_to_reach_target_bitrate_sec = time_since_first_input_sec;
      }
    }
  }

  const float encoded_bitrate_kbps =
      8 * encoded_bytes / input_duration_sec / 1000;
  const float bitrate_mismatch_percent =
      100 * std::fabs(encoded_bitrate_kbps - target_bitrate_kbps) /
      target_bitrate_kbps;
  const size_t num_encoded_frames = num_input_frames - num_dropped_frames;
  const float encoded_framerate_fps = num_encoded_frames / input_duration_sec;
  const float decoded_framerate_fps = num_decoded_frames / input_duration_sec;
  const float framerate_mismatch_percent =
      100 * std::fabs(decoded_framerate_fps - target_framerate_fps) /
      target_framerate_fps;
  const float max_key_frame_delay_sec =
      8 * key_frame_size_bytes.Max() / 1000 / target_bitrate_kbps;
  const float max_delta_frame_delay_sec =
      8 * delta_frame_size_bytes.Max() / 1000 / target_bitrate_kbps;

  printf("Target bitrate                 : %f kbps\n", target_bitrate_kbps);
  printf("Encoded bitrate                : %f kbps\n", encoded_bitrate_kbps);
  printf("Bitrate mismatch               : %f %%\n", bitrate_mismatch_percent);
  printf("Time to reach target bitrate   : %f sec\n",
         time_to_reach_target_bitrate_sec);
  printf("Target framerate               : %f fps\n", target_framerate_fps);
  printf("Encoding framerate             : %f fps\n", encoded_framerate_fps);
  printf("Decoding framerate             : %f fps\n", decoded_framerate_fps);
  printf("Frame encoding time            : %f us\n", encoding_time_us.Mean());
  printf("Frame decoding time            : %f us\n", decoding_time_us.Mean());
  printf("Framerate mismatch percent     : %f %%\n",
         framerate_mismatch_percent);
  printf("Avg buffer level               : %f sec\n", buffer_level_sec.Mean());
  printf("Max key frame delay            : %f sec\n", max_key_frame_delay_sec);
  printf("Max delta frame delay          : %f sec\n",
         max_delta_frame_delay_sec);
  printf("Avg key frame size             : %f bytes\n",
         key_frame_size_bytes.Mean());
  printf("Avg delta frame size           : %f bytes\n",
         delta_frame_size_bytes.Mean());
  printf("Avg QP                         : %f\n", qp.Mean());
  printf("Avg PSNR                       : %f dB\n", psnr.Mean());
  printf("Min PSNR                       : %f dB\n", psnr.Min());
  printf("Avg SSIM                       : %f\n", ssim.Mean());
  printf("Min SSIM                       : %f\n", ssim.Min());
  printf("# input frames                 : %zu\n", num_input_frames);
  printf("# encoded frames               : %zu\n", num_encoded_frames);
  printf("# decoded frames               : %zu\n", num_decoded_frames);
  printf("# dropped frames               : %zu\n", num_dropped_frames);
  printf("# key frames                   : %zu\n", num_key_frames);
  printf("# encoded bytes                : %zu\n", encoded_bytes);
  printf("# spatial resizes              : %zu\n", num_spatial_resizes);

  if (rc_thresholds) {
    EXPECT_LE(bitrate_mismatch_percent,
              rc_thresholds->max_avg_bitrate_mismatch_percent);
    EXPECT_LE(time_to_reach_target_bitrate_sec,
              rc_thresholds->max_time_to_reach_target_bitrate_sec);
    EXPECT_LE(framerate_mismatch_percent,
              rc_thresholds->max_avg_framerate_mismatch_percent);
    EXPECT_LE(buffer_level_sec.Mean(), rc_thresholds->max_avg_buffer_level_sec);
    EXPECT_LE(max_key_frame_delay_sec,
              rc_thresholds->max_max_key_frame_delay_sec);
    EXPECT_LE(max_delta_frame_delay_sec,
              rc_thresholds->max_max_delta_frame_delay_sec);
    EXPECT_LE(num_spatial_resizes, rc_thresholds->max_num_spatial_resizes);
    EXPECT_LE(num_key_frames, rc_thresholds->max_num_key_frames);
  }

  if (quality_thresholds) {
    EXPECT_GT(psnr.Mean(), quality_thresholds->min_avg_psnr);
    EXPECT_GT(psnr.Min(), quality_thresholds->min_min_psnr);
    EXPECT_GT(ssim.Mean(), quality_thresholds->min_avg_ssim);
    EXPECT_GT(ssim.Min(), quality_thresholds->min_min_ssim);
  }

  if (bs_thresholds) {
    EXPECT_LE(max_nalu_size_bytes, bs_thresholds->max_max_nalu_size_bytes);
  }
}

void VideoProcessorIntegrationTest::PrintFrameLevelStats(
    const std::vector<FrameStatistic>& stats) const {
  for (auto& frame_stat : stats) {
    printf("%s\n", frame_stat.ToString().c_str());
  }
}

}  // namespace test
}  // namespace webrtc
