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

#include "media/gpu/vaapi/vp9_vaapi_video_decoder_delegate.h"

#include <type_traits>

#include "base/cxx17_backports.h"
#include "base/numerics/checked_math.h"
#include "base/trace_event/trace_event.h"
#include "build/chromeos_buildflags.h"
#include "media/gpu/decode_surface_handler.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_common.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"

namespace media {

using DecodeStatus = VP9Decoder::VP9Accelerator::Status;

VP9VaapiVideoDecoderDelegate::VP9VaapiVideoDecoderDelegate(
    DecodeSurfaceHandler<VASurface>* const vaapi_dec,
    scoped_refptr<VaapiWrapper> vaapi_wrapper,
    ProtectedSessionUpdateCB on_protected_session_update_cb,
    CdmContext* cdm_context,
    EncryptionScheme encryption_scheme)
    : VaapiVideoDecoderDelegate(vaapi_dec,
                                std::move(vaapi_wrapper),
                                std::move(on_protected_session_update_cb),
                                cdm_context,
                                encryption_scheme) {}

VP9VaapiVideoDecoderDelegate::~VP9VaapiVideoDecoderDelegate() {
  DCHECK(!picture_params_);
  DCHECK(!slice_params_);
  DCHECK(!crypto_params_);
  DCHECK(!protected_params_);
}

scoped_refptr<VP9Picture> VP9VaapiVideoDecoderDelegate::CreateVP9Picture() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  const auto va_surface = vaapi_dec_->CreateSurface();
  if (!va_surface)
    return nullptr;

  return new VaapiVP9Picture(std::move(va_surface));
}

