// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// #define LOG_NDEBUG 0
#define LOG_TAG "MediaCodecDecoder"

#include "arc/codec-test/mediacodec_decoder.h"

#include <assert.h>
#include <inttypes.h>

#include <utility>
#include <vector>

#include <media/NdkMediaFormat.h>
#include <utils/Log.h>

namespace android {
namespace {
// The timeout of AMediaCodec_dequeueOutputBuffer function calls.
constexpr int kTimeoutWaitForOutputUs = 1000;  // 1 millisecond

// The timeout of AMediaCodec_dequeueInputBuffer function calls.
constexpr int kTimeoutWaitForInputUs = 1000;  // 1 millisecond

// The maximal retry times of doDecode routine.
// The maximal tolerable interval between two dequeued outputs will be:
//   kTimeoutWaitForOutputUs * kTimeoutMaxRetries = 500 milliseconds
constexpr size_t kTimeoutMaxRetries = 500;

// The specified framerate for generating input timestamps.
constexpr int32_t kFrameRate = 25;

// Helper function to get possible decoder names from |type|.
std::vector<const char*> GetArcVideoDecoderNames(VideoCodecType type) {
  switch (type) {
    case VideoCodecType::H264:
      return {"c2.vda.avc.decoder", "ARC.h264.decode"};
    case VideoCodecType::VP8:
      return {"c2.vda.vp8.decoder", "ARC.vp8.decode"};
    case VideoCodecType::VP9:
      return {"c2.vda.vp9.decoder", "ARC.vp9.decode"};
    default:  // unknown type
      return {};
  }
}

#if ANDROID_VERSION >= 0x0900
const uint32_t BUFFER_FLAG_CODEC_CONFIG = AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
const char* FORMAT_KEY_SLICE_HEIGHT = AMEDIAFORMAT_KEY_SLICE_HEIGHT;
#else
// Define non-exported constants of MediaCodec NDK interface here for usage of
// Android Version < Pie.
const uint32_t BUFFER_FLAG_CODEC_CONFIG = 2;
const char* FORMAT_KEY_SLICE_HEIGHT = "slice-height";
#endif

}  // namespace

// static
std::unique_ptr<MediaCodecDecoder> MediaCodecDecoder::Create(
    const std::string& input_path,
    VideoCodecProfile profile,
    const Size& video_size) {
  if (video_size.IsEmpty()) {
    ALOGE("Size is not valid: %dx%d", video_size.width, video_size.height);
    return nullptr;
  }

  VideoCodecType type = VideoCodecProfileToType(profile);

  std::unique_ptr<EncodedDataHelper> encoded_data_helper(
      new EncodedDataHelper(input_path, type));
  if (!encoded_data_helper->IsValid()) {
    ALOGE("EncodedDataHelper is not created for file: %s", input_path.c_str());
    return nullptr;
  }

  AMediaCodec* codec = nullptr;
  auto decoder_names = GetArcVideoDecoderNames(type);
  for (const auto& decoder_name : decoder_names) {
    codec = AMediaCodec_createCodecByName(decoder_name);
    if (codec) {
      ALOGD("Created mediacodec decoder by name: %s", decoder_name);
      break;
    }
  }
  if (!codec) {
    ALOGE("Failed to create mediacodec decoder.");
    return nullptr;
  }

  return std::unique_ptr<MediaCodecDecoder>(new MediaCodecDecoder(
      codec, std::move(encoded_data_helper), type, video_size));
}

MediaCodecDecoder::MediaCodecDecoder(
    AMediaCodec* codec,
    std::unique_ptr<EncodedDataHelper> encoded_data_helper,
    VideoCodecType type,
    const Size& size)
    : codec_(codec),
      encoded_data_helper_(std::move(encoded_data_helper)),
      type_(type),
      input_visible_size_(size) {}

MediaCodecDecoder::~MediaCodecDecoder() {
  if (codec_ != nullptr) {
    AMediaCodec_delete(codec_);
  }
}

void MediaCodecDecoder::AddOutputBufferReadyCb(const OutputBufferReadyCb& cb) {
  output_buffer_ready_cbs_.push_back(cb);
}

void MediaCodecDecoder::AddOutputFormatChangedCb(
    const OutputFormatChangedCb& cb) {
  output_format_changed_cbs_.push_back(cb);
}

void MediaCodecDecoder::Rewind() {
  encoded_data_helper_->Rewind();
  input_fragment_index_ = 0;
}

bool MediaCodecDecoder::Configure() {
  ALOGD("configure: mime=%s, width=%d, height=%d", GetMimeType(type_),
        input_visible_size_.width, input_visible_size_.height);
  AMediaFormat* format = AMediaFormat_new();
  AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, GetMimeType(type_));
  AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH,
                        input_visible_size_.width);
  AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT,
                        input_visible_size_.height);
  media_status_t ret =
      AMediaCodec_configure(codec_, format, nullptr /* surface */,
                            nullptr /* crtpto */, 0 /* flag */);
  AMediaFormat_delete(format);
  if (ret != AMEDIA_OK) {
    ALOGE("Configure return error: %d", ret);
    return false;
  }
  return true;
}

