// Copyright 2022 The Fuchsia 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 "mjpeg_accelerator.h"

#include <safemath/safe_conversions.h>
#include <va/va.h>

#include "codec_adapter_vaapi_decoder.h"
#include "vaapi_utils.h"

VaapiJpegPicture::VaapiJpegPicture(std::shared_ptr<VASurface> va_surface)
    : va_surface_(va_surface) {}

VaapiJpegPicture::~VaapiJpegPicture() = default;

MJPEGAccelerator::MJPEGAccelerator(CodecAdapterVaApiDecoder* adapter) : adapter_(adapter) {
  FX_DCHECK(adapter_);
}

MJPEGAccelerator::~MJPEGAccelerator() = default;

// Set picture parameters.
std::shared_ptr<media::JPEGPicture> MJPEGAccelerator::CreateJPEGPicture() {
  auto surface = adapter_->GetVASurface();
  auto surface_ptr = std::make_shared<VaapiJpegPicture>(surface);
  return surface_ptr;
}

MJPEGAccelerator::Status MJPEGAccelerator::SubmitDecode(
    std::shared_ptr<media::JPEGPicture> picture, const media::JpegParseResult& parse_result) {
  // Populate the picture parameters
  VAPictureParameterBufferJPEGBaseline pic_param{};
  PopulatePictureParameterBuffer(picture->frame_header(), pic_param);

  // Populate the IQ matrix
  VAIQMatrixBufferJPEGBaseline matrix_buffer{};
  PopulateIQMatrix(parse_result.q_table, matrix_buffer);

  // Populate huffman table
  VAHuffmanTableBufferJPEGBaseline huffman_table{};
  PopulateHuffmanTable(parse_result.dc_table, parse_result.ac_table, huffman_table);

  // Populate slice parameters
  VASliceParameterBufferJPEGBaseline slice_param{};
  PopulateSliceParameters(parse_result, slice_param);

  VAStatus status;
  VADisplay display = VADisplayWrapper::GetSingleton()->display();

  VABufferID pic_params_buffer_id;
  status = vaCreateBuffer(display, adapter_->context_id(), VAPictureParameterBufferType,
                          sizeof(pic_param), 1, &pic_param, &pic_params_buffer_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateBuffer for pic_param failed", FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }
  ScopedBufferID pic_params_buffer(pic_params_buffer_id);

  VABufferID iq_matrix_buffer_id;
  status = vaCreateBuffer(display, adapter_->context_id(), VAIQMatrixBufferType,
                          sizeof(matrix_buffer), 1, &matrix_buffer, &iq_matrix_buffer_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateBuffer for matrix_buffer failed",
            FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }
  ScopedBufferID iq_matrix_buffer(iq_matrix_buffer_id);

  VABufferID huffman_table_buffer_id;
  status = vaCreateBuffer(display, adapter_->context_id(), VAHuffmanTableBufferType,
                          sizeof(huffman_table), 1, &huffman_table, &huffman_table_buffer_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateBuffer for huffman_table failed",
            FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }
  ScopedBufferID huffman_table_buffer(huffman_table_buffer_id);

  VABufferID slice_param_buffer_id;
  status = vaCreateBuffer(display, adapter_->context_id(), VASliceParameterBufferType,
                          sizeof(slice_param), 1, &slice_param, &slice_param_buffer_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateBuffer for slice_param failed", FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }
  ScopedBufferID slice_param_buffer(slice_param_buffer_id);

  VABufferID jpeg_data_buffer_id;
  status = vaCreateBuffer(display, adapter_->context_id(), VASliceDataBufferType,
                          static_cast<unsigned int>(parse_result.data_size), 1,
                          reinterpret_cast<uint8_t*>(const_cast<char*>(parse_result.data)),
                          &jpeg_data_buffer_id);

  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "vaCreateBuffer for jpeg_data_buffer_id failed",
            FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }
  ScopedBufferID jpeg_data_buffer(jpeg_data_buffer_id);

  auto va_surface_id = static_cast<VaapiJpegPicture*>(picture.get())->GetVASurfaceID();
  status = vaBeginPicture(display, adapter_->context_id(), va_surface_id);
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "BeginPicture failed", FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }

  std::vector<VABufferID> buffers{pic_params_buffer.id(), iq_matrix_buffer.id(),
                                  huffman_table_buffer.id(), slice_param_buffer.id(),
                                  jpeg_data_buffer.id()};
  status = vaRenderPicture(display, adapter_->context_id(), buffers.data(),
                           static_cast<int>(buffers.size()));
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "RenderPicture failed", FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }

  status = vaEndPicture(display, adapter_->context_id());
  if (status != VA_STATUS_SUCCESS) {
    FX_SLOG(ERROR, "EndPicture failed", FX_KV("error_str", vaErrorStr(status)));
    return Status::kFail;
  }

  return Status::kOk;
}

