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

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

#include <algorithm>
#include <type_traits>
#include <utility>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/lock.h"
#include "build/chromeos_buildflags.h"
#include "media/gpu/vaapi/vaapi_common.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/gpu/vp8_picture.h"
#include "media/gpu/vp8_reference_frame_vector.h"
#include "third_party/libva_protected_content/va_protected_content.h"

namespace media {

namespace {

template <typename To, typename From>
void CheckedMemcpy(To& to, From& from) {
  static_assert(std::is_array<To>::value, "First parameter must be an array");
  static_assert(std::is_array<From>::value,
                "Second parameter must be an array");
  static_assert(sizeof(to) == sizeof(from), "arrays must be of same size");
  memcpy(&to, &from, sizeof(to));
}

}  // namespace

ScopedVABufferMapping::ScopedVABufferMapping(
    const base::Lock* lock,
    VADisplay va_display,
    VABufferID buffer_id,
    base::OnceCallback<void(VABufferID)> release_callback)
    : lock_(lock), va_display_(va_display), buffer_id_(buffer_id) {
  MAYBE_ASSERT_ACQUIRED(lock_);
  DCHECK_NE(buffer_id, VA_INVALID_ID);

  const VAStatus result =
      vaMapBuffer(va_display_, buffer_id_, &va_buffer_data_);
  const bool success = result == VA_STATUS_SUCCESS;
  LOG_IF(ERROR, !success) << "vaMapBuffer failed: " << vaErrorStr(result);
  DCHECK(success == (va_buffer_data_ != nullptr))
      << "|va_buffer_data| should be null if vaMapBuffer() fails";

  if (!success && release_callback)
    std::move(release_callback).Run(buffer_id_);
}

ScopedVABufferMapping::~ScopedVABufferMapping() {
  CHECK(sequence_checker_.CalledOnValidSequence());
  if (va_buffer_data_) {
    MAYBE_ASSERT_ACQUIRED(lock_);
    Unmap();
  }
}

VAStatus ScopedVABufferMapping::Unmap() {
  CHECK(sequence_checker_.CalledOnValidSequence());
  MAYBE_ASSERT_ACQUIRED(lock_);
  const VAStatus result = vaUnmapBuffer(va_display_, buffer_id_);
  if (result == VA_STATUS_SUCCESS)
    va_buffer_data_ = nullptr;
  else
    LOG(ERROR) << "vaUnmapBuffer failed: " << vaErrorStr(result);
  return result;
}

// static
std::unique_ptr<ScopedVABuffer> ScopedVABuffer::Create(
    base::Lock* lock,
    VADisplay va_display,
    VAContextID va_context_id,
    VABufferType va_buffer_type,
    size_t size) {
  DCHECK(va_display);
  DCHECK_NE(va_context_id, VA_INVALID_ID);
  DCHECK(IsValidVABufferType(va_buffer_type));
  DCHECK_NE(size, 0u);
  MAYBE_ASSERT_ACQUIRED(lock);
  unsigned int va_buffer_size;
  if (!base::CheckedNumeric<size_t>(size).AssignIfValid(&va_buffer_size)) {
    LOG(ERROR) << "Invalid size, " << size;
    return nullptr;
  }
  VABufferID buffer_id = VA_INVALID_ID;
  const VAStatus va_res =
      vaCreateBuffer(va_display, va_context_id, va_buffer_type, va_buffer_size,
                     1, nullptr, &buffer_id);
  if (va_res != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to create a VA buffer: " << vaErrorStr(va_res);
    return nullptr;
  }
  DCHECK_NE(buffer_id, VA_INVALID_ID);
  return base::WrapUnique(
      new ScopedVABuffer(lock, va_display, buffer_id, va_buffer_type, size));
}

// static
std::unique_ptr<ScopedVABuffer> ScopedVABuffer::CreateForTesting(
    VABufferID va_buffer_id,
    VABufferType va_buffer_type,
    size_t size) {
  return base::WrapUnique(
      new ScopedVABuffer(nullptr, nullptr, va_buffer_id, va_buffer_type, size));
}

ScopedVABuffer::ScopedVABuffer(base::Lock* lock,
                               VADisplay va_display,
                               VABufferID va_buffer_id,
                               VABufferType va_buffer_type,
                               size_t size)
    : lock_(lock),
      va_display_(va_display),
      va_buffer_id_(va_buffer_id),
      va_buffer_type_(va_buffer_type),
      size_(size) {}

ScopedVABuffer::~ScopedVABuffer() {
  DCHECK_NE(va_buffer_id_, VA_INVALID_ID);
  if (!va_display_)
    return;  // Don't call VA-API function in test.

  base::AutoLockMaybe auto_lock(lock_.get());
  VAStatus va_res = vaDestroyBuffer(va_display_, va_buffer_id_);
  LOG_IF(ERROR, va_res != VA_STATUS_SUCCESS)
      << "Failed to destroy a VA buffer: " << vaErrorStr(va_res);
}

ScopedVAImage::ScopedVAImage(base::Lock* lock,
                             VADisplay va_display,
                             VASurfaceID va_surface_id,
                             VAImageFormat* format,
                             const gfx::Size& size)
    : lock_(lock), va_display_(va_display), image_(new VAImage{}) {
  MAYBE_ASSERT_ACQUIRED(lock_);
  VAStatus result = vaCreateImage(va_display_, format, size.width(),
                                  size.height(), image_.get());
  if (result != VA_STATUS_SUCCESS) {
    DCHECK_EQ(image_->image_id, VA_INVALID_ID);
    LOG(ERROR) << "vaCreateImage failed: " << vaErrorStr(result);
    return;
  }
  DCHECK_NE(image_->image_id, VA_INVALID_ID);

  result = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(),
                      size.height(), image_->image_id);
  if (result != VA_STATUS_SUCCESS) {
    LOG(ERROR) << "vaGetImage failed: " << vaErrorStr(result);
    return;
  }

