/*
 *  Copyright (c) 2019 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 "test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h"

#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>

#include "absl/types/optional.h"
#include "api/video/i420_buffer.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/logging.h"
#include "test/pc/e2e/analyzer/video/simulcast_dummy_buffer_helper.h"

namespace webrtc {
namespace webrtc_pc_e2e {

QualityAnalyzingVideoDecoder::QualityAnalyzingVideoDecoder(
    int id,
    std::unique_ptr<VideoDecoder> delegate,
    EncodedImageDataExtractor* extractor,
    VideoQualityAnalyzerInterface* analyzer)
    : id_(id),
      implementation_name_("AnalyzingDecoder-" +
                           std::string(delegate->ImplementationName())),
      delegate_(std::move(delegate)),
      extractor_(extractor),
      analyzer_(analyzer) {
  analyzing_callback_ = std::make_unique<DecoderCallback>(this);
}
QualityAnalyzingVideoDecoder::~QualityAnalyzingVideoDecoder() = default;

int32_t QualityAnalyzingVideoDecoder::InitDecode(
    const VideoCodec* codec_settings,
    int32_t number_of_cores) {
  return delegate_->InitDecode(codec_settings, number_of_cores);
}

int32_t QualityAnalyzingVideoDecoder::Decode(const EncodedImage& input_image,
                                             bool missing_frames,
                                             int64_t render_time_ms) {
  // Image  extractor extracts id from provided EncodedImage and also returns
  // the image with the original buffer. Buffer can be modified in place, so
  // owner of original buffer will be responsible for deleting it, or extractor
  // can create a new buffer. In such case extractor will be responsible for
  // deleting it.
  EncodedImageExtractionResult out = extractor_->ExtractData(input_image, id_);

  if (out.discard) {
    // To partly emulate behavior of Selective Forwarding Unit (SFU) in the
    // test, on receiver side we will "discard" frames from irrelevant streams.
    // When all encoded images were marked to discarded, black frame have to be
    // returned. Because simulcast streams will be received by receiver as 3
    // different independent streams we don't want that irrelevant streams
    // affect video quality metrics and also we don't want to use CPU time to
    // decode them to prevent regressions on relevant streams. Also we can't
    // just drop frame, because in such case, receiving part will be confused
    // with all frames missing and will request a key frame, which will result
    // into extra load on network and sender side. Because of it, discarded
    // image will be always decoded as black frame and will be passed to
    // callback directly without reaching decoder and video quality analyzer.
    //
    // For more details see QualityAnalyzingVideoEncoder.
    return analyzing_callback_->IrrelevantSimulcastStreamDecoded(
        out.id, input_image.Timestamp());
  }

  EncodedImage* origin_image;
  {
    rtc::CritScope crit(&lock_);
    // Store id to be able to retrieve it in analyzing callback.
    timestamp_to_frame_id_.insert({input_image.Timestamp(), out.id});
    // Store encoded image to prevent its destruction while it is used in
    // decoder.
    origin_image = &(
        decoding_images_.insert({out.id, std::move(out.image)}).first->second);
  }
  // We can safely dereference |origin_image|, because it can be removed from
  // the map only after |delegate_| Decode method will be invoked. Image will be
  // removed inside DecodedImageCallback, which can be done on separate thread.
  analyzer_->OnFramePreDecode(out.id, *origin_image);
  int32_t result =
      delegate_->Decode(*origin_image, missing_frames, render_time_ms);
  if (result != WEBRTC_VIDEO_CODEC_OK) {
    // If delegate decoder failed, then cleanup data for this image.
    {
      rtc::CritScope crit(&lock_);
      timestamp_to_frame_id_.erase(input_image.Timestamp());
      decoding_images_.erase(out.id);
    }
    analyzer_->OnDecoderError(out.id, result);
  }
  return result;
}

int32_t QualityAnalyzingVideoDecoder::RegisterDecodeCompleteCallback(
    DecodedImageCallback* callback) {
  analyzing_callback_->SetDelegateCallback(callback);
  return delegate_->RegisterDecodeCompleteCallback(analyzing_callback_.get());
}

int32_t QualityAnalyzingVideoDecoder::Release() {
  // Release decoder first. During release process it can still decode some
  // frames, so we don't take a lock to prevent deadlock.
  int32_t result = delegate_->Release();

  rtc::CritScope crit(&lock_);
  analyzing_callback_->SetDelegateCallback(nullptr);
  timestamp_to_frame_id_.clear();
  decoding_images_.clear();
  return result;
}

bool QualityAnalyzingVideoDecoder::PrefersLateDecoding() const {
  return delegate_->PrefersLateDecoding();
}

const char* QualityAnalyzingVideoDecoder::ImplementationName() const {
  return implementation_name_.c_str();
}

QualityAnalyzingVideoDecoder::DecoderCallback::DecoderCallback(
    QualityAnalyzingVideoDecoder* decoder)
    : decoder_(decoder), delegate_callback_(nullptr) {}
QualityAnalyzingVideoDecoder::DecoderCallback::~DecoderCallback() = default;

void QualityAnalyzingVideoDecoder::DecoderCallback::SetDelegateCallback(
    DecodedImageCallback* delegate) {
  rtc::CritScope crit(&callback_lock_);
  delegate_callback_ = delegate;
}

// We have to implement all next 3 methods because we don't know which one
// exactly is implemented in |delegate_callback_|, so we need to call the same
// method on |delegate_callback_|, as was called on |this| callback.
int32_t QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
    VideoFrame& decodedImage) {
  decoder_->OnFrameDecoded(&decodedImage, /*decode_time_ms=*/absl::nullopt,
                           /*qp=*/absl::nullopt);

  rtc::CritScope crit(&callback_lock_);
  RTC_DCHECK(delegate_callback_);
  return delegate_callback_->Decoded(decodedImage);
}

