// Copyright 2020 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/test/vp9_decoder.h"

#include <va/va.h>

#include "media/filters/ivf_parser.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/test/macros.h"
#include "media/gpu/vaapi/test/scoped_va_config.h"
#include "media/gpu/vaapi/test/scoped_va_context.h"
#include "media/gpu/vaapi/test/shared_va_surface.h"
#include "media/gpu/vaapi/test/vaapi_device.h"

namespace media {
namespace vaapi_test {

namespace {

// Returns the VAProfile from |frame_hdr|.
VAProfile GetProfile(Vp9FrameHeader frame_hdr) {
  switch (frame_hdr.profile) {
    case 0:
      return VAProfileVP9Profile0;
    case 1:
      break;
    case 2:
      LOG_ASSERT(frame_hdr.bit_depth == 10)
          << "Only 10-bit streams are supported for VP9 profile 2";
      return VAProfileVP9Profile2;
    case 3:
      break;
    default:
      break;
  }

  LOG_ASSERT(false) << "Unsupported VP9 profile " << frame_hdr.profile;
  return VAProfileNone;
}

// Returns the preferred VA_RT_FORMAT for the given |profile|.
// TODO(jchinlee): Have format dependent on bit depth, not profile.
unsigned int GetFormatForProfile(VAProfile profile) {
  if (profile == VAProfileVP9Profile2 || profile == VAProfileVP9Profile3)
    return VA_RT_FORMAT_YUV420_10;
  return VA_RT_FORMAT_YUV420;
}

}  // namespace

Vp9Decoder::Vp9Decoder(std::unique_ptr<IvfParser> ivf_parser,
                       const VaapiDevice& va_device,
                       SharedVASurface::FetchPolicy fetch_policy)
    : VideoDecoder::VideoDecoder(std::move(ivf_parser),
                                 va_device,
                                 fetch_policy),
      vp9_parser_(
          std::make_unique<Vp9Parser>(/*parsing_compressed_header=*/false)),
      ref_frames_(kVp9NumRefFrames) {}

Vp9Decoder::~Vp9Decoder() {
  // We destroy the VA handles explicitly to ensure the correct order.
  // The configuration must be destroyed after the context so that the
  // configuration reference remains valid in the context, and surfaces can only
  // be destroyed after the context as per
  // https://github.com/intel/libva/blob/8c6126e67c446f4c7808cb51b609077e4b9bd8fe/va/va.h#L1549
  va_context_.reset();
  va_config_.reset();

  ref_frames_.clear();
  last_decoded_surface_.reset();
}

Vp9Parser::Result Vp9Decoder::ReadNextFrame(Vp9FrameHeader& vp9_frame_header,
                                            gfx::Size& size) {
  while (true) {
    std::unique_ptr<DecryptConfig> null_config;
    Vp9Parser::Result res =
        vp9_parser_->ParseNextFrame(&vp9_frame_header, &size, &null_config);
    if (res == Vp9Parser::kEOStream) {
      IvfFrameHeader ivf_frame_header{};
      const uint8_t* ivf_frame_data;

      if (!ivf_parser_->ParseNextFrame(&ivf_frame_header, &ivf_frame_data))
        return Vp9Parser::kEOStream;

      vp9_parser_->SetStream(ivf_frame_data, ivf_frame_header.frame_size,
                             /*stream_config=*/nullptr);
      continue;
    }

    return res;
  }
}

void Vp9Decoder::RefreshReferenceSlots(uint8_t refresh_frame_flags,
                                       scoped_refptr<SharedVASurface> surface) {
  const std::bitset<kVp9NumRefFrames> slots(refresh_frame_flags);
  for (size_t i = 0; i < kVp9NumRefFrames; i++) {
    if (slots[i])
      ref_frames_[i] = surface;
  }
}

VideoDecoder::Result Vp9Decoder::DecodeNextFrame() {
  // Parse next frame from stream.
  gfx::Size size;
  Vp9FrameHeader frame_hdr{};
  Vp9Parser::Result parser_res = ReadNextFrame(frame_hdr, size);
  if (parser_res == Vp9Parser::kEOStream)
    return VideoDecoder::kEOStream;
  LOG_ASSERT(parser_res == Vp9Parser::kOk)
      << "Failed to parse next frame, got " << parser_res;

  VLOG_IF(2, !frame_hdr.show_frame) << "not displaying frame";
  last_decoded_frame_visible_ = frame_hdr.show_frame;

  if (frame_hdr.show_existing_frame) {
    last_decoded_surface_ = ref_frames_[frame_hdr.frame_to_show_map_idx];
    LOG_ASSERT(last_decoded_surface_)
        << "got invalid surface as existing frame to decode";
    VLOG(2) << "ref_frame: " << last_decoded_surface_->id();
    return VideoDecoder::kOk;
  }

  const VAProfile profile = GetProfile(frame_hdr);
  // Note: some streams may fail to decode; see
  // https://source.chromium.org/chromium/chromium/src/+/main:media/gpu/vp9_decoder.cc;l=249-285;drc=3893688a88eb1b4cf39e346fd8f8c743ad255469
  if (!va_config_ || va_config_->profile() != profile) {
    va_context_.reset();
    va_config_ = std::make_unique<ScopedVAConfig>(va_device_, profile,
                                                  GetFormatForProfile(profile));
  }

  // [Re]create context for decode.
  // A resolution change may occur on a frame that is neither keyframe nor
  // intra-only, i.e. may refer to earlier frames. If the earlier referred frame
  // is larger than the new frame, consequently, do *not* recreate the context.
  // See also
  // https://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/tree/gst-libs/gst/vaapi/gstvaapidecoder_vp9.c?h=1.18#n652
  if (!va_context_ || va_context_->size().width() < size.width() ||
      va_context_->size().height() < size.height()) {
    va_context_ =
        std::make_unique<ScopedVAContext>(va_device_, *va_config_, size);
  }

  // Create surfaces for decode.
  VASurfaceAttrib attribute{};
  attribute.type = VASurfaceAttribUsageHint;
  attribute.flags = VA_SURFACE_ATTRIB_SETTABLE;
  attribute.value.type = VAGenericValueTypeInteger;
  attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER;
  scoped_refptr<SharedVASurface> surface = SharedVASurface::Create(
      va_device_, va_config_->va_rt_format(), size, attribute);

  const Vp9Parser::Context& context = vp9_parser_->context();
  const Vp9SegmentationParams& seg = context.segmentation();
  const Vp9LoopFilterParams& lf = context.loop_filter();

  // Set up buffer for picture level parameters.
  VADecPictureParameterBufferVP9 pic_param{};

  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));
  CHECK_EQ(kVp9NumRefFrames, ref_frames_.size());
  for (size_t i = 0; i < base::size(pic_param.reference_frames); ++i) {
    pic_param.reference_frames[i] =
        ref_frames_[i] ? ref_frames_[i]->id() : 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));

  std::vector<VABufferID> buffers;
  VABufferID buffer_id;
  VAStatus res = vaCreateBuffer(
      va_device_.display(), va_context_->id(), VAPictureParameterBufferType,
      sizeof(VADecPictureParameterBufferVP9), 1u, &pic_param, &buffer_id);
  VA_LOG_ASSERT(res, "vaCreateBuffer");
  buffers.push_back(buffer_id);

  // Set up buffer for slice decoding.
  VASliceParameterBufferVP9 slice_param{};
  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;

  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];
  }

  res = vaCreateBuffer(
      va_device_.display(), va_context_->id(), VASliceParameterBufferType,
      sizeof(VASliceParameterBufferVP9), 1u, &slice_param, &buffer_id);
  VA_LOG_ASSERT(res, "vaCreateBuffer");
  buffers.push_back(buffer_id);

  // Set up buffer for frame header.
  res = vaCreateBuffer(va_device_.display(), va_context_->id(),
                       VASliceDataBufferType, frame_hdr.frame_size, 1u,
                       const_cast<uint8_t*>(frame_hdr.data), &buffer_id);
  VA_LOG_ASSERT(res, "vaCreateBuffer");
  buffers.push_back(buffer_id);

  res = vaBeginPicture(va_device_.display(), va_context_->id(), surface->id());
  VA_LOG_ASSERT(res, "vaBeginPicture");

  res = vaRenderPicture(va_device_.display(), va_context_->id(), buffers.data(),
                        buffers.size());
  VA_LOG_ASSERT(res, "vaRenderPicture");

  res = vaEndPicture(va_device_.display(), va_context_->id());
  VA_LOG_ASSERT(res, "vaEndPicture");

  last_decoded_surface_ = surface;

  RefreshReferenceSlots(frame_hdr.refresh_frame_flags, surface);

  for (auto id : buffers)
    vaDestroyBuffer(va_device_.display(), id);
  buffers.clear();

  return VideoDecoder::kOk;
}

}  // namespace vaapi_test
}  // namespace media