  va_buffer_ =
      std::make_unique<ScopedVABufferMapping>(lock_, va_display, image_->buf);
}

ScopedVAImage::~ScopedVAImage() {
  CHECK(sequence_checker_.CalledOnValidSequence());
  if (image_->image_id != VA_INVALID_ID) {
    base::AutoLockMaybe auto_lock(lock_.get());

    // |va_buffer_| has to be deleted before vaDestroyImage().
    va_buffer_.reset();
    vaDestroyImage(va_display_, image_->image_id);
  }
}

ScopedVASurface::ScopedVASurface(scoped_refptr<VaapiWrapper> vaapi_wrapper,
                                 VASurfaceID va_surface_id,
                                 const gfx::Size& size,
                                 unsigned int va_rt_format)
    : vaapi_wrapper_(std::move(vaapi_wrapper)),
      va_surface_id_(va_surface_id),
      size_(size),
      va_rt_format_(va_rt_format) {
  DCHECK(vaapi_wrapper_);
}

ScopedVASurface::~ScopedVASurface() {
  if (va_surface_id_ != VA_INVALID_ID)
    vaapi_wrapper_->DestroySurface(va_surface_id_);
}

bool ScopedVASurface::IsValid() const {
  return va_surface_id_ != VA_INVALID_ID && !size_.IsEmpty() &&
         va_rt_format_ != kInvalidVaRtFormat;
}