bool MJPEGAccelerator::OutputPicture(std::shared_ptr<media::JPEGPicture> picture) {
  auto va_surface = static_cast<VaapiJpegPicture*>(picture.get())->va_surface();
  return adapter_->ProcessOutput(va_surface, picture->bitstream_id());
}

void MJPEGAccelerator::PopulatePictureParameterBuffer(
    const media::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 component_idx = 0; component_idx < pic_param.num_components; component_idx += 1) {
    const auto& header_comp = frame_header.components[component_idx];
    auto& pic_comp = pic_param.components[component_idx];

    pic_comp.component_id = header_comp.id;
    pic_comp.h_sampling_factor = header_comp.horizontal_sampling_factor;
    pic_comp.v_sampling_factor = header_comp.vertical_sampling_factor;
    pic_comp.quantiser_table_selector = header_comp.quantization_table_selector;
  }
}

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

void MJPEGAccelerator::PopulateHuffmanTable(
    const media::JpegHuffmanTable dc_table[media::kJpegMaxHuffmanTableNumBaseline],
    const media::JpegHuffmanTable ac_table[media::kJpegMaxHuffmanTableNumBaseline],
    VAHuffmanTableBufferJPEGBaseline& huffman_table) {
  // Use default huffman tables if not specified in header.
  bool has_huffman_table = false;
  for (size_t i = 0; i < media::kJpegMaxHuffmanTableNumBaseline; i++) {
    if (dc_table[i].valid || ac_table[i].valid) {
      has_huffman_table = true;
      break;
    }
  }

  if (!has_huffman_table) {
    dc_table = media::kDefaultDcTable;
    ac_table = media::kDefaultAcTable;
  }

  static_assert(media::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 < media::kJpegMaxHuffmanTableNumBaseline; i++) {
    if (!dc_table[i].valid || !ac_table[i].valid) {
      continue;
    }

    huffman_table.load_huffman_table[i] = 1;
    std::memcpy(huffman_table.huffman_table[i].num_dc_codes, dc_table[i].code_length,
                sizeof(huffman_table.huffman_table[i].num_dc_codes));
    std::memcpy(huffman_table.huffman_table[i].dc_values, dc_table[i].code_value,
                sizeof(huffman_table.huffman_table[i].dc_values));
    std::memcpy(huffman_table.huffman_table[i].num_ac_codes, ac_table[i].code_length,
                sizeof(huffman_table.huffman_table[i].num_ac_codes));
    std::memcpy(huffman_table.huffman_table[i].ac_values, ac_table[i].code_value,
                sizeof(huffman_table.huffman_table[i].ac_values));
  }
}

void MJPEGAccelerator::PopulateSliceParameters(const media::JpegParseResult& parse_result,
                                               VASliceParameterBufferJPEGBaseline& slice_param) {
  slice_param.slice_data_size = safemath::checked_cast<uint32_t>(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 = safemath::strict_cast<int>(
      parse_result.frame_header.components[0].horizontal_sampling_factor);
  int max_v_factor =
      safemath::strict_cast<int>(parse_result.frame_header.components[0].vertical_sampling_factor);
  int mcu_cols =
      safemath::strict_cast<int>(parse_result.frame_header.coded_width) / (max_h_factor * 8);
  int mcu_rows =
      safemath::strict_cast<int>(parse_result.frame_header.coded_height) / (max_v_factor * 8);
  FX_DCHECK(mcu_cols > 0);
  FX_DCHECK(mcu_rows > 0);
  slice_param.num_mcus = mcu_rows * mcu_cols;
}