bool MediaCodecDecoder::Start() {
  media_status_t ret = AMediaCodec_start(codec_);
  if (ret != AMEDIA_OK) {
    ALOGE("Start return error: %d", ret);
    return false;
  }
  return true;
}

bool MediaCodecDecoder::Decode() {
  while (!output_done_) {
    size_t retries = 0;
    bool success = false;

    // It will keep retrying until one output buffer is dequeued successfully.
    // On each retry we would like to enqueue input buffers as fast as possible.
    // The retry loop will break as failure if maxmimum retries are reached or
    // errors returned from enqueue input buffer or dequeue output buffer.
    while (retries < kTimeoutMaxRetries && !success) {
      if (!EnqueueInputBuffers())
        return false;

      switch (DequeueOutputBuffer()) {
        case DequeueStatus::RETRY:
          retries++;
          break;
        case DequeueStatus::SUCCESS:
          success = true;
          break;
        case DequeueStatus::FAILURE:
          return false;
      }
    }

    if (retries >= kTimeoutMaxRetries) {
      ALOGE("Decoder did not produce an output buffer after %zu retries",
            kTimeoutMaxRetries);
    }
    if (!success)
      return false;
  }
  return true;
}

bool MediaCodecDecoder::EnqueueInputBuffers() {
  ssize_t index;
  while (!input_done_) {
    index = AMediaCodec_dequeueInputBuffer(codec_, kTimeoutWaitForInputUs);
    if (index == AMEDIACODEC_INFO_TRY_AGAIN_LATER)
      return true;  // no available input buffers, try next time

    if (index < 0) {
      ALOGE("Unknown error while dequeueInputBuffer: %zd", index);
      return false;
    }

    if (encoded_data_helper_->ReachEndOfStream()) {
      if (!FeedEOSInputBuffer(index))
        return false;
      input_done_ = true;
    } else {
      if (!FeedInputBuffer(index))
        return false;
    }
  }
  return true;
}

MediaCodecDecoder::DequeueStatus MediaCodecDecoder::DequeueOutputBuffer() {
  AMediaCodecBufferInfo info;
  ssize_t index =
      AMediaCodec_dequeueOutputBuffer(codec_, &info, kTimeoutWaitForOutputUs);

  switch (index) {
    case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
      ALOGV("Try again later is reported");
      return DequeueStatus::RETRY;
    case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
      ALOGV("Output buffers changed");
      return DequeueStatus::RETRY;
    case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
      ALOGV("Output format changed");
      if (GetOutputFormat())
        return DequeueStatus::SUCCESS;
      else
        return DequeueStatus::FAILURE;
    default:
      if (index < 0) {
        ALOGE("Unknown error while dequeueOutputBuffer: %zd", index);
        return DequeueStatus::FAILURE;
      }
      break;
  }

  if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM)
    output_done_ = true;
  if (!ReceiveOutputBuffer(index, info))
    return DequeueStatus::FAILURE;
  return DequeueStatus::SUCCESS;
}

bool MediaCodecDecoder::Stop() {
  return AMediaCodec_stop(codec_) == AMEDIA_OK;
}

bool MediaCodecDecoder::FeedInputBuffer(size_t index) {
  assert(!encoded_data_helper_->ReachEndOfStream());

  size_t buf_size = 0;
  uint8_t* buf = AMediaCodec_getInputBuffer(codec_, index, &buf_size);
  if (!buf) {
    ALOGE("Failed to getInputBuffer: index=%zu", index);
    return false;
  }

  auto fragment = encoded_data_helper_->GetNextFragment();
  assert(fragment);

  if (buf_size < fragment->data.size()) {
    ALOGE("Input buffer size is not enough: buf_size=%zu, data_size=%zu",
          buf_size, fragment->data.size());
    return false;
  }

  memcpy(reinterpret_cast<char*>(buf), fragment->data.data(),
         fragment->data.size());

  uint32_t input_flag = 0;
  if (fragment->csd_flag)
    input_flag |= BUFFER_FLAG_CODEC_CONFIG;

  uint64_t timestamp_us = input_fragment_index_ * 1000000 / kFrameRate;

  ALOGV("queueInputBuffer(index=%zu, offset=0, size=%zu, time=%" PRIu64
        ", flags=%u) #%d",
        index, fragment->data.size(), timestamp_us, input_flag,
        input_fragment_index_);
  media_status_t status = AMediaCodec_queueInputBuffer(
      codec_, index, 0 /* offset */, fragment->data.size(), timestamp_us,
      input_flag);
  if (status != AMEDIA_OK) {
    ALOGE("Failed to queueInputBuffer: %d", status);
    return false;
  }
  ++input_fragment_index_;
  return true;
}