void FillVP8DataStructures(const Vp8FrameHeader& frame_header,
                           const Vp8ReferenceFrameVector& reference_frames,
                           VAIQMatrixBufferVP8* iq_matrix_buf,
                           VAProbabilityDataBufferVP8* prob_buf,
                           VAPictureParameterBufferVP8* pic_param,
                           VASliceParameterBufferVP8* slice_param) {
  const Vp8SegmentationHeader& sgmnt_hdr = frame_header.segmentation_hdr;
  const Vp8QuantizationHeader& quant_hdr = frame_header.quantization_hdr;
  static_assert(std::size(decltype(iq_matrix_buf->quantization_index){}) ==
                    kMaxMBSegments,
                "incorrect quantization matrix segment size");
  static_assert(
      std::size(decltype(iq_matrix_buf->quantization_index){}[0]) == 6,
      "incorrect quantization matrix Q index size");
  for (size_t i = 0; i < kMaxMBSegments; ++i) {
    int q = quant_hdr.y_ac_qi;

    if (sgmnt_hdr.segmentation_enabled) {
      if (sgmnt_hdr.segment_feature_mode ==
          Vp8SegmentationHeader::FEATURE_MODE_ABSOLUTE) {
        q = sgmnt_hdr.quantizer_update_value[i];
      } else {
        q += sgmnt_hdr.quantizer_update_value[i];
      }
    }

#define CLAMP_Q(q) std::clamp(q, 0, 127)
    iq_matrix_buf->quantization_index[i][0] = CLAMP_Q(q);
    iq_matrix_buf->quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta);
    iq_matrix_buf->quantization_index[i][2] =
        CLAMP_Q(q + quant_hdr.y2_dc_delta);
    iq_matrix_buf->quantization_index[i][3] =
        CLAMP_Q(q + quant_hdr.y2_ac_delta);
    iq_matrix_buf->quantization_index[i][4] =
        CLAMP_Q(q + quant_hdr.uv_dc_delta);
    iq_matrix_buf->quantization_index[i][5] =
        CLAMP_Q(q + quant_hdr.uv_ac_delta);
#undef CLAMP_Q
  }

  const Vp8EntropyHeader& entr_hdr = frame_header.entropy_hdr;
  CheckedMemcpy(prob_buf->dct_coeff_probs, entr_hdr.coeff_probs);

  pic_param->frame_width = frame_header.width;
  pic_param->frame_height = frame_header.height;

  const auto last_frame = reference_frames.GetFrame(Vp8RefType::VP8_FRAME_LAST);
  if (last_frame) {
    pic_param->last_ref_frame =
        last_frame->AsVaapiVP8Picture()->GetVASurfaceID();
  } else {
    pic_param->last_ref_frame = VA_INVALID_SURFACE;
  }

  const auto golden_frame =
      reference_frames.GetFrame(Vp8RefType::VP8_FRAME_GOLDEN);
  if (golden_frame) {
    pic_param->golden_ref_frame =
        golden_frame->AsVaapiVP8Picture()->GetVASurfaceID();
  } else {
    pic_param->golden_ref_frame = VA_INVALID_SURFACE;
  }

  const auto alt_frame =
      reference_frames.GetFrame(Vp8RefType::VP8_FRAME_ALTREF);
  if (alt_frame)
    pic_param->alt_ref_frame = alt_frame->AsVaapiVP8Picture()->GetVASurfaceID();
  else
    pic_param->alt_ref_frame = VA_INVALID_SURFACE;

  pic_param->out_of_loop_frame = VA_INVALID_SURFACE;

  const Vp8LoopFilterHeader& lf_hdr = frame_header.loopfilter_hdr;

#define FHDR_TO_PP_PF(a, b) pic_param->pic_fields.bits.a = (b)
  FHDR_TO_PP_PF(key_frame, frame_header.IsKeyframe() ? 0 : 1);
  FHDR_TO_PP_PF(version, frame_header.version);
  FHDR_TO_PP_PF(segmentation_enabled, sgmnt_hdr.segmentation_enabled);
  FHDR_TO_PP_PF(update_mb_segmentation_map,
                sgmnt_hdr.update_mb_segmentation_map);
  FHDR_TO_PP_PF(update_segment_feature_data,
                sgmnt_hdr.update_segment_feature_data);
  FHDR_TO_PP_PF(filter_type, lf_hdr.type);
  FHDR_TO_PP_PF(sharpness_level, lf_hdr.sharpness_level);
  FHDR_TO_PP_PF(loop_filter_adj_enable, lf_hdr.loop_filter_adj_enable);
  FHDR_TO_PP_PF(mode_ref_lf_delta_update, lf_hdr.mode_ref_lf_delta_update);
  FHDR_TO_PP_PF(sign_bias_golden, frame_header.sign_bias_golden);
  FHDR_TO_PP_PF(sign_bias_alternate, frame_header.sign_bias_alternate);
  FHDR_TO_PP_PF(mb_no_coeff_skip, frame_header.mb_no_skip_coeff);
  FHDR_TO_PP_PF(loop_filter_disable, lf_hdr.level == 0);
