/*
 *  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 "modules/video_coding/codecs/test/videoprocessor.h"

#include <string.h>

#include <algorithm>
#include <cstddef>
#include <limits>
#include <memory>
#include <utility>

#include "api/scoped_refptr.h"
#include "api/video/builtin_video_bitrate_allocator_factory.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_bitrate_allocator_factory.h"
#include "api/video/video_frame_buffer.h"
#include "api/video/video_rotation.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "common_video/h264/h264_common.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/video_coding/codecs/interface/common_constants.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/checks.h"
#include "rtc_base/task_utils/to_queued_task.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"
#include "third_party/libyuv/include/libyuv/compare.h"
#include "third_party/libyuv/include/libyuv/scale.h"

namespace webrtc {
namespace test {

namespace {
const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
const int kMaxBufferedInputFrames = 20;

const VideoEncoder::Capabilities kCapabilities(false);

size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame,
                           const VideoCodecTestFixture::Config& config) {
  if (config.codec_settings.codecType != kVideoCodecH264)
    return 0;

  std::vector<webrtc::H264::NaluIndex> nalu_indices =
      webrtc::H264::FindNaluIndices(encoded_frame.data(), encoded_frame.size());

  RTC_CHECK(!nalu_indices.empty());

  size_t max_size = 0;
  for (const webrtc::H264::NaluIndex& index : nalu_indices)
    max_size = std::max(max_size, index.payload_size);

  return max_size;
}

size_t GetTemporalLayerIndex(const CodecSpecificInfo& codec_specific) {
  size_t temporal_idx = 0;
  if (codec_specific.codecType == kVideoCodecVP8) {
    temporal_idx = codec_specific.codecSpecific.VP8.temporalIdx;
  } else if (codec_specific.codecType == kVideoCodecVP9) {
    temporal_idx = codec_specific.codecSpecific.VP9.temporal_idx;
  }
  if (temporal_idx == kNoTemporalIdx) {
    temporal_idx = 0;
  }
  return temporal_idx;
}

int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) {
  int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec;
  RTC_DCHECK_GE(diff_us, std::numeric_limits<int>::min());
  RTC_DCHECK_LE(diff_us, std::numeric_limits<int>::max());
  return static_cast<int>(diff_us);
}

void CalculateFrameQuality(const I420BufferInterface& ref_buffer,
                           const I420BufferInterface& dec_buffer,
                           VideoCodecTestStats::FrameStatistics* frame_stat,
                           bool calc_ssim) {
  if (ref_buffer.width() != dec_buffer.width() ||
      ref_buffer.height() != dec_buffer.height()) {
    RTC_CHECK_GE(ref_buffer.width(), dec_buffer.width());
    RTC_CHECK_GE(ref_buffer.height(), dec_buffer.height());
    // Downscale reference frame.
    rtc::scoped_refptr<I420Buffer> scaled_buffer =
        I420Buffer::Create(dec_buffer.width(), dec_buffer.height());
    I420Scale(ref_buffer.DataY(), ref_buffer.StrideY(), ref_buffer.DataU(),
              ref_buffer.StrideU(), ref_buffer.DataV(), ref_buffer.StrideV(),
              ref_buffer.width(), ref_buffer.height(),
              scaled_buffer->MutableDataY(), scaled_buffer->StrideY(),
              scaled_buffer->MutableDataU(), scaled_buffer->StrideU(),
              scaled_buffer->MutableDataV(), scaled_buffer->StrideV(),
              scaled_buffer->width(), scaled_buffer->height(),
              libyuv::kFilterBox);

    CalculateFrameQuality(*scaled_buffer, dec_buffer, frame_stat, calc_ssim);
  } else {
    const uint64_t sse_y = libyuv::ComputeSumSquareErrorPlane(
        dec_buffer.DataY(), dec_buffer.StrideY(), ref_buffer.DataY(),
        ref_buffer.StrideY(), dec_buffer.width(), dec_buffer.height());

    const uint64_t sse_u = libyuv::ComputeSumSquareErrorPlane(
        dec_buffer.DataU(), dec_buffer.StrideU(), ref_buffer.DataU(),
        ref_buffer.StrideU(), dec_buffer.width() / 2, dec_buffer.height() / 2);

    const uint64_t sse_v = libyuv::ComputeSumSquareErrorPlane(
        dec_buffer.DataV(), dec_buffer.StrideV(), ref_buffer.DataV(),
        ref_buffer.StrideV(), dec_buffer.width() / 2, dec_buffer.height() / 2);

    const size_t num_y_samples = dec_buffer.width() * dec_buffer.height();
    const size_t num_u_samples =
        dec_buffer.width() / 2 * dec_buffer.height() / 2;

    frame_stat->psnr_y = libyuv::SumSquareErrorToPsnr(sse_y, num_y_samples);
    frame_stat->psnr_u = libyuv::SumSquareErrorToPsnr(sse_u, num_u_samples);
    frame_stat->psnr_v = libyuv::SumSquareErrorToPsnr(sse_v, num_u_samples);
    frame_stat->psnr = libyuv::SumSquareErrorToPsnr(
        sse_y + sse_u + sse_v, num_y_samples + 2 * num_u_samples);

    if (calc_ssim) {
      frame_stat->ssim = I420SSIM(ref_buffer, dec_buffer);
    }
  }
}

}  // namespace

VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
                               VideoDecoderList* decoders,
                               FrameReader* input_frame_reader,
                               const VideoCodecTestFixture::Config& config,
                               VideoCodecTestStatsImpl* stats,
                               IvfFileWriterMap* encoded_frame_writers,
                               FrameWriterList* decoded_frame_writers)
    : config_(config),
      num_simulcast_or_spatial_layers_(
          std::max(config_.NumberOfSimulcastStreams(),
                   config_.NumberOfSpatialLayers())),
      analyze_frame_quality_(!config_.measure_cpu),
      stats_(stats),
      encoder_(encoder),
      decoders_(decoders),
      bitrate_allocator_(
          CreateBuiltinVideoBitrateAllocatorFactory()
              ->CreateVideoBitrateAllocator(config_.codec_settings)),
      framerate_fps_(0),
      encode_callback_(this),
      input_frame_reader_(input_frame_reader),
      merged_encoded_frames_(num_simulcast_or_spatial_layers_),
      encoded_frame_writers_(encoded_frame_writers),
      decoded_frame_writers_(decoded_frame_writers),
      last_inputed_frame_num_(0),
      last_inputed_timestamp_(0),
      first_encoded_frame_(num_simulcast_or_spatial_layers_, true),
      last_encoded_frame_num_(num_simulcast_or_spatial_layers_),
      first_decoded_frame_(num_simulcast_or_spatial_layers_, true),
      last_decoded_frame_num_(num_simulcast_or_spatial_layers_),
      last_decoded_frame_buffer_(num_simulcast_or_spatial_layers_),
      post_encode_time_ns_(0),
      is_finalized_(false) {
  // Sanity checks.
  RTC_CHECK(TaskQueueBase::Current())
      << "VideoProcessor must be run on a task queue.";
  RTC_CHECK(stats_);
  RTC_CHECK(encoder_);
  RTC_CHECK(decoders_);
  RTC_CHECK_EQ(decoders_->size(), num_simulcast_or_spatial_layers_);
  RTC_CHECK(input_frame_reader_);
  RTC_CHECK(encoded_frame_writers_);
  RTC_CHECK(!decoded_frame_writers ||
            decoded_frame_writers->size() == num_simulcast_or_spatial_layers_);

  // Setup required callbacks for the encoder and decoder and initialize them.
  RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(&encode_callback_),
               WEBRTC_VIDEO_CODEC_OK);

  // Initialize codecs so that they are ready to receive frames.
  RTC_CHECK_EQ(encoder_->InitEncode(
                   &config_.codec_settings,
                   VideoEncoder::Settings(
                       kCapabilities, static_cast<int>(config_.NumberOfCores()),
                       config_.max_payload_size_bytes)),
               WEBRTC_VIDEO_CODEC_OK);

  for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
    decode_callback_.push_back(
        std::make_unique<VideoProcessorDecodeCompleteCallback>(this, i));
    VideoDecoder::Settings decoder_settings;
    decoder_settings.set_max_render_resolution(
        {config_.codec_settings.width, config_.codec_settings.height});
    decoder_settings.set_codec_type(config_.codec_settings.codecType);
    decoder_settings.set_number_of_cores(config_.NumberOfCores());
    RTC_CHECK(decoders_->at(i)->Configure(decoder_settings));
    RTC_CHECK_EQ(decoders_->at(i)->RegisterDecodeCompleteCallback(
                     decode_callback_.at(i).get()),
                 WEBRTC_VIDEO_CODEC_OK);
  }
}

VideoProcessor::~VideoProcessor() {
  RTC_DCHECK_RUN_ON(&sequence_checker_);

  if (!is_finalized_) {
    Finalize();
  }

  // Explicitly reset codecs, in case they don't do that themselves when they
  // go out of scope.
  RTC_CHECK_EQ(encoder_->Release(), WEBRTC_VIDEO_CODEC_OK);
  encoder_->RegisterEncodeCompleteCallback(nullptr);
  for (auto& decoder : *decoders_) {
    RTC_CHECK_EQ(decoder->Release(), WEBRTC_VIDEO_CODEC_OK);
    decoder->RegisterDecodeCompleteCallback(nullptr);
  }

  // Sanity check.
  RTC_CHECK_LE(input_frames_.size(), kMaxBufferedInputFrames);
}

void VideoProcessor::ProcessFrame() {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  RTC_DCHECK(!is_finalized_);

  const size_t frame_number = last_inputed_frame_num_++;

  // Get input frame and store for future quality calculation.
  rtc::scoped_refptr<I420BufferInterface> buffer =
      input_frame_reader_->ReadFrame();
  RTC_CHECK(buffer) << "Tried to read too many frames from the file.";
  const size_t timestamp =
      last_inputed_timestamp_ +
      static_cast<size_t>(kVideoPayloadTypeFrequency / framerate_fps_);
  VideoFrame input_frame =
      VideoFrame::Builder()
          .set_video_frame_buffer(buffer)
          .set_timestamp_rtp(static_cast<uint32_t>(timestamp))
          .set_timestamp_ms(static_cast<int64_t>(timestamp / kMsToRtpTimestamp))
          .set_rotation(webrtc::kVideoRotation_0)
          .build();
  // Store input frame as a reference for quality calculations.
  if (config_.decode && !config_.measure_cpu) {
    if (input_frames_.size() == kMaxBufferedInputFrames) {
      input_frames_.erase(input_frames_.begin());
    }

    if (config_.reference_width != -1 && config_.reference_height != -1 &&
        (input_frame.width() != config_.reference_width ||
         input_frame.height() != config_.reference_height)) {
      rtc::scoped_refptr<I420Buffer> scaled_buffer = I420Buffer::Create(
          config_.codec_settings.width, config_.codec_settings.height);
      scaled_buffer->ScaleFrom(*input_frame.video_frame_buffer()->ToI420());

      VideoFrame scaled_reference_frame = input_frame;
      scaled_reference_frame.set_video_frame_buffer(scaled_buffer);
      input_frames_.emplace(frame_number, scaled_reference_frame);

      if (config_.reference_width == config_.codec_settings.width &&
          config_.reference_height == config_.codec_settings.height) {
        // Both encoding and comparison uses the same down-scale factor, reuse
        // it for encoder below.
        input_frame = scaled_reference_frame;
      }
    } else {
      input_frames_.emplace(frame_number, input_frame);
    }
  }
  last_inputed_timestamp_ = timestamp;

  post_encode_time_ns_ = 0;

  // Create frame statistics object for all simulcast/spatial layers.
  for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
    FrameStatistics frame_stat(frame_number, timestamp, i);
    stats_->AddFrame(frame_stat);
  }

  // For the highest measurement accuracy of the encode time, the start/stop
  // time recordings should wrap the Encode call as tightly as possible.
  const int64_t encode_start_ns = rtc::TimeNanos();
  for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
    FrameStatistics* frame_stat = stats_->GetFrame(frame_number, i);
    frame_stat->encode_start_ns = encode_start_ns;
  }

  if (input_frame.width() != config_.codec_settings.width ||
      input_frame.height() != config_.codec_settings.height) {
    rtc::scoped_refptr<I420Buffer> scaled_buffer = I420Buffer::Create(
        config_.codec_settings.width, config_.codec_settings.height);
    scaled_buffer->ScaleFrom(*input_frame.video_frame_buffer()->ToI420());
    input_frame.set_video_frame_buffer(scaled_buffer);
  }

  // Encode.
  const std::vector<VideoFrameType> frame_types =
      (frame_number == 0)
          ? std::vector<VideoFrameType>{VideoFrameType::kVideoFrameKey}
          : std::vector<VideoFrameType>{VideoFrameType::kVideoFrameDelta};
  const int encode_return_code = encoder_->Encode(input_frame, &frame_types);
  for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {
    FrameStatistics* frame_stat = stats_->GetFrame(frame_number, i);
    frame_stat->encode_return_code = encode_return_code;
  }
}

void VideoProcessor::SetRates(size_t bitrate_kbps, double framerate_fps) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  RTC_DCHECK(!is_finalized_);

  framerate_fps_ = framerate_fps;
  bitrate_allocation_ =
      bitrate_allocator_->Allocate(VideoBitrateAllocationParameters(
          static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_));
  encoder_->SetRates(
      VideoEncoder::RateControlParameters(bitrate_allocation_, framerate_fps_));
}

int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded(
    VideoFrame& image) {
  // Post the callback to the right task queue, if needed.
  if (!task_queue_->IsCurrent()) {
    // There might be a limited amount of output buffers, make a copy to make
    // sure we don't block the decoder.
    VideoFrame copy = VideoFrame::Builder()
                          .set_video_frame_buffer(I420Buffer::Copy(
                              *image.video_frame_buffer()->ToI420()))
                          .set_rotation(image.rotation())
                          .set_timestamp_us(image.timestamp_us())
                          .set_id(image.id())
                          .build();
    copy.set_timestamp(image.timestamp());

    task_queue_->PostTask(ToQueuedTask([this, copy]() {
      video_processor_->FrameDecoded(copy, simulcast_svc_idx_);
    }));
    return 0;
  }
  video_processor_->FrameDecoded(image, simulcast_svc_idx_);
  return 0;
}

void VideoProcessor::FrameEncoded(
    const webrtc::EncodedImage& encoded_image,
    const webrtc::CodecSpecificInfo& codec_specific) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);

  // For the highest measurement accuracy of the encode time, the start/stop
  // time recordings should wrap the Encode call as tightly as possible.
  const int64_t encode_stop_ns = rtc::TimeNanos();

  const VideoCodecType codec_type = codec_specific.codecType;
  if (config_.encoded_frame_checker) {
    config_.encoded_frame_checker->CheckEncodedFrame(codec_type, encoded_image);
  }

  // Layer metadata.
  size_t spatial_idx = encoded_image.SpatialIndex().value_or(0);
  size_t temporal_idx = GetTemporalLayerIndex(codec_specific);

  FrameStatistics* frame_stat =
      stats_->GetFrameWithTimestamp(encoded_image.Timestamp(), spatial_idx);
  const size_t frame_number = frame_stat->frame_number;

  // Ensure that the encode order is monotonically increasing, within this
  // simulcast/spatial layer.
  RTC_CHECK(first_encoded_frame_[spatial_idx] ||
            last_encoded_frame_num_[spatial_idx] < frame_number);

  // Ensure SVC spatial layers are delivered in ascending order.
  const size_t num_spatial_layers = config_.NumberOfSpatialLayers();
  if (!first_encoded_frame_[spatial_idx] && num_spatial_layers > 1) {
    for (size_t i = 0; i < spatial_idx; ++i) {
      RTC_CHECK_LE(last_encoded_frame_num_[i], frame_number);
    }
    for (size_t i = spatial_idx + 1; i < num_simulcast_or_spatial_layers_;
         ++i) {
      RTC_CHECK_GT(frame_number, last_encoded_frame_num_[i]);
    }
  }
  first_encoded_frame_[spatial_idx] = false;
  last_encoded_frame_num_[spatial_idx] = frame_number;

  // Update frame statistics.
  frame_stat->encoding_successful = true;
  frame_stat->encode_time_us = GetElapsedTimeMicroseconds(
      frame_stat->encode_start_ns, encode_stop_ns - post_encode_time_ns_);
  frame_stat->target_bitrate_kbps =
      bitrate_allocation_.GetTemporalLayerSum(spatial_idx, temporal_idx) / 1000;
  frame_stat->target_framerate_fps = framerate_fps_;
  frame_stat->length_bytes = encoded_image.size();
  frame_stat->frame_type = encoded_image._frameType;
  frame_stat->temporal_idx = temporal_idx;
  frame_stat->max_nalu_size_bytes = GetMaxNaluSizeBytes(encoded_image, config_);
  frame_stat->qp = encoded_image.qp_;

  if (codec_type == kVideoCodecVP9) {
    const CodecSpecificInfoVP9& vp9_info = codec_specific.codecSpecific.VP9;
    frame_stat->inter_layer_predicted = vp9_info.inter_layer_predicted;
    frame_stat->non_ref_for_inter_layer_pred =
        vp9_info.non_ref_for_inter_layer_pred;
  } else {
    frame_stat->inter_layer_predicted = false;
    frame_stat->non_ref_for_inter_layer_pred = true;
  }

  const webrtc::EncodedImage* encoded_image_for_decode = &encoded_image;
  if (config_.decode || !encoded_frame_writers_->empty()) {
    if (num_spatial_layers > 1) {
      encoded_image_for_decode = BuildAndStoreSuperframe(
          encoded_image, codec_type, frame_number, spatial_idx,
          frame_stat->inter_layer_predicted);
    }
  }

  if (config_.decode) {
    DecodeFrame(*encoded_image_for_decode, spatial_idx);

    if (codec_specific.end_of_picture && num_spatial_layers > 1) {
      // If inter-layer prediction is enabled and upper layer was dropped then
      // base layer should be passed to upper layer decoder. Otherwise decoder
      // won't be able to decode next superframe.
      const EncodedImage* base_image = nullptr;
      const FrameStatistics* base_stat = nullptr;
      for (size_t i = 0; i < num_spatial_layers; ++i) {
        const bool layer_dropped = (first_decoded_frame_[i] ||
                                    last_decoded_frame_num_[i] < frame_number);

        // Ensure current layer was decoded.
        RTC_CHECK(layer_dropped == false || i != spatial_idx);

        if (!layer_dropped) {
          base_image = &merged_encoded_frames_[i];
          base_stat =
              stats_->GetFrameWithTimestamp(encoded_image.Timestamp(), i);
        } else if (base_image && !base_stat->non_ref_for_inter_layer_pred) {
          DecodeFrame(*base_image, i);
        }
      }
    }
  } else {
    frame_stat->decode_return_code = WEBRTC_VIDEO_CODEC_NO_OUTPUT;
  }

  // Since frames in higher TLs typically depend on frames in lower TLs,
  // write out frames in lower TLs to bitstream dumps of higher TLs.
  for (size_t write_temporal_idx = temporal_idx;
       write_temporal_idx < config_.NumberOfTemporalLayers();
       ++write_temporal_idx) {
    const VideoProcessor::LayerKey layer_key(spatial_idx, write_temporal_idx);
    auto it = encoded_frame_writers_->find(layer_key);
    if (it != encoded_frame_writers_->cend()) {
      RTC_CHECK(it->second->WriteFrame(*encoded_image_for_decode,
                                       config_.codec_settings.codecType));
    }
  }

  if (!config_.encode_in_real_time) {
    // To get pure encode time for next layers, measure time spent in encode
    // callback and subtract it from encode time of next layers.
    post_encode_time_ns_ += rtc::TimeNanos() - encode_stop_ns;
  }
}

void VideoProcessor::CalcFrameQuality(const I420BufferInterface& decoded_frame,
                                      FrameStatistics* frame_stat) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);

  const auto reference_frame = input_frames_.find(frame_stat->frame_number);
  RTC_CHECK(reference_frame != input_frames_.cend())
      << "The codecs are either buffering too much, dropping too much, or "
         "being too slow relative to the input frame rate.";

  // SSIM calculation is not optimized. Skip it in real-time mode.
  const bool calc_ssim = !config_.encode_in_real_time;
  CalculateFrameQuality(*reference_frame->second.video_frame_buffer()->ToI420(),
                        decoded_frame, frame_stat, calc_ssim);

  frame_stat->quality_analysis_successful = true;
}

void VideoProcessor::WriteDecodedFrame(const I420BufferInterface& decoded_frame,
                                       FrameWriter& frame_writer) {
  int input_video_width = config_.codec_settings.width;
  int input_video_height = config_.codec_settings.height;

  rtc::scoped_refptr<I420Buffer> scaled_buffer;
  const I420BufferInterface* scaled_frame;

  if (decoded_frame.width() == input_video_width &&
      decoded_frame.height() == input_video_height) {
    scaled_frame = &decoded_frame;
  } else {
    EXPECT_DOUBLE_EQ(
        static_cast<double>(input_video_width) / input_video_height,
        static_cast<double>(decoded_frame.width()) / decoded_frame.height());

    scaled_buffer = I420Buffer::Create(input_video_width, input_video_height);
    scaled_buffer->ScaleFrom(decoded_frame);

    scaled_frame = scaled_buffer;
  }

  // Ensure there is no padding.
  RTC_CHECK_EQ(scaled_frame->StrideY(), input_video_width);
  RTC_CHECK_EQ(scaled_frame->StrideU(), input_video_width / 2);
  RTC_CHECK_EQ(scaled_frame->StrideV(), input_video_width / 2);

  RTC_CHECK_EQ(3 * input_video_width * input_video_height / 2,
               frame_writer.FrameLength());

  RTC_CHECK(frame_writer.WriteFrame(scaled_frame->DataY()));
}

void VideoProcessor::FrameDecoded(const VideoFrame& decoded_frame,
                                  size_t spatial_idx) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);

  // For the highest measurement accuracy of the decode time, the start/stop
  // time recordings should wrap the Decode call as tightly as possible.
  const int64_t decode_stop_ns = rtc::TimeNanos();

  FrameStatistics* frame_stat =
      stats_->GetFrameWithTimestamp(decoded_frame.timestamp(), spatial_idx);
  const size_t frame_number = frame_stat->frame_number;

  if (!first_decoded_frame_[spatial_idx]) {
    for (size_t dropped_frame_number = last_decoded_frame_num_[spatial_idx] + 1;
         dropped_frame_number < frame_number; ++dropped_frame_number) {
      FrameStatistics* dropped_frame_stat =
          stats_->GetFrame(dropped_frame_number, spatial_idx);

      if (analyze_frame_quality_ && config_.analyze_quality_of_dropped_frames) {
        // Calculate frame quality comparing input frame with last decoded one.
        CalcFrameQuality(*last_decoded_frame_buffer_[spatial_idx],
                         dropped_frame_stat);
      }

      if (decoded_frame_writers_ != nullptr) {
        // Fill drops with last decoded frame to make them look like freeze at
        // playback and to keep decoded layers in sync.
        WriteDecodedFrame(*last_decoded_frame_buffer_[spatial_idx],
                          *decoded_frame_writers_->at(spatial_idx));
      }
    }
  }

  // Ensure that the decode order is monotonically increasing, within this
  // simulcast/spatial layer.
  RTC_CHECK(first_decoded_frame_[spatial_idx] ||
            last_decoded_frame_num_[spatial_idx] < frame_number);
  first_decoded_frame_[spatial_idx] = false;
  last_decoded_frame_num_[spatial_idx] = frame_number;

  // Update frame statistics.
  frame_stat->decoding_successful = true;
  frame_stat->decode_time_us =
      GetElapsedTimeMicroseconds(frame_stat->decode_start_ns, decode_stop_ns);
  frame_stat->decoded_width = decoded_frame.width();
  frame_stat->decoded_height = decoded_frame.height();

  // Skip quality metrics calculation to not affect CPU usage.
  if (analyze_frame_quality_ || decoded_frame_writers_) {
    // Save last decoded frame to handle possible future drops.
    rtc::scoped_refptr<I420BufferInterface> i420buffer =
        decoded_frame.video_frame_buffer()->ToI420();

    // Copy decoded frame to a buffer without padding/stride such that we can
    // dump Y, U and V planes into a file in one shot.
    last_decoded_frame_buffer_[spatial_idx] = I420Buffer::Copy(
        i420buffer->width(), i420buffer->height(), i420buffer->DataY(),
        i420buffer->StrideY(), i420buffer->DataU(), i420buffer->StrideU(),
        i420buffer->DataV(), i420buffer->StrideV());
  }

  if (analyze_frame_quality_) {
    CalcFrameQuality(*decoded_frame.video_frame_buffer()->ToI420(), frame_stat);
  }

  if (decoded_frame_writers_ != nullptr) {
    WriteDecodedFrame(*last_decoded_frame_buffer_[spatial_idx],
                      *decoded_frame_writers_->at(spatial_idx));
  }

  // Erase all buffered input frames that we have moved past for all
  // simulcast/spatial layers. Never buffer more than
  // `kMaxBufferedInputFrames` frames, to protect against long runs of
  // consecutive frame drops for a particular layer.
  const auto min_last_decoded_frame_num = std::min_element(
      last_decoded_frame_num_.cbegin(), last_decoded_frame_num_.cend());
  const size_t min_buffered_frame_num =
      std::max(0, static_cast<int>(frame_number) - kMaxBufferedInputFrames + 1);
  RTC_CHECK(min_last_decoded_frame_num != last_decoded_frame_num_.cend());
  const auto input_frames_erase_before = input_frames_.lower_bound(
      std::max(*min_last_decoded_frame_num, min_buffered_frame_num));
  input_frames_.erase(input_frames_.cbegin(), input_frames_erase_before);
}

void VideoProcessor::DecodeFrame(const EncodedImage& encoded_image,
                                 size_t spatial_idx) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  FrameStatistics* frame_stat =
      stats_->GetFrameWithTimestamp(encoded_image.Timestamp(), spatial_idx);

  frame_stat->decode_start_ns = rtc::TimeNanos();
  frame_stat->decode_return_code =
      decoders_->at(spatial_idx)->Decode(encoded_image, false, 0);
}

const webrtc::EncodedImage* VideoProcessor::BuildAndStoreSuperframe(
    const EncodedImage& encoded_image,
    const VideoCodecType codec,
    size_t frame_number,
    size_t spatial_idx,
    bool inter_layer_predicted) {
  // Should only be called for SVC.
  RTC_CHECK_GT(config_.NumberOfSpatialLayers(), 1);

  EncodedImage base_image;
  RTC_CHECK_EQ(base_image.size(), 0);

  // Each SVC layer is decoded with dedicated decoder. Find the nearest
  // non-dropped base frame and merge it and current frame into superframe.
  if (inter_layer_predicted) {
    for (int base_idx = static_cast<int>(spatial_idx) - 1; base_idx >= 0;
         --base_idx) {
      EncodedImage lower_layer = merged_encoded_frames_.at(base_idx);
      if (lower_layer.Timestamp() == encoded_image.Timestamp()) {
        base_image = lower_layer;
        break;
      }
    }
  }
  const size_t payload_size_bytes = base_image.size() + encoded_image.size();

  auto buffer = EncodedImageBuffer::Create(payload_size_bytes);
  if (base_image.size()) {
    RTC_CHECK(base_image.data());
    memcpy(buffer->data(), base_image.data(), base_image.size());
  }
  memcpy(buffer->data() + base_image.size(), encoded_image.data(),
         encoded_image.size());

  EncodedImage copied_image = encoded_image;
  copied_image.SetEncodedData(buffer);
  if (base_image.size())
    copied_image._frameType = base_image._frameType;

  // Replace previous EncodedImage for this spatial layer.
  merged_encoded_frames_.at(spatial_idx) = std::move(copied_image);

  return &merged_encoded_frames_.at(spatial_idx);
}

void VideoProcessor::Finalize() {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  RTC_DCHECK(!is_finalized_);
  is_finalized_ = true;

  if (!(analyze_frame_quality_ && config_.analyze_quality_of_dropped_frames) &&
      decoded_frame_writers_ == nullptr) {
    return;
  }

  for (size_t spatial_idx = 0; spatial_idx < num_simulcast_or_spatial_layers_;
       ++spatial_idx) {
    if (first_decoded_frame_[spatial_idx]) {
      continue;  // No decoded frames on this spatial layer.
    }

    for (size_t dropped_frame_number = last_decoded_frame_num_[spatial_idx] + 1;
         dropped_frame_number < last_inputed_frame_num_;
         ++dropped_frame_number) {
      FrameStatistics* frame_stat =
          stats_->GetFrame(dropped_frame_number, spatial_idx);

      RTC_DCHECK(!frame_stat->decoding_successful);

      if (analyze_frame_quality_ && config_.analyze_quality_of_dropped_frames) {
        CalcFrameQuality(*last_decoded_frame_buffer_[spatial_idx], frame_stat);
      }

      if (decoded_frame_writers_ != nullptr) {
        WriteDecodedFrame(*last_decoded_frame_buffer_[spatial_idx],
                          *decoded_frame_writers_->at(spatial_idx));
      }
    }
  }
}

}  // namespace test
}  // namespace webrtc
