// Copyright 2019 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/vaapi_jpeg_decoder.h"

#include <string.h>
#include <va/va.h>

#include <iostream>
#include <type_traits>

#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "media/base/video_types.h"
#include "media/gpu/macros.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/parsers/jpeg_parser.h"
#include "ui/gfx/geometry/size.h"

namespace media {

namespace {

static void FillPictureParameters(
    const JpegFrameHeader& frame_header,
    VAPictureParameterBufferJPEGBaseline* pic_param) {
  pic_param->picture_width = frame_header.coded_width;
  pic_param->picture_height = frame_header.coded_height;
  pic_param->num_components = frame_header.num_components;

  for (int i = 0; i < pic_param->num_components; i++) {
    pic_param->components[i].component_id = frame_header.components[i].id;
    pic_param->components[i].h_sampling_factor =
        frame_header.components[i].horizontal_sampling_factor;
    pic_param->components[i].v_sampling_factor =
        frame_header.components[i].vertical_sampling_factor;
    pic_param->components[i].quantiser_table_selector =
        frame_header.components[i].quantization_table_selector;
  }
}

static void FillIQMatrix(const JpegQuantizationTable* q_table,
                         VAIQMatrixBufferJPEGBaseline* iq_matrix) {
  static_assert(kJpegMaxQuantizationTableNum ==
                    std::extent<decltype(iq_matrix->load_quantiser_table)>(),
                "max number of quantization table mismatched");
  static_assert(
      sizeof(iq_matrix->quantiser_table[0]) == sizeof(q_table[0].value),
      "number of quantization entries mismatched");
  for (size_t i = 0; i < kJpegMaxQuantizationTableNum; i++) {
    if (!q_table[i].valid)
      continue;
    iq_matrix->load_quantiser_table[i] = 1;
    for (size_t j = 0; j < base::size(q_table[i].value); j++)
      iq_matrix->quantiser_table[i][j] = q_table[i].value[j];
  }
}

static void FillHuffmanTable(const JpegHuffmanTable* dc_table,
                             const JpegHuffmanTable* ac_table,
                             VAHuffmanTableBufferJPEGBaseline* huffman_table) {
  // Use default huffman tables if not specified in header.
  bool has_huffman_table = false;
  for (size_t i = 0; i < kJpegMaxHuffmanTableNumBaseline; i++) {
    if (dc_table[i].valid || ac_table[i].valid) {
      has_huffman_table = true;
      break;
    }
  }
  if (!has_huffman_table) {
    dc_table = kDefaultDcTable;
    ac_table = kDefaultAcTable;
  }

  static_assert(kJpegMaxHuffmanTableNumBaseline ==
                    std::extent<decltype(huffman_table->load_huffman_table)>(),
                "max number of huffman table mismatched");
  static_assert(sizeof(huffman_table->huffman_table[0].num_dc_codes) ==
                    sizeof(dc_table[0].code_length),
                "size of huffman table code length mismatch");
  static_assert(sizeof(huffman_table->huffman_table[0].dc_values[0]) ==
                    sizeof(dc_table[0].code_value[0]),
                "size of huffman table code value mismatch");
  for (size_t i = 0; i < kJpegMaxHuffmanTableNumBaseline; i++) {
    if (!dc_table[i].valid || !ac_table[i].valid)
      continue;
    huffman_table->load_huffman_table[i] = 1;

    memcpy(huffman_table->huffman_table[i].num_dc_codes,
           dc_table[i].code_length,
           sizeof(huffman_table->huffman_table[i].num_dc_codes));
    memcpy(huffman_table->huffman_table[i].dc_values, dc_table[i].code_value,
           sizeof(huffman_table->huffman_table[i].dc_values));
    memcpy(huffman_table->huffman_table[i].num_ac_codes,
           ac_table[i].code_length,
           sizeof(huffman_table->huffman_table[i].num_ac_codes));
    memcpy(huffman_table->huffman_table[i].ac_values, ac_table[i].code_value,
           sizeof(huffman_table->huffman_table[i].ac_values));
  }
}

static void FillSliceParameters(
    const JpegParseResult& parse_result,
    VASliceParameterBufferJPEGBaseline* slice_param) {
  slice_param->slice_data_size = parse_result.data_size;
  slice_param->slice_data_offset = 0;
  slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
  slice_param->slice_horizontal_position = 0;
  slice_param->slice_vertical_position = 0;
  slice_param->num_components = parse_result.scan.num_components;
  for (int i = 0; i < slice_param->num_components; i++) {
    slice_param->components[i].component_selector =
        parse_result.scan.components[i].component_selector;
    slice_param->components[i].dc_table_selector =
        parse_result.scan.components[i].dc_selector;
    slice_param->components[i].ac_table_selector =
        parse_result.scan.components[i].ac_selector;
  }
  slice_param->restart_interval = parse_result.restart_interval;

  // Cast to int to prevent overflow.
  int max_h_factor =
      parse_result.frame_header.components[0].horizontal_sampling_factor;
  int max_v_factor =
      parse_result.frame_header.components[0].vertical_sampling_factor;
  int mcu_cols = parse_result.frame_header.coded_width / (max_h_factor * 8);
  DCHECK_GT(mcu_cols, 0);
  int mcu_rows = parse_result.frame_header.coded_height / (max_v_factor * 8);
  DCHECK_GT(mcu_rows, 0);
  slice_param->num_mcus = mcu_rows * mcu_cols;
}

// VAAPI only supports a subset of JPEG profiles. This function determines
// whether a given parsed JPEG result is supported or not.
static bool IsVaapiSupportedJpeg(const JpegParseResult& jpeg) {
  // Make sure the JPEG's chroma subsampling format is supported.
  if (!VaapiWrapper::IsDecodingSupportedForInternalFormat(
          VAProfileJPEGBaseline, VaSurfaceFormatForJpeg(jpeg.frame_header))) {
    DLOG(ERROR) << "The JPEG's subsampling format is unsupported";
    return false;
  }

  // Validate the visible size.
  if (jpeg.frame_header.visible_width == 0u) {
    DLOG(ERROR) << "Visible width can't be zero";
    return false;
  }
  if (jpeg.frame_header.visible_height == 0u) {
    DLOG(ERROR) << "Visible height can't be zero";
    return false;
  }

  // Validate the coded size.
  gfx::Size min_jpeg_resolution;
  if (!VaapiWrapper::GetDecodeMinResolution(VAProfileJPEGBaseline,
                                            &min_jpeg_resolution)) {
    DLOG(ERROR) << "Could not get the minimum resolution";
    return false;
  }
  gfx::Size max_jpeg_resolution;
  if (!VaapiWrapper::GetDecodeMaxResolution(VAProfileJPEGBaseline,
                                            &max_jpeg_resolution)) {
    DLOG(ERROR) << "Could not get the maximum resolution";
    return false;
  }
  const int actual_jpeg_coded_width =
      base::strict_cast<int>(jpeg.frame_header.coded_width);
  const int actual_jpeg_coded_height =
      base::strict_cast<int>(jpeg.frame_header.coded_height);
  if (actual_jpeg_coded_width < min_jpeg_resolution.width() ||
      actual_jpeg_coded_height < min_jpeg_resolution.height() ||
      actual_jpeg_coded_width > max_jpeg_resolution.width() ||
      actual_jpeg_coded_height > max_jpeg_resolution.height()) {
    DLOG(ERROR) << "VAAPI doesn't support size " << actual_jpeg_coded_width
                << "x" << actual_jpeg_coded_height << ": not in range "
                << min_jpeg_resolution.ToString() << " - "
                << max_jpeg_resolution.ToString();
    return false;
  }

  return true;
}

}  // namespace

unsigned int VaSurfaceFormatForJpeg(const JpegFrameHeader& frame_header) {
  if (frame_header.num_components != 3)
    return kInvalidVaRtFormat;

  const uint8_t y_h = frame_header.components[0].horizontal_sampling_factor;
  const uint8_t y_v = frame_header.components[0].vertical_sampling_factor;
  const uint8_t u_h = frame_header.components[1].horizontal_sampling_factor;
  const uint8_t u_v = frame_header.components[1].vertical_sampling_factor;
  const uint8_t v_h = frame_header.components[2].horizontal_sampling_factor;
  const uint8_t v_v = frame_header.components[2].vertical_sampling_factor;

  if (u_h != 1 || u_v != 1 || v_h != 1 || v_v != 1)
    return kInvalidVaRtFormat;

  if (y_h == 2 && y_v == 2)
    return VA_RT_FORMAT_YUV420;
  else if (y_h == 2 && y_v == 1)
    return VA_RT_FORMAT_YUV422;
  else if (y_h == 1 && y_v == 1)
    return VA_RT_FORMAT_YUV444;
  return kInvalidVaRtFormat;
}

VaapiJpegDecoder::VaapiJpegDecoder()
    : VaapiImageDecoder(VAProfileJPEGBaseline) {}

VaapiJpegDecoder::~VaapiJpegDecoder() = default;

VaapiImageDecodeStatus VaapiJpegDecoder::AllocateVASurfaceAndSubmitVABuffers(
    base::span<const uint8_t> encoded_image) {
  DCHECK(vaapi_wrapper_);

  // Parse the JPEG encoded data.
  JpegParseResult parse_result;
  if (!ParseJpegPicture(encoded_image.data(), encoded_image.size(),
                        &parse_result)) {
    VLOGF(1) << "ParseJpegPicture failed";
    return VaapiImageDecodeStatus::kParseFailed;
  }

  // Figure out the right format for the VaSurface.
  const unsigned int picture_va_rt_format =
      VaSurfaceFormatForJpeg(parse_result.frame_header);
  if (picture_va_rt_format == kInvalidVaRtFormat) {
    VLOGF(1) << "Unsupported subsampling";
    return VaapiImageDecodeStatus::kUnsupportedSubsampling;
  }

  // Make sure this JPEG can be decoded.
  if (!IsVaapiSupportedJpeg(parse_result)) {
    VLOGF(1) << "The supplied JPEG is unsupported";
    return VaapiImageDecodeStatus::kUnsupportedImage;
  }

  // Prepare the surface for decoding.
  const gfx::Size new_visible_size(
      base::strict_cast<int>(parse_result.frame_header.visible_width),
      base::strict_cast<int>(parse_result.frame_header.visible_height));
  const gfx::Size new_coded_size(
      base::strict_cast<int>(parse_result.frame_header.coded_width),
      base::strict_cast<int>(parse_result.frame_header.coded_height));
  if (!MaybeCreateSurface(picture_va_rt_format, new_coded_size,
                          new_visible_size)) {
    return VaapiImageDecodeStatus::kSurfaceCreationFailed;
  }

  // Submit input buffers.
  if (!SubmitBuffers(parse_result))
    return VaapiImageDecodeStatus::kSubmitVABuffersFailed;

  return VaapiImageDecodeStatus::kSuccess;
}

gpu::ImageDecodeAcceleratorType VaapiJpegDecoder::GetType() const {
  return gpu::ImageDecodeAcceleratorType::kJpeg;
}

SkYUVColorSpace VaapiJpegDecoder::GetYUVColorSpace() const {
  return SkYUVColorSpace::kJPEG_SkYUVColorSpace;
}

std::unique_ptr<ScopedVAImage> VaapiJpegDecoder::GetImage(
    uint32_t preferred_image_fourcc,
    VaapiImageDecodeStatus* status) {
  if (!scoped_va_context_and_surface_) {
    VLOGF(1) << "No decoded JPEG available";
    *status = VaapiImageDecodeStatus::kInvalidState;
    return nullptr;
  }

  DCHECK(scoped_va_context_and_surface_->IsValid());
  DCHECK(vaapi_wrapper_);
  uint32_t image_fourcc;
  if (!VaapiWrapper::GetJpegDecodeSuitableImageFourCC(
          scoped_va_context_and_surface_->format(), preferred_image_fourcc,
          &image_fourcc)) {
    VLOGF(1) << "Cannot determine the output FOURCC";
    *status = VaapiImageDecodeStatus::kCannotGetImage;
    return nullptr;
  }
  VAImageFormat image_format{.fourcc = image_fourcc};
  // In at least one driver, the VPP seems to have problems if we request a
  // VAImage with odd dimensions. Rather than debugging the issue in depth, we
  // disable support for odd dimensions since the VAImage path is only expected
  // to be used in camera captures (and we don't expect JPEGs with odd
  // dimensions in that path).
  if ((scoped_va_context_and_surface_->size().width() & 1) ||
      (scoped_va_context_and_surface_->size().height() & 1)) {
    VLOGF(1) << "Getting images with odd dimensions is not supported";
    *status = VaapiImageDecodeStatus::kCannotGetImage;
    NOTREACHED();
    return nullptr;
  }
  auto scoped_image = vaapi_wrapper_->CreateVaImage(
      scoped_va_context_and_surface_->id(), &image_format,
      scoped_va_context_and_surface_->size());
  if (!scoped_image) {
    VLOGF(1) << "Cannot get VAImage, FOURCC = "
             << FourccToString(image_format.fourcc);
    *status = VaapiImageDecodeStatus::kCannotGetImage;
    return nullptr;
  }

  *status = VaapiImageDecodeStatus::kSuccess;
  return scoped_image;
}

bool VaapiJpegDecoder::MaybeCreateSurface(unsigned int picture_va_rt_format,
                                          const gfx::Size& new_coded_size,
                                          const gfx::Size& new_visible_size) {
  DCHECK(!scoped_va_context_and_surface_ ||
         scoped_va_context_and_surface_->IsValid());
  if (scoped_va_context_and_surface_ &&
      new_visible_size == scoped_va_context_and_surface_->size() &&
      picture_va_rt_format == scoped_va_context_and_surface_->format()) {
    // No need to allocate a new surface. We can re-use the current one.
    return true;
  }

  scoped_va_context_and_surface_.reset();

  // We'll request a surface of |new_coded_size| from the VAAPI, but we will
  // keep track of the |new_visible_size| inside the ScopedVASurface so that
  // when we create a VAImage or export the surface as a NativePixmapDmaBuf, we
  // can report the size that clients should be using to read the contents.
  auto scoped_va_surfaces = vaapi_wrapper_->CreateContextAndScopedVASurfaces(
      picture_va_rt_format, new_coded_size,
      {VaapiWrapper::SurfaceUsageHint::kGeneric}, 1u, new_visible_size);
  if (scoped_va_surfaces.empty()) {
    VLOGF(1) << "CreateContextAndScopedVASurface() failed";
    return false;
  }

  scoped_va_context_and_surface_.reset(scoped_va_surfaces[0].release());
  DCHECK(scoped_va_context_and_surface_->IsValid());
  return true;
}

bool VaapiJpegDecoder::SubmitBuffers(const JpegParseResult& parse_result) {
  // Set picture parameters.
  VAPictureParameterBufferJPEGBaseline pic_param{};
  FillPictureParameters(parse_result.frame_header, &pic_param);

  // Set quantization table.
  VAIQMatrixBufferJPEGBaseline iq_matrix{};
  FillIQMatrix(parse_result.q_table, &iq_matrix);

  // Set huffman table.
  VAHuffmanTableBufferJPEGBaseline huffman_table{};
  FillHuffmanTable(parse_result.dc_table, parse_result.ac_table,
                   &huffman_table);

  // Set slice parameters.
  VASliceParameterBufferJPEGBaseline slice_param{};
  FillSliceParameters(parse_result, &slice_param);

  return vaapi_wrapper_->SubmitBuffers(
      {{VAPictureParameterBufferType, sizeof(pic_param), &pic_param},
       {VAIQMatrixBufferType, sizeof(iq_matrix), &iq_matrix},
       {VAHuffmanTableBufferType, sizeof(huffman_table), &huffman_table},
       {VASliceParameterBufferType, sizeof(slice_param), &slice_param},
       {VASliceDataBufferType, parse_result.data_size,
        const_cast<char*>(parse_result.data)}});
}

}  // namespace media