bool MediaCodecDecoder::FeedEOSInputBuffer(size_t index) {
  // Timestamp of EOS input buffer is undefined, use 0 here to test decoder
  // robustness.
  uint64_t timestamp_us = 0;

  ALOGV("queueInputBuffer(index=%zu) EOS", index);
  media_status_t status = AMediaCodec_queueInputBuffer(
      codec_, index, 0 /* offset */, 0 /* size */, timestamp_us,
      AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
  if (status != AMEDIA_OK) {
    ALOGE("Failed to queueInputBuffer EOS: %d", status);
    return false;
  }
  return true;
}

bool MediaCodecDecoder::ReceiveOutputBuffer(size_t index,
                                            const AMediaCodecBufferInfo& info) {
  size_t out_size;
  uint8_t* buf = AMediaCodec_getOutputBuffer(codec_, index, &out_size);
  if (!buf) {
    ALOGE("Failed to getOutputBuffer(index=%zu)", index);
    return false;
  }

  received_outputs_++;
  ALOGV(
      "ReceiveOutputBuffer(index=%zu, size=%d, time=%" PRId64 ", flags=%u) #%d",
      index, info.size, info.presentationTimeUs, info.flags, received_outputs_);

  // Do not callback for dummy EOS output (info.size == 0)
  if (info.size > 0) {
    for (const auto& callback : output_buffer_ready_cbs_)
      callback(buf, info.size, received_outputs_);
  }

  media_status_t status =
      AMediaCodec_releaseOutputBuffer(codec_, index, false /* render */);
  if (status != AMEDIA_OK) {
    ALOGE("Failed to releaseOutputBuffer(index=%zu): %d", index, status);
    return false;
  }
  return true;
}

bool MediaCodecDecoder::GetOutputFormat() {
  AMediaFormat* format = AMediaCodec_getOutputFormat(codec_);
  bool success = true;

  // Required formats
  int32_t width = 0;
  if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width)) {
    ALOGE("Cannot find width in format.");
    success = false;
  }

  int32_t height = 0;
  if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height)) {
    ALOGE("Cannot find height in format.");
    success = false;
  }

  int32_t color_format = 0;
  if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT,
                             &color_format)) {
    ALOGE("Cannot find color-format in format.");
    success = false;
  }

  // Optional formats
  int32_t crop_left = 0;
  int32_t crop_top = 0;
  int32_t crop_right = width - 1;
  int32_t crop_bottom = height - 1;
#if ANDROID_VERSION >= 0x0900  // Android 9.0 (Pie)
  // Crop info is only avaiable on NDK version >= Pie.
  if (!AMediaFormat_getRect(format, AMEDIAFORMAT_KEY_DISPLAY_CROP, &crop_left,
                            &crop_top, &crop_right, &crop_bottom)) {
    ALOGD("Cannot find crop window in format. Set as large as frame size.");
    crop_left = 0;
    crop_top = 0;
    crop_right = width - 1;
    crop_bottom = height - 1;
  }
#endif
  // Note: For ARC++N, width and height are set as same as the size of crop
  //       window in ArcCodec. So the values above will be still satisfied in
  //       ARC++N.

  // In current exiting ARC video decoder crop origin is always at (0,0)
  if (crop_left != 0 || crop_top != 0) {
    ALOGE("Crop origin is not (0,0): (%d,%d)", crop_left, crop_top);
    success = false;
  }

  int32_t stride = 0;
  if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_STRIDE, &stride)) {
    ALOGD("Cannot find stride in format. Set as frame width.");
    stride = width;
  }

  int32_t slice_height = 0;
  if (!AMediaFormat_getInt32(format, FORMAT_KEY_SLICE_HEIGHT, &slice_height)) {
    ALOGD("Cannot find slice-height in format. Set as frame height.");
    slice_height = height;
  }

  for (const auto& callback : output_format_changed_cbs_) {
    callback(Size(stride, slice_height),
             Size(crop_right - crop_left + 1, crop_bottom - crop_top + 1),
             color_format);
  }
  return success;
}

}  // namespace android
