/*
 *  Copyright (c) 2020 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/av1/libaom_av1_decoder.h"

#include <stdint.h>

#include <memory>

#include "absl/types/optional.h"
#include "api/scoped_refptr.h"
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_decoder.h"
#include "common_video/include/video_frame_buffer_pool.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/logging.h"
#include "third_party/libaom/source/libaom/aom/aom_decoder.h"
#include "third_party/libaom/source/libaom/aom/aomdx.h"
#include "third_party/libyuv/include/libyuv/convert.h"

namespace webrtc {
namespace {

constexpr int kConfigLowBitDepth = 1;  // 8-bits per luma/chroma sample.
constexpr int kDecFlags = 0;           // 0 signals no post processing.

class LibaomAv1Decoder final : public VideoDecoder {
 public:
  LibaomAv1Decoder();
  LibaomAv1Decoder(const LibaomAv1Decoder&) = delete;
  LibaomAv1Decoder& operator=(const LibaomAv1Decoder&) = delete;
  ~LibaomAv1Decoder();

  // Implements VideoDecoder.
  int32_t InitDecode(const VideoCodec* codec_settings,
                     int number_of_cores) override;

  // Decode an encoded video frame.
  int32_t Decode(const EncodedImage& encoded_image,
                 bool missing_frames,
                 int64_t render_time_ms) override;

  int32_t RegisterDecodeCompleteCallback(
      DecodedImageCallback* callback) override;

  int32_t Release() override;

  const char* ImplementationName() const override;

 private:
  aom_codec_ctx_t context_;
  bool inited_;
  // Pool of memory buffers to store decoded image data for application access.
  VideoFrameBufferPool buffer_pool_;
  DecodedImageCallback* decode_complete_callback_;
};

LibaomAv1Decoder::LibaomAv1Decoder()
    : context_(),  // Force value initialization instead of default one.
      inited_(false),
      buffer_pool_(false, /*max_number_of_buffers=*/150),
      decode_complete_callback_(nullptr) {}

LibaomAv1Decoder::~LibaomAv1Decoder() {
  Release();
}

int32_t LibaomAv1Decoder::InitDecode(const VideoCodec* codec_settings,
                                     int number_of_cores) {
  aom_codec_dec_cfg_t config = {
      static_cast<unsigned int>(number_of_cores),  // Max # of threads.
      0,                    // Frame width set after decode.
      0,                    // Frame height set after decode.
      kConfigLowBitDepth};  // Enable low-bit-depth code path.

  aom_codec_err_t ret =
      aom_codec_dec_init(&context_, aom_codec_av1_dx(), &config, kDecFlags);
  if (ret != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::InitDecode returned " << ret
                        << " on aom_codec_dec_init.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  inited_ = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t LibaomAv1Decoder::Decode(const EncodedImage& encoded_image,
                                 bool missing_frames,
                                 int64_t /*render_time_ms*/) {
  if (!inited_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (decode_complete_callback_ == nullptr) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  // Decode one video frame.
  aom_codec_err_t ret =
      aom_codec_decode(&context_, encoded_image.data(), encoded_image.size(),
                       /*user_priv=*/nullptr);
  if (ret != AOM_CODEC_OK) {
    RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode returned " << ret
                        << " on aom_codec_decode.";
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  // Get decoded frame data.
  int corrupted_frame = 0;
  aom_codec_iter_t iter = nullptr;
  while (aom_image_t* decoded_image = aom_codec_get_frame(&context_, &iter)) {
    if (aom_codec_control(&context_, AOMD_GET_FRAME_CORRUPTED,
                          &corrupted_frame)) {
      RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode "
                             "AOM_GET_FRAME_CORRUPTED.";
    }
    // Check that decoded image format is I420 and has 8-bit depth.
    if (decoded_image->fmt != AOM_IMG_FMT_I420) {
      RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode invalid image format";
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    // Return decoded frame data.
    int qp;
    ret = aom_codec_control(&context_, AOMD_GET_LAST_QUANTIZER, &qp);
    if (ret != AOM_CODEC_OK) {
      RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode returned " << ret
                          << " on control AOME_GET_LAST_QUANTIZER.";
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    // Allocate memory for decoded frame.
    rtc::scoped_refptr<I420Buffer> buffer =
        buffer_pool_.CreateI420Buffer(decoded_image->d_w, decoded_image->d_h);
    if (!buffer.get()) {
      // Pool has too many pending frames.
      RTC_LOG(LS_WARNING) << "LibaomAv1Decoder::Decode returned due to lack of"
                             " space in decoded frame buffer pool.";
      return WEBRTC_VIDEO_CODEC_ERROR;
    }

    // Copy decoded_image to decoded_frame.
    libyuv::I420Copy(
        decoded_image->planes[AOM_PLANE_Y], decoded_image->stride[AOM_PLANE_Y],
        decoded_image->planes[AOM_PLANE_U], decoded_image->stride[AOM_PLANE_U],
        decoded_image->planes[AOM_PLANE_V], decoded_image->stride[AOM_PLANE_V],
        buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
        buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
        decoded_image->d_w, decoded_image->d_h);
    VideoFrame decoded_frame = VideoFrame::Builder()
                                   .set_video_frame_buffer(buffer)
                                   .set_timestamp_rtp(encoded_image.Timestamp())
                                   .set_ntp_time_ms(encoded_image.ntp_time_ms_)
                                   .set_color_space(encoded_image.ColorSpace())
                                   .build();

    decode_complete_callback_->Decoded(decoded_frame, absl::nullopt,
                                       absl::nullopt);
  }
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t LibaomAv1Decoder::RegisterDecodeCompleteCallback(
    DecodedImageCallback* decode_complete_callback) {
  decode_complete_callback_ = decode_complete_callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t LibaomAv1Decoder::Release() {
  if (aom_codec_destroy(&context_) != AOM_CODEC_OK) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }
  buffer_pool_.Release();
  inited_ = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

const char* LibaomAv1Decoder::ImplementationName() const {
  return "libaom";
}

}  // namespace

const bool kIsLibaomAv1DecoderSupported = true;

std::unique_ptr<VideoDecoder> CreateLibaomAv1Decoder() {
  return std::make_unique<LibaomAv1Decoder>();
}

}  // namespace webrtc