int32_t QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
    VideoFrame& decodedImage,
    int64_t decode_time_ms) {
  decoder_->OnFrameDecoded(&decodedImage, decode_time_ms, /*qp=*/absl::nullopt);

  rtc::CritScope crit(&callback_lock_);
  RTC_DCHECK(delegate_callback_);
  return delegate_callback_->Decoded(decodedImage, decode_time_ms);
}

void QualityAnalyzingVideoDecoder::DecoderCallback::Decoded(
    VideoFrame& decodedImage,
    absl::optional<int32_t> decode_time_ms,
    absl::optional<uint8_t> qp) {
  decoder_->OnFrameDecoded(&decodedImage, decode_time_ms, qp);

  rtc::CritScope crit(&callback_lock_);
  RTC_DCHECK(delegate_callback_);
  delegate_callback_->Decoded(decodedImage, decode_time_ms, qp);
}

int32_t
QualityAnalyzingVideoDecoder::DecoderCallback::IrrelevantSimulcastStreamDecoded(
    uint16_t frame_id,
    uint32_t timestamp_ms) {
  webrtc::VideoFrame dummy_frame =
      webrtc::VideoFrame::Builder()
          .set_video_frame_buffer(GetDummyFrameBuffer())
          .set_timestamp_rtp(timestamp_ms)
          .set_id(frame_id)
          .build();
  rtc::CritScope crit(&callback_lock_);
  RTC_DCHECK(delegate_callback_);
  delegate_callback_->Decoded(dummy_frame, absl::nullopt, absl::nullopt);
  return WEBRTC_VIDEO_CODEC_OK;
}

rtc::scoped_refptr<webrtc::VideoFrameBuffer>
QualityAnalyzingVideoDecoder::DecoderCallback::GetDummyFrameBuffer() {
  if (!dummy_frame_buffer_) {
    dummy_frame_buffer_ = CreateDummyFrameBuffer();
  }

  return dummy_frame_buffer_;
}

void QualityAnalyzingVideoDecoder::OnFrameDecoded(
    VideoFrame* frame,
    absl::optional<int32_t> decode_time_ms,
    absl::optional<uint8_t> qp) {
  uint16_t frame_id;
  {
    rtc::CritScope crit(&lock_);
    auto it = timestamp_to_frame_id_.find(frame->timestamp());
    if (it == timestamp_to_frame_id_.end()) {
      // Ensure, that we have info about this frame. It can happen that for some
      // reasons decoder response, that he failed to decode, when we were
      // posting frame to it, but then call the callback for this frame.
      RTC_LOG(LS_ERROR) << "QualityAnalyzingVideoDecoder::OnFrameDecoded: No "
                           "frame id for frame for frame->timestamp()="
                        << frame->timestamp();
      return;
    }
    frame_id = it->second;
    timestamp_to_frame_id_.erase(it);
    decoding_images_.erase(frame_id);
  }
  // Set frame id to the value, that was extracted from corresponding encoded
  // image.
  frame->set_id(frame_id);
  analyzer_->OnFrameDecoded(*frame, decode_time_ms, qp);
}

QualityAnalyzingVideoDecoderFactory::QualityAnalyzingVideoDecoderFactory(
    std::unique_ptr<VideoDecoderFactory> delegate,
    IdGenerator<int>* id_generator,
    EncodedImageDataExtractor* extractor,
    VideoQualityAnalyzerInterface* analyzer)
    : delegate_(std::move(delegate)),
      id_generator_(id_generator),
      extractor_(extractor),
      analyzer_(analyzer) {}
QualityAnalyzingVideoDecoderFactory::~QualityAnalyzingVideoDecoderFactory() =
    default;

std::vector<SdpVideoFormat>
QualityAnalyzingVideoDecoderFactory::GetSupportedFormats() const {
  return delegate_->GetSupportedFormats();
}

std::unique_ptr<VideoDecoder>
QualityAnalyzingVideoDecoderFactory::CreateVideoDecoder(
    const SdpVideoFormat& format) {
  std::unique_ptr<VideoDecoder> decoder = delegate_->CreateVideoDecoder(format);
  return std::make_unique<QualityAnalyzingVideoDecoder>(
      id_generator_->GetNextId(), std::move(decoder), extractor_, analyzer_);
}

std::unique_ptr<VideoDecoder>
QualityAnalyzingVideoDecoderFactory::LegacyCreateVideoDecoder(
    const SdpVideoFormat& format,
    const std::string& receive_stream_id) {
  std::unique_ptr<VideoDecoder> decoder =
      delegate_->LegacyCreateVideoDecoder(format, receive_stream_id);
  return std::make_unique<QualityAnalyzingVideoDecoder>(
      id_generator_->GetNextId(), std::move(decoder), extractor_, analyzer_);
}

}  // namespace webrtc_pc_e2e
}  // namespace webrtc
