// Copyright 2017 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/mojo/mojom/video_encode_accelerator_mojom_traits.h"

#include <optional>

#include "base/notreached.h"
#include "media/base/video_bitrate_allocation.h"
#include "media/mojo/mojom/video_encode_accelerator.mojom.h"
#include "media/video/video_encode_accelerator.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"

namespace mojo {

// static
media::mojom::VideoEncodeAcceleratorSupportedRateControlMode
EnumTraits<media::mojom::VideoEncodeAcceleratorSupportedRateControlMode,
           media::VideoEncodeAccelerator::SupportedRateControlMode>::
    ToMojom(media::VideoEncodeAccelerator::SupportedRateControlMode mode) {
  switch (mode) {
    case media::VideoEncodeAccelerator::kNoMode:
      return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
          kNoMode;
    case media::VideoEncodeAccelerator::kConstantMode:
      return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
          kConstantMode;
    case media::VideoEncodeAccelerator::kVariableMode:
      return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
          kVariableMode;
    case media::VideoEncodeAccelerator::kExternalMode:
      return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
          kExternalMode;
  }
  NOTREACHED_NORETURN();
}

// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorSupportedRateControlMode,
                media::VideoEncodeAccelerator::SupportedRateControlMode>::
    FromMojom(media::mojom::VideoEncodeAcceleratorSupportedRateControlMode mode,
              media::VideoEncodeAccelerator::SupportedRateControlMode* out) {
  switch (mode) {
    case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::kNoMode:
      *out = media::VideoEncodeAccelerator::kNoMode;
      return true;
    case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
        kConstantMode:
      *out = media::VideoEncodeAccelerator::kConstantMode;
      return true;
    case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
        kVariableMode:
      *out = media::VideoEncodeAccelerator::kVariableMode;
      return true;
    case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
        kExternalMode:
      *out = media::VideoEncodeAccelerator::kExternalMode;
      return true;
  }
  NOTREACHED_NORETURN();
}

// static
bool StructTraits<media::mojom::VideoEncodeAcceleratorSupportedProfileDataView,
                  media::VideoEncodeAccelerator::SupportedProfile>::
    Read(media::mojom::VideoEncodeAcceleratorSupportedProfileDataView data,
         media::VideoEncodeAccelerator::SupportedProfile* out) {
  if (!data.ReadMinResolution(&out->min_resolution) ||
      !data.ReadMaxResolution(&out->max_resolution) ||
      !data.ReadProfile(&out->profile)) {
    return false;
  }

  out->max_framerate_numerator = data.max_framerate_numerator();
  out->max_framerate_denominator = data.max_framerate_denominator();
  out->rate_control_modes = media::VideoEncodeAccelerator::kNoMode;
  std::vector<media::VideoEncodeAccelerator::SupportedRateControlMode> modes;
  if (!data.ReadRateControlModes(&modes))
    return false;
  for (const auto& mode : modes) {
    out->rate_control_modes |= mode;
  }

  std::vector<media::SVCScalabilityMode> scalability_modes;
  if (!data.ReadScalabilityModes(&scalability_modes))
    return false;
  out->scalability_modes = std::move(scalability_modes);

  out->is_software_codec = data.is_software_codec();

  return true;
}

// static
bool StructTraits<media::mojom::VariableBitratePeakDataView, uint32_t>::Read(
    media::mojom::VariableBitratePeakDataView data,
    uint32_t* out_peak_bps) {
  uint32_t peak_bps = data.bps();
  if (peak_bps == 0)
    return false;
  *out_peak_bps = peak_bps;
  return true;
}

// static
std::vector<uint32_t> StructTraits<media::mojom::VideoBitrateAllocationDataView,
                                   media::VideoBitrateAllocation>::
    bitrates(const media::VideoBitrateAllocation& bitrate_allocation) {
  std::vector<uint32_t> bitrates;
  uint32_t sum_bps = 0;
  for (size_t si = 0; si < media::VideoBitrateAllocation::kMaxSpatialLayers;
       ++si) {
    for (size_t ti = 0; ti < media::VideoBitrateAllocation::kMaxTemporalLayers;
         ++ti) {
      if (sum_bps == bitrate_allocation.GetSumBps()) {
        // The rest is all zeros, no need to iterate further.
        return bitrates;
      }
      const uint32_t layer_bitrate = bitrate_allocation.GetBitrateBps(si, ti);
      bitrates.emplace_back(layer_bitrate);
      sum_bps += layer_bitrate;
    }
  }
  return bitrates;
}

// static
bool StructTraits<media::mojom::VideoBitrateAllocationDataView,
                  media::VideoBitrateAllocation>::
    Read(media::mojom::VideoBitrateAllocationDataView data,
         media::VideoBitrateAllocation* out_bitrate_allocation) {
  std::optional<uint32_t> peak_bps;
  if (!data.ReadVariableBitratePeak(&peak_bps))
    return false;
  if (peak_bps.has_value()) {
    *out_bitrate_allocation =
        media::VideoBitrateAllocation(media::Bitrate::Mode::kVariable);
  } else {
    *out_bitrate_allocation =
        media::VideoBitrateAllocation(media::Bitrate::Mode::kConstant);
  }
  ArrayDataView<uint32_t> bitrates;
  data.GetBitratesDataView(&bitrates);
  size_t size = bitrates.size();
  if (size > media::VideoBitrateAllocation::kMaxSpatialLayers *
                 media::VideoBitrateAllocation::kMaxTemporalLayers) {
    return false;
  }
  for (size_t i = 0; i < size; ++i) {
    const uint32_t bitrate = bitrates[i];
    const size_t si = i / media::VideoBitrateAllocation::kMaxTemporalLayers;
    const size_t ti = i % media::VideoBitrateAllocation::kMaxTemporalLayers;
    if (!out_bitrate_allocation->SetBitrate(si, ti, bitrate)) {
      return false;
    }
  }

  if (peak_bps.has_value()) {
    if (!out_bitrate_allocation->SetPeakBps(*peak_bps)) {
      // Invalid (too low) peak for the sum of the bitrates.
      return false;
    }
  }

  return true;
}

// static
bool StructTraits<media::mojom::VideoEncodeOptionsDataView,
                  media::VideoEncoder::EncodeOptions>::
    Read(media::mojom::VideoEncodeOptionsDataView data,
         media::VideoEncoder::EncodeOptions* out_options) {
  out_options->key_frame = data.force_keyframe();
  int32_t quantizer = data.quantizer();
  if (quantizer < 0) {
    out_options->quantizer.reset();
  } else {
    out_options->quantizer = data.quantizer();
  }

  return true;
}

// static
bool UnionTraits<media::mojom::CodecMetadataDataView,
                 media::BitstreamBufferMetadata>::
    Read(media::mojom::CodecMetadataDataView data,
         media::BitstreamBufferMetadata* out) {
  switch (data.tag()) {
    case media::mojom::CodecMetadataDataView::Tag::kH264: {
      return data.ReadH264(&out->h264);
    }
    case media::mojom::CodecMetadataDataView::Tag::kVp8: {
      return data.ReadVp8(&out->vp8);
    }
    case media::mojom::CodecMetadataDataView::Tag::kVp9: {
      return data.ReadVp9(&out->vp9);
    }
    case media::mojom::CodecMetadataDataView::Tag::kAv1: {
      return data.ReadAv1(&out->av1);
    }
    case media::mojom::CodecMetadataDataView::Tag::kH265: {
      return data.ReadH265(&out->h265);
    }
  }
  NOTREACHED_NORETURN();
}

// static
bool StructTraits<media::mojom::BitstreamBufferMetadataDataView,
                  media::BitstreamBufferMetadata>::
    Read(media::mojom::BitstreamBufferMetadataDataView data,
         media::BitstreamBufferMetadata* metadata) {
  metadata->payload_size_bytes = data.payload_size_bytes();
  metadata->key_frame = data.key_frame();
  if (!data.ReadTimestamp(&metadata->timestamp)) {
    return false;
  }
  metadata->end_of_picture = data.end_of_picture();
  metadata->qp = data.qp();
  if (!data.ReadEncodedSize(&metadata->encoded_size)) {
    return false;
  }
  if (!data.ReadEncodedColorSpace(&metadata->encoded_color_space)) {
    return false;
  }

  return data.ReadCodecMetadata(metadata);
}

// static
bool StructTraits<media::mojom::H264MetadataDataView, media::H264Metadata>::
    Read(media::mojom::H264MetadataDataView data,
         media::H264Metadata* out_metadata) {
  out_metadata->temporal_idx = data.temporal_idx();
  out_metadata->layer_sync = data.layer_sync();
  return true;
}

// static
bool StructTraits<media::mojom::H265MetadataDataView, media::H265Metadata>::
    Read(media::mojom::H265MetadataDataView data,
         media::H265Metadata* out_metadata) {
  out_metadata->temporal_idx = data.temporal_idx();
  return true;
}

// static
bool StructTraits<media::mojom::Vp8MetadataDataView, media::Vp8Metadata>::Read(
    media::mojom::Vp8MetadataDataView data,
    media::Vp8Metadata* out_metadata) {
  out_metadata->non_reference = data.non_reference();
  out_metadata->temporal_idx = data.temporal_idx();
  out_metadata->layer_sync = data.layer_sync();
  return true;
}

// static
bool StructTraits<media::mojom::Vp9MetadataDataView, media::Vp9Metadata>::Read(
    media::mojom::Vp9MetadataDataView data,
    media::Vp9Metadata* out_metadata) {
  out_metadata->inter_pic_predicted = data.inter_pic_predicted();
  out_metadata->temporal_up_switch = data.temporal_up_switch();
  out_metadata->referenced_by_upper_spatial_layers =
      data.referenced_by_upper_spatial_layers();
  out_metadata->reference_lower_spatial_layers =
      data.reference_lower_spatial_layers();
  out_metadata->temporal_idx = data.temporal_idx();
  out_metadata->spatial_idx = data.spatial_idx();
  out_metadata->begin_active_spatial_layer_index =
      data.begin_active_spatial_layer_index();
  out_metadata->end_active_spatial_layer_index =
      data.end_active_spatial_layer_index();
  return data.ReadSpatialLayerResolutions(
             &out_metadata->spatial_layer_resolutions) &&
         data.ReadPDiffs(&out_metadata->p_diffs);
}

// static
bool StructTraits<media::mojom::Av1MetadataDataView, media::Av1Metadata>::Read(
    media::mojom::Av1MetadataDataView data,
    media::Av1Metadata* out_metadata) {
  out_metadata->temporal_idx = data.temporal_idx();
  return true;
}

// static
media::mojom::VideoEncodeAcceleratorConfig_StorageType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_StorageType,
           media::VideoEncodeAccelerator::Config::StorageType>::
    ToMojom(media::VideoEncodeAccelerator::Config::StorageType input) {
  switch (input) {
    case media::VideoEncodeAccelerator::Config::StorageType::kGpuMemoryBuffer:
      return media::mojom::VideoEncodeAcceleratorConfig_StorageType::
          kGpuMemoryBuffer;
    case media::VideoEncodeAccelerator::Config::StorageType::kShmem:
      return media::mojom::VideoEncodeAcceleratorConfig_StorageType::kShmem;
  }
  NOTREACHED_NORETURN();
}

// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_StorageType,
                media::VideoEncodeAccelerator::Config::StorageType>::
    FromMojom(media::mojom::VideoEncodeAcceleratorConfig_StorageType input,
              media::VideoEncodeAccelerator::Config::StorageType* output) {
  switch (input) {
    case media::mojom::VideoEncodeAcceleratorConfig_StorageType::kShmem:
      *output = media::VideoEncodeAccelerator::Config::StorageType::kShmem;
      return true;
    case media::mojom::VideoEncodeAcceleratorConfig_StorageType::
        kGpuMemoryBuffer:
      *output =
          media::VideoEncodeAccelerator::Config::StorageType::kGpuMemoryBuffer;
      return true;
  }
  NOTREACHED_NORETURN();
}

// static
media::mojom::VideoEncodeAcceleratorConfig_EncoderType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_EncoderType,
           media::VideoEncodeAccelerator::Config::EncoderType>::
    ToMojom(media::VideoEncodeAccelerator::Config::EncoderType input) {
  switch (input) {
    case media::VideoEncodeAccelerator::Config::EncoderType::kHardware:
      return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kHardware;
    case media::VideoEncodeAccelerator::Config::EncoderType::kSoftware:
      return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kSoftware;
    case media::VideoEncodeAccelerator::Config::EncoderType::kNoPreference:
      return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::
          kNoPreference;
  }
  NOTREACHED_NORETURN();
}

// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_EncoderType,
                media::VideoEncodeAccelerator::Config::EncoderType>::
    FromMojom(media::mojom::VideoEncodeAcceleratorConfig_EncoderType input,
              media::VideoEncodeAccelerator::Config::EncoderType* output) {
  switch (input) {
    case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kHardware:
      *output = media::VideoEncodeAccelerator::Config::EncoderType::kHardware;
      return true;
    case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kSoftware:
      *output = media::VideoEncodeAccelerator::Config::EncoderType::kSoftware;
      return true;
    case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kNoPreference:
      *output =
          media::VideoEncodeAccelerator::Config::EncoderType::kNoPreference;
      return true;
  }
  NOTREACHED_NORETURN();
}

// static
media::mojom::VideoEncodeAcceleratorConfig_ContentType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_ContentType,
           media::VideoEncodeAccelerator::Config::ContentType>::
    ToMojom(media::VideoEncodeAccelerator::Config::ContentType input) {
  switch (input) {
    case media::VideoEncodeAccelerator::Config::ContentType::kDisplay:
      return media::mojom::VideoEncodeAcceleratorConfig_ContentType::kDisplay;
    case media::VideoEncodeAccelerator::Config::ContentType::kCamera:
      return media::mojom::VideoEncodeAcceleratorConfig_ContentType::kCamera;
  }
  NOTREACHED_NORETURN();
}

// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_ContentType,
                media::VideoEncodeAccelerator::Config::ContentType>::
    FromMojom(media::mojom::VideoEncodeAcceleratorConfig_ContentType input,
              media::VideoEncodeAccelerator::Config::ContentType* output) {
  switch (input) {
    case media::mojom::VideoEncodeAcceleratorConfig_ContentType::kCamera:
      *output = media::VideoEncodeAccelerator::Config::ContentType::kCamera;
      return true;
    case media::mojom::VideoEncodeAcceleratorConfig_ContentType::kDisplay:
      *output = media::VideoEncodeAccelerator::Config::ContentType::kDisplay;
      return true;
  }
  NOTREACHED_NORETURN();
}

// static
bool StructTraits<media::mojom::SpatialLayerDataView,
                  media::VideoEncodeAccelerator::Config::SpatialLayer>::
    Read(media::mojom::SpatialLayerDataView input,
         media::VideoEncodeAccelerator::Config::SpatialLayer* output) {
  output->width = input.width();
  output->height = input.height();
  output->bitrate_bps = input.bitrate_bps();
  output->framerate = input.framerate();
  output->max_qp = input.max_qp();
  output->num_of_temporal_layers = input.num_of_temporal_layers();
  return true;
}

// static
bool StructTraits<media::mojom::ConstantBitrateDataView, media::Bitrate>::Read(
    media::mojom::ConstantBitrateDataView input,
    media::Bitrate* output) {
  *output = media::Bitrate::ConstantBitrate(input.target_bps());
  return true;
}

// static
bool StructTraits<media::mojom::VariableBitrateDataView, media::Bitrate>::Read(
    media::mojom::VariableBitrateDataView input,
    media::Bitrate* output) {
  if (input.target_bps() > input.peak_bps())
    return false;
  if (input.peak_bps() == 0u)
    return false;
  *output =
      media::Bitrate::VariableBitrate(input.target_bps(), input.peak_bps());
  return true;
}

// static
bool StructTraits<media::mojom::ExternalBitrateDataView, media::Bitrate>::Read(
    media::mojom::ExternalBitrateDataView input,
    media::Bitrate* output) {
  *output = media::Bitrate::ExternalRateControl();
  return true;
}

// static
media::mojom::BitrateDataView::Tag
UnionTraits<media::mojom::BitrateDataView, media::Bitrate>::GetTag(
    const media::Bitrate& input) {
  switch (input.mode()) {
    case media::Bitrate::Mode::kConstant:
      return media::mojom::BitrateDataView::Tag::kConstant;
    case media::Bitrate::Mode::kVariable:
      return media::mojom::BitrateDataView::Tag::kVariable;
    case media::Bitrate::Mode::kExternal:
      return media::mojom::BitrateDataView::Tag::kExternal;
  }
  NOTREACHED_NORETURN();
}

// static
bool UnionTraits<media::mojom::BitrateDataView, media::Bitrate>::Read(
    media::mojom::BitrateDataView input,
    media::Bitrate* output) {
  switch (input.tag()) {
    case media::mojom::BitrateDataView::Tag::kConstant:
      return input.ReadConstant(output);
    case media::mojom::BitrateDataView::Tag::kVariable:
      return input.ReadVariable(output);
    case media::mojom::BitrateDataView::Tag::kExternal:
      return input.ReadExternal(output);
  }

  NOTREACHED_NORETURN();
}

// static
bool StructTraits<media::mojom::VideoEncodeAcceleratorConfigDataView,
                  media::VideoEncodeAccelerator::Config>::
    Read(media::mojom::VideoEncodeAcceleratorConfigDataView input,
         media::VideoEncodeAccelerator::Config* output) {
  media::VideoPixelFormat input_format;
  if (!input.ReadInputFormat(&input_format))
    return false;

  gfx::Size input_visible_size;
  if (!input.ReadInputVisibleSize(&input_visible_size))
    return false;

  media::VideoCodecProfile output_profile;
  if (!input.ReadOutputProfile(&output_profile))
    return false;

  media::Bitrate bitrate;
  if (!input.ReadBitrate(&bitrate))
    return false;

  std::optional<uint32_t> initial_framerate;
  if (input.has_initial_framerate())
    initial_framerate = input.initial_framerate();

  std::optional<uint32_t> gop_length;
  if (input.has_gop_length())
    gop_length = input.gop_length();

  std::optional<uint8_t> h264_output_level;
  if (input.has_h264_output_level())
    h264_output_level = input.h264_output_level();

  bool is_constrained_h264 = input.is_constrained_h264();

  std::optional<media::VideoEncodeAccelerator::Config::StorageType>
      storage_type;
  if (input.has_storage_type()) {
    if (!input.ReadStorageType(&storage_type))
      return false;
  }

  media::VideoEncodeAccelerator::Config::ContentType content_type;
  if (!input.ReadContentType(&content_type))
    return false;

  uint8_t drop_frame_thresh_percentage = input.drop_frame_thresh_percentage();
  if (drop_frame_thresh_percentage > 100) {
    return false;
  }
  std::vector<media::VideoEncodeAccelerator::Config::SpatialLayer>
      spatial_layers;
  if (!input.ReadSpatialLayers(&spatial_layers))
    return false;

  media::SVCInterLayerPredMode inter_layer_pred;
  if (!input.ReadInterLayerPred(&inter_layer_pred))
    return false;

  media::VideoEncodeAccelerator::Config::EncoderType required_encoder_type;
  if (!input.ReadRequiredEncoderType(&required_encoder_type))
    return false;

  struct CheckVEAConfig {
    // The variable declaration order must be the same as
    // VideoEncodeAccelerator::Config.
    media::VideoPixelFormat input_format;
    gfx::Size input_visible_size;
    media::VideoCodecProfile output_profile;
    media::Bitrate bitrate;
    std::optional<uint32_t> initial_framerate;
    std::optional<uint32_t> gop_length;
    std::optional<uint8_t> h264_output_level;
    bool is_constrained_h264;
    std::optional<media::VideoEncodeAccelerator::Config::StorageType>
        storage_type;
    media::VideoEncodeAccelerator::Config::ContentType content_type;
    uint8_t drop_frame_thresh_percentage;
    std::vector<media::VideoEncodeAccelerator::Config::SpatialLayer>
        spatial_layers;
    media::SVCInterLayerPredMode inter_layer_pred;
    bool require_low_delay = true;
    media::VideoEncodeAccelerator::Config::EncoderType required_encoder_type;
  };
  static_assert(
      sizeof(CheckVEAConfig) == sizeof(media::VideoEncodeAccelerator::Config),
      "Please apply removed/added values in VideoEncodeAccelerator::Config "
      "to the following copy and then remove/add the values in CheckVEAConfig");

  *output = media::VideoEncodeAccelerator::Config(
      input_format, input_visible_size, output_profile, bitrate);
  output->initial_framerate = initial_framerate;
  output->gop_length = gop_length;
  output->h264_output_level = h264_output_level;
  output->is_constrained_h264 = is_constrained_h264;
  output->storage_type = storage_type;
  output->content_type = content_type;
  output->drop_frame_thresh_percentage = drop_frame_thresh_percentage;
  output->spatial_layers = spatial_layers;
  output->inter_layer_pred = inter_layer_pred;
  output->require_low_delay = input.require_low_delay();
  output->required_encoder_type = required_encoder_type;

  return true;
}

}  // namespace mojo
