/*
 *  Copyright (c) 2018 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/decoder_database.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <utility>

#include "api/sequence_checker.h"
#include "api/video/encoded_frame.h"
#include "api/video/render_resolution.h"
#include "api/video_codecs/video_decoder.h"
#include "modules/video_coding/generic_decoder.h"
#include "modules/video_coding/include/video_coding_defines.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

VCMDecoderDatabase::VCMDecoderDatabase() {
  decoder_sequence_checker_.Detach();
}

void VCMDecoderDatabase::DeregisterExternalDecoder(uint8_t payload_type) {
  RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
  auto it = decoders_.find(payload_type);
  if (it == decoders_.end()) {
    return;
  }

  // We can't use payload_type to check if the decoder is currently in use,
  // because payload type may be out of date (e.g. before we decode the first
  // frame after RegisterReceiveCodec).
  if (current_decoder_ && current_decoder_->IsSameDecoder(it->second.get())) {
    // Release it if it was registered and in use.
    current_decoder_ = std::nullopt;
  }
  decoders_.erase(it);
}

// Add the external decoder object to the list of external decoders.
// Won't be registered as a receive codec until RegisterReceiveCodec is called.
void VCMDecoderDatabase::RegisterExternalDecoder(
    uint8_t payload_type,
    std::unique_ptr<VideoDecoder> external_decoder) {
  RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
  // If payload value already exists, erase old and insert new.
  DeregisterExternalDecoder(payload_type);
  if (external_decoder) {
    decoders_.emplace(
        std::make_pair(payload_type, std::move(external_decoder)));
  }
}

bool VCMDecoderDatabase::IsExternalDecoderRegistered(
    uint8_t payload_type) const {
  RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
  return decoders_.find(payload_type) != decoders_.end();
}

void VCMDecoderDatabase::RegisterReceiveCodec(
    uint8_t payload_type,
    const VideoDecoder::Settings& settings) {
  // If payload value already exists, erase old and insert new.
  if (payload_type == current_payload_type_) {
    current_payload_type_ = std::nullopt;
  }
  decoder_settings_[payload_type] = settings;
}

bool VCMDecoderDatabase::DeregisterReceiveCodec(uint8_t payload_type) {
  if (decoder_settings_.erase(payload_type) == 0) {
    return false;
  }
  if (payload_type == current_payload_type_) {
    // This codec is currently in use.
    current_payload_type_ = std::nullopt;
  }
  return true;
}

void VCMDecoderDatabase::DeregisterReceiveCodecs() {
  current_payload_type_ = std::nullopt;
  decoder_settings_.clear();
}

VCMGenericDecoder* VCMDecoderDatabase::GetDecoder(
    const EncodedFrame& frame,
    VCMDecodedFrameCallback* decoded_frame_callback) {
  RTC_DCHECK_RUN_ON(&decoder_sequence_checker_);
  RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
  uint8_t payload_type = frame.PayloadType();
  if (payload_type == current_payload_type_ || payload_type == 0) {
    return current_decoder_.has_value() ? &*current_decoder_ : nullptr;
  }
  // If decoder exists - delete.
  if (current_decoder_.has_value()) {
    current_decoder_ = std::nullopt;
    current_payload_type_ = std::nullopt;
  }

  CreateAndInitDecoder(frame);
  if (current_decoder_ == std::nullopt) {
    return nullptr;
  }

  VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
  callback->OnIncomingPayloadType(payload_type);
  if (current_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
      0) {
    current_decoder_ = std::nullopt;
    return nullptr;
  }

  current_payload_type_ = payload_type;
  return &*current_decoder_;
}

void VCMDecoderDatabase::CreateAndInitDecoder(const EncodedFrame& frame) {
  uint8_t payload_type = frame.PayloadType();
  RTC_DLOG(LS_INFO) << "Initializing decoder with payload type '"
                    << int{payload_type} << "'.";
  auto decoder_item = decoder_settings_.find(payload_type);
  if (decoder_item == decoder_settings_.end()) {
    RTC_LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
                      << int{payload_type};
    return;
  }
  auto external_dec_item = decoders_.find(payload_type);
  if (external_dec_item == decoders_.end()) {
    RTC_LOG(LS_ERROR) << "No decoder of this type exists.";
    return;
  }
  current_decoder_.emplace(external_dec_item->second.get());

  // Copy over input resolutions to prevent codec reinitialization due to
  // the first frame being of a different resolution than the database values.
  // This is best effort, since there's no guarantee that width/height have been
  // parsed yet (and may be zero).
  RenderResolution frame_resolution(frame.EncodedImage()._encodedWidth,
                                    frame.EncodedImage()._encodedHeight);
  if (frame_resolution.Valid()) {
    decoder_item->second.set_max_render_resolution(frame_resolution);
  }
  if (!current_decoder_->Configure(decoder_item->second)) {
    current_decoder_ = std::nullopt;
    RTC_LOG(LS_ERROR) << "Failed to initialize decoder.";
  }
}

}  // namespace webrtc