DecodeStatus VP9VaapiVideoDecoderDelegate::SubmitDecode(
    scoped_refptr<VP9Picture> pic,
    const Vp9SegmentationParams& seg,
    const Vp9LoopFilterParams& lf,
    const Vp9ReferenceFrameVector& ref_frames,
    base::OnceClosure done_cb) {
  TRACE_EVENT0("media,gpu", "VP9VaapiVideoDecoderDelegate::SubmitDecode");
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // |done_cb| should be null as we return false from IsFrameContextRequired().
  DCHECK(!done_cb);

  const Vp9FrameHeader* frame_hdr = pic->frame_hdr.get();
  DCHECK(frame_hdr);

  VADecPictureParameterBufferVP9 pic_param{};
  VASliceParameterBufferVP9 slice_param{};

  if (!picture_params_) {
    picture_params_ = vaapi_wrapper_->CreateVABuffer(
        VAPictureParameterBufferType, sizeof(pic_param));
    if (!picture_params_)
      return DecodeStatus::kFail;
  }
  if (!slice_params_) {
    slice_params_ = vaapi_wrapper_->CreateVABuffer(VASliceParameterBufferType,
                                                   sizeof(slice_param));
    if (!slice_params_)
      return DecodeStatus::kFail;
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  const DecryptConfig* decrypt_config = pic->decrypt_config();
  if (decrypt_config && !SetDecryptConfig(decrypt_config->Clone()))
    return DecodeStatus::kFail;

  bool uses_crypto = false;
  std::vector<VAEncryptionSegmentInfo> encryption_segment_info;
  VAEncryptionParameters crypto_param{};
  if (IsEncryptedSession()) {
    const ProtectedSessionState state = SetupDecryptDecode(
        /*full_sample=*/false, frame_hdr->frame_size, &crypto_param,
        &encryption_segment_info,
        decrypt_config ? decrypt_config->subsamples()
                       : std::vector<SubsampleEntry>());
    if (state == ProtectedSessionState::kFailed) {
      LOG(ERROR)
          << "SubmitDecode fails because we couldn't setup the protected "
             "session";
      return DecodeStatus::kFail;
    } else if (state != ProtectedSessionState::kCreated) {
      return DecodeStatus::kTryAgain;
    }
    uses_crypto = true;
    if (!crypto_params_) {
      crypto_params_ = vaapi_wrapper_->CreateVABuffer(
          VAEncryptionParameterBufferType, sizeof(crypto_param));
      if (!crypto_params_)
        return DecodeStatus::kFail;
    }
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  pic_param.frame_width = base::checked_cast<uint16_t>(frame_hdr->frame_width);
  pic_param.frame_height =
      base::checked_cast<uint16_t>(frame_hdr->frame_height);
  CHECK_EQ(kVp9NumRefFrames, base::size(pic_param.reference_frames));
  for (size_t i = 0; i < base::size(pic_param.reference_frames); ++i) {
    auto ref_pic = ref_frames.GetFrame(i);
    if (ref_pic) {
      pic_param.reference_frames[i] =
          ref_pic->AsVaapiVP9Picture()->GetVASurfaceID();
    } else {
      pic_param.reference_frames[i] = VA_INVALID_SURFACE;
    }
  }

#define FHDR_TO_PP_PF1(a) pic_param.pic_fields.bits.a = frame_hdr->a
#define FHDR_TO_PP_PF2(a, b) pic_param.pic_fields.bits.a = b
  FHDR_TO_PP_PF2(subsampling_x, frame_hdr->subsampling_x == 1);
  FHDR_TO_PP_PF2(subsampling_y, frame_hdr->subsampling_y == 1);
  FHDR_TO_PP_PF2(frame_type, frame_hdr->IsKeyframe() ? 0 : 1);
  FHDR_TO_PP_PF1(show_frame);
  FHDR_TO_PP_PF1(error_resilient_mode);
  FHDR_TO_PP_PF1(intra_only);
  FHDR_TO_PP_PF1(allow_high_precision_mv);
  FHDR_TO_PP_PF2(mcomp_filter_type, frame_hdr->interpolation_filter);
  FHDR_TO_PP_PF1(frame_parallel_decoding_mode);
  FHDR_TO_PP_PF1(reset_frame_context);
  FHDR_TO_PP_PF1(refresh_frame_context);
  FHDR_TO_PP_PF2(frame_context_idx, frame_hdr->frame_context_idx_to_save_probs);
  FHDR_TO_PP_PF2(segmentation_enabled, seg.enabled);
  FHDR_TO_PP_PF2(segmentation_temporal_update, seg.temporal_update);
  FHDR_TO_PP_PF2(segmentation_update_map, seg.update_map);
  FHDR_TO_PP_PF2(last_ref_frame, frame_hdr->ref_frame_idx[0]);
  FHDR_TO_PP_PF2(last_ref_frame_sign_bias,
                 frame_hdr->ref_frame_sign_bias[Vp9RefType::VP9_FRAME_LAST]);
  FHDR_TO_PP_PF2(golden_ref_frame, frame_hdr->ref_frame_idx[1]);
  FHDR_TO_PP_PF2(golden_ref_frame_sign_bias,
                 frame_hdr->ref_frame_sign_bias[Vp9RefType::VP9_FRAME_GOLDEN]);
  FHDR_TO_PP_PF2(alt_ref_frame, frame_hdr->ref_frame_idx[2]);
  FHDR_TO_PP_PF2(alt_ref_frame_sign_bias,
                 frame_hdr->ref_frame_sign_bias[Vp9RefType::VP9_FRAME_ALTREF]);
  FHDR_TO_PP_PF2(lossless_flag, frame_hdr->quant_params.IsLossless());
#undef FHDR_TO_PP_PF2
#undef FHDR_TO_PP_PF1

  pic_param.filter_level = lf.level;
  pic_param.sharpness_level = lf.sharpness;
  pic_param.log2_tile_rows = frame_hdr->tile_rows_log2;
  pic_param.log2_tile_columns = frame_hdr->tile_cols_log2;
  pic_param.frame_header_length_in_bytes = frame_hdr->uncompressed_header_size;
  pic_param.first_partition_size = frame_hdr->header_size_in_bytes;

  SafeArrayMemcpy(pic_param.mb_segment_tree_probs, seg.tree_probs);
  SafeArrayMemcpy(pic_param.segment_pred_probs, seg.pred_probs);

  pic_param.profile = frame_hdr->profile;
  pic_param.bit_depth = frame_hdr->bit_depth;
  DCHECK((pic_param.profile == 0 && pic_param.bit_depth == 8) ||
         (pic_param.profile == 2 && pic_param.bit_depth == 10));

  slice_param.slice_data_size = frame_hdr->frame_size;
  slice_param.slice_data_offset = 0;
  slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;

  static_assert(
      std::extent<decltype(Vp9SegmentationParams::feature_enabled)>() ==
          std::extent<decltype(slice_param.seg_param)>(),
      "seg_param array of incorrect size");
  for (size_t i = 0; i < base::size(slice_param.seg_param); ++i) {
    VASegmentParameterVP9& seg_param = slice_param.seg_param[i];
#define SEG_TO_SP_SF(a, b) seg_param.segment_flags.fields.a = b
    SEG_TO_SP_SF(
        segment_reference_enabled,
        seg.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_REF_FRAME));
    SEG_TO_SP_SF(segment_reference,
                 seg.FeatureData(i, Vp9SegmentationParams::SEG_LVL_REF_FRAME));
    SEG_TO_SP_SF(segment_reference_skipped,
                 seg.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_SKIP));
#undef SEG_TO_SP_SF

    SafeArrayMemcpy(seg_param.filter_level, lf.lvl[i]);

    seg_param.luma_dc_quant_scale = seg.y_dequant[i][0];
    seg_param.luma_ac_quant_scale = seg.y_dequant[i][1];
    seg_param.chroma_dc_quant_scale = seg.uv_dequant[i][0];
    seg_param.chroma_ac_quant_scale = seg.uv_dequant[i][1];
  }

  // Always re-create |encoded_data| because reusing the buffer causes horrific
  // artifacts in decoded buffers. TODO(b/169725321): This seems to be a driver
  // bug, fix it and reuse the buffer.
  std::unique_ptr<ScopedVABuffer> encoded_data;

  std::vector<std::pair<VABufferID, VaapiWrapper::VABufferDescriptor>> buffers =
      {{picture_params_->id(),
        {picture_params_->type(), picture_params_->size(), &pic_param}},
       {slice_params_->id(),
        {slice_params_->type(), slice_params_->size(), &slice_param}}};
#if BUILDFLAG(IS_CHROMEOS_ASH)
  std::unique_ptr<uint8_t[]> protected_vp9_data;
  std::string amd_decrypt_params;
  if (IsTranscrypted()) {
    CHECK(decrypt_config);
    CHECK_EQ(decrypt_config->subsamples().size(), 1u);
    if (!protected_params_) {
      protected_params_ = vaapi_wrapper_->CreateVABuffer(
          VAProtectedSliceDataBufferType, decrypt_config->key_id().length());
      if (!protected_params_)
        return DecodeStatus::kFail;
    }
    DCHECK_EQ(decrypt_config->key_id().length(), protected_params_->size());
    // For VP9 superframes, the IV may have been incremented, so copy that
    // back into the decryption parameters. The decryption parameters struct has
    // a uint32_t for the first parameter, and the second is the 128-bit IV and
    // then various other fields. Total max structure size is 128 bytes. The
    // structure definition is in ChromeOS internal code so we do not reference
    // it directly here.
    constexpr uint32_t dp_iv_offset = sizeof(uint32_t);
    amd_decrypt_params = decrypt_config->key_id();
    memcpy(&amd_decrypt_params[dp_iv_offset], decrypt_config->iv().data(),
           DecryptConfig::kDecryptionKeySize);
    buffers.push_back({protected_params_->id(),
                       {protected_params_->type(), protected_params_->size(),
                        amd_decrypt_params.data()}});

    // For transcrypted VP9 on AMD we need to send the UCH + cypher_bytes from
    // the buffer as the slice data per AMD's instructions.
    base::CheckedNumeric<size_t> protected_data_size =
        decrypt_config->subsamples()[0].cypher_bytes;
    protected_data_size += frame_hdr->uncompressed_header_size;
    if (!protected_data_size.IsValid()) {
      DVLOG(1) << "Invalid protected_data_size";
      return DecodeStatus::kFail;
    }
    encoded_data = vaapi_wrapper_->CreateVABuffer(
        VASliceDataBufferType, protected_data_size.ValueOrDie());
    if (!encoded_data)
      return DecodeStatus::kFail;
    protected_vp9_data =
        std::make_unique<uint8_t[]>(protected_data_size.ValueOrDie());
    // Copy the UCH.
    memcpy(protected_vp9_data.get(), frame_hdr->data,
           frame_hdr->uncompressed_header_size);
    // Copy the transcrypted data.
    memcpy(protected_vp9_data.get() + frame_hdr->uncompressed_header_size,
           frame_hdr->data + decrypt_config->subsamples()[0].clear_bytes,
           decrypt_config->subsamples()[0].cypher_bytes);
    buffers.push_back({encoded_data->id(),
                       {encoded_data->type(), encoded_data->size(),
                        protected_vp9_data.get()}});
  } else {
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
    encoded_data = vaapi_wrapper_->CreateVABuffer(VASliceDataBufferType,
                                                  frame_hdr->frame_size);
    if (!encoded_data)
      return DecodeStatus::kFail;
    buffers.push_back(
        {encoded_data->id(),
         {encoded_data->type(), encoded_data->size(), frame_hdr->data}});
#if BUILDFLAG(IS_CHROMEOS_ASH)
  }
  if (uses_crypto) {
    buffers.push_back(
        {crypto_params_->id(),
         {crypto_params_->type(), crypto_params_->size(), &crypto_param}});
  }
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

  const VaapiVP9Picture* vaapi_pic = pic->AsVaapiVP9Picture();
  CHECK(
      gfx::Rect(vaapi_pic->va_surface()->size()).Contains(pic->visible_rect()));

  bool success = vaapi_wrapper_->MapAndCopyAndExecute(
      vaapi_pic->GetVASurfaceID(), buffers);
  if (!success && NeedsProtectedSessionRecovery())
    return DecodeStatus::kTryAgain;

  if (success && IsEncryptedSession())
    ProtectedDecodedSucceeded();

  return success ? DecodeStatus::kOk : DecodeStatus::kFail;
}

bool VP9VaapiVideoDecoderDelegate::OutputPicture(
    scoped_refptr<VP9Picture> pic) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  const VaapiVP9Picture* vaapi_pic = pic->AsVaapiVP9Picture();
  vaapi_dec_->SurfaceReady(vaapi_pic->va_surface(), vaapi_pic->bitstream_id(),
                           vaapi_pic->visible_rect(),
                           vaapi_pic->get_colorspace());
  return true;
}

bool VP9VaapiVideoDecoderDelegate::IsFrameContextRequired() const {
  return false;
}

bool VP9VaapiVideoDecoderDelegate::GetFrameContext(
    scoped_refptr<VP9Picture> pic,
    Vp9FrameContext* frame_ctx) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  NOTIMPLEMENTED() << "Frame context update not supported";
  return false;
}

void VP9VaapiVideoDecoderDelegate::OnVAContextDestructionSoon() {
  // Destroy the member ScopedVABuffers below since they refer to a VAContextID
  // that will be destroyed soon.
  picture_params_.reset();
  slice_params_.reset();
  crypto_params_.reset();
  protected_params_.reset();
}

}  // namespace media