#undef FHDR_TO_PP_PF

  CheckedMemcpy(pic_param->mb_segment_tree_probs, sgmnt_hdr.segment_prob);

  static_assert(std::extent<decltype(sgmnt_hdr.lf_update_value)>() ==
                    std::extent<decltype(pic_param->loop_filter_level)>(),
                "loop filter level arrays mismatch");
  for (size_t i = 0; i < std::size(sgmnt_hdr.lf_update_value); ++i) {
    int lf_level = lf_hdr.level;
    if (sgmnt_hdr.segmentation_enabled) {
      if (sgmnt_hdr.segment_feature_mode ==
          Vp8SegmentationHeader::FEATURE_MODE_ABSOLUTE) {
        lf_level = sgmnt_hdr.lf_update_value[i];
      } else {
        lf_level += sgmnt_hdr.lf_update_value[i];
      }
    }

    pic_param->loop_filter_level[i] = std::clamp(lf_level, 0, 63);
  }

  static_assert(
      std::extent<decltype(lf_hdr.ref_frame_delta)>() ==
          std::extent<decltype(pic_param->loop_filter_deltas_ref_frame)>(),
      "loop filter deltas arrays size mismatch");
  static_assert(std::extent<decltype(lf_hdr.mb_mode_delta)>() ==
                    std::extent<decltype(pic_param->loop_filter_deltas_mode)>(),
                "loop filter deltas arrays size mismatch");
  static_assert(std::extent<decltype(lf_hdr.ref_frame_delta)>() ==
                    std::extent<decltype(lf_hdr.mb_mode_delta)>(),
                "loop filter deltas arrays size mismatch");
  for (size_t i = 0; i < std::size(lf_hdr.ref_frame_delta); ++i) {
    pic_param->loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i];
    pic_param->loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i];
  }

#define FHDR_TO_PP(a) pic_param->a = frame_header.a
  FHDR_TO_PP(prob_skip_false);
  FHDR_TO_PP(prob_intra);
  FHDR_TO_PP(prob_last);
  FHDR_TO_PP(prob_gf);
#undef FHDR_TO_PP

  CheckedMemcpy(pic_param->y_mode_probs, entr_hdr.y_mode_probs);
  CheckedMemcpy(pic_param->uv_mode_probs, entr_hdr.uv_mode_probs);
  CheckedMemcpy(pic_param->mv_probs, entr_hdr.mv_probs);

  pic_param->bool_coder_ctx.range = frame_header.bool_dec_range;
  pic_param->bool_coder_ctx.value = frame_header.bool_dec_value;
  pic_param->bool_coder_ctx.count = frame_header.bool_dec_count;

  slice_param->slice_data_size = frame_header.frame_size;
  slice_param->slice_data_offset = frame_header.first_part_offset;
  slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
  slice_param->macroblock_offset = frame_header.macroblock_bit_offset;
  // Number of DCT partitions plus control partition.
  slice_param->num_of_partitions = frame_header.num_of_dct_partitions + 1;

  // Per VAAPI, this size only includes the size of the macroblock data in
  // the first partition (in bytes), so we have to subtract the header size.
  slice_param->partition_size[0] =
      frame_header.first_part_size -
      ((frame_header.macroblock_bit_offset + 7) / 8);

  for (size_t i = 0; i < frame_header.num_of_dct_partitions; ++i)
    slice_param->partition_size[i + 1] = frame_header.dct_partition_sizes[i];
}

bool IsValidVABufferType(VABufferType type) {
  return type < VABufferTypeMax ||
#if BUILDFLAG(IS_CHROMEOS_ASH)
         // TODO(jkardatzke): Remove this once we update to libva 2.0.10 in
         // ChromeOS.
         type == VAEncryptionParameterBufferType ||
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
         type == VACencStatusParameterBufferType;
}

}  // namespace media
