// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/media/base/starboard_utils.h"

#include <algorithm>

#include "base/logging.h"
#include "cobalt/media/base/decrypt_config.h"
#include "starboard/configuration.h"
#include "starboard/memory.h"

using base::Time;
using base::TimeDelta;

namespace cobalt {
namespace media {

SbMediaAudioCodec MediaAudioCodecToSbMediaAudioCodec(AudioCodec codec) {
  switch (codec) {
    case kCodecAAC:
      return kSbMediaAudioCodecAac;
#if SB_API_VERSION >= 12 || SB_HAS(AC3_AUDIO)
    case kCodecAC3:
      if (!kSbHasAc3Audio) {
        DLOG(ERROR) << "Audio codec AC3 not enabled on this platform. To "
                    << "enable it, set kSbHasAc3Audio to |true|.";
        return kSbMediaAudioCodecNone;
      }
      return kSbMediaAudioCodecAc3;
    case kCodecEAC3:
      if (!kSbHasAc3Audio) {
        DLOG(ERROR) << "Audio codec AC3 not enabled on this platform. To "
                    << "enable it, set kSbHasAc3Audio to |true|.";
        return kSbMediaAudioCodecNone;
      }
      return kSbMediaAudioCodecEac3;
#endif  // SB_API_VERSION >= 12 ||
        // SB_HAS(AC3_AUDIO)
    case kCodecVorbis:
      return kSbMediaAudioCodecVorbis;
    case kCodecOpus:
      return kSbMediaAudioCodecOpus;
    default:
      // Cobalt only supports a subset of audio codecs defined by Chromium.
      DLOG(ERROR) << "Unsupported audio codec "
                  << cobalt::media::GetCodecName(codec);
      return kSbMediaAudioCodecNone;
  }
  NOTREACHED();
  return kSbMediaAudioCodecNone;
}

SbMediaVideoCodec MediaVideoCodecToSbMediaVideoCodec(VideoCodec codec) {
  switch (codec) {
    case kCodecH264:
      return kSbMediaVideoCodecH264;
    case kCodecVC1:
      return kSbMediaVideoCodecVc1;
    case kCodecMPEG2:
      return kSbMediaVideoCodecMpeg2;
    case kCodecTheora:
      return kSbMediaVideoCodecTheora;
    case kCodecVP8:
      return kSbMediaVideoCodecVp8;
    case kCodecVP9:
      return kSbMediaVideoCodecVp9;
    case kCodecHEVC:
      return kSbMediaVideoCodecH265;
    case kCodecAV1:
      return kSbMediaVideoCodecAv1;
    default:
      // Cobalt only supports a subset of video codecs defined by Chromium.
      DLOG(ERROR) << "Unsupported video codec "
                  << cobalt::media::GetCodecName(codec);
      return kSbMediaVideoCodecNone;
  }
  NOTREACHED();
  return kSbMediaVideoCodecNone;
}

SbMediaAudioSampleInfo MediaAudioConfigToSbMediaAudioSampleInfo(
    const AudioDecoderConfig& audio_decoder_config) {
  DCHECK(audio_decoder_config.IsValidConfig());

  SbMediaAudioSampleInfo audio_sample_info;

  audio_sample_info.codec =
      MediaAudioCodecToSbMediaAudioCodec(audio_decoder_config.codec());

#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
  audio_sample_info.mime = audio_decoder_config.mime().c_str();
#endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)

  // TODO: Make this work with non AAC audio.
  audio_sample_info.format_tag = 0x00ff;
  audio_sample_info.number_of_channels =
      ChannelLayoutToChannelCount(audio_decoder_config.channel_layout());
  audio_sample_info.samples_per_second =
      audio_decoder_config.samples_per_second();
  audio_sample_info.average_bytes_per_second = 1;
  audio_sample_info.block_alignment = 4;
  audio_sample_info.bits_per_sample = audio_decoder_config.bits_per_channel();

  audio_sample_info.audio_specific_config_size =
      static_cast<uint16_t>(audio_decoder_config.extra_data().size());
  if (audio_sample_info.audio_specific_config_size == 0) {
    audio_sample_info.audio_specific_config = NULL;
  } else {
    audio_sample_info.audio_specific_config =
        &audio_decoder_config.extra_data()[0];
  }

  return audio_sample_info;
}

DemuxerStream::Type SbMediaTypeToDemuxerStreamType(SbMediaType type) {
  if (type == kSbMediaTypeAudio) {
    return DemuxerStream::AUDIO;
  }
  DCHECK_EQ(type, kSbMediaTypeVideo);
  return DemuxerStream::VIDEO;
}

SbMediaType DemuxerStreamTypeToSbMediaType(DemuxerStream::Type type) {
  if (type == DemuxerStream::AUDIO) {
    return kSbMediaTypeAudio;
  }
  DCHECK_EQ(type, DemuxerStream::VIDEO);
  return kSbMediaTypeVideo;
}

void FillDrmSampleInfo(const scoped_refptr<DecoderBuffer>& buffer,
                       SbDrmSampleInfo* drm_info,
                       SbDrmSubSampleMapping* subsample_mapping) {
  DCHECK(drm_info);
  DCHECK(subsample_mapping);

  const DecryptConfig* config = buffer->decrypt_config();

#if SB_API_VERSION >= 12
  if (config->encryption_mode() == EncryptionMode::kCenc) {
    drm_info->encryption_scheme = kSbDrmEncryptionSchemeAesCtr;
  } else {
    DCHECK_EQ(config->encryption_mode(), EncryptionMode::kCbcs);
    drm_info->encryption_scheme = kSbDrmEncryptionSchemeAesCbc;
  }
#else   // SB_API_VERSION >= 12
  DCHECK_EQ(config->encryption_mode(), EncryptionMode::kCenc);
#endif  // SB_API_VERSION >= 12

// Set content of |drm_info| to default or invalid values.
#if SB_API_VERSION >= 12
  drm_info->encryption_pattern.crypt_byte_block = 0;
  drm_info->encryption_pattern.skip_byte_block = 0;
#endif  // SB_API_VERSION >= 12
  drm_info->initialization_vector_size = 0;
  drm_info->identifier_size = 0;
  drm_info->subsample_count = 0;
  drm_info->subsample_mapping = NULL;

  if (!config || config->iv().empty() || config->key_id().empty()) {
    return;
  }

  DCHECK_LE(config->iv().size(), sizeof(drm_info->initialization_vector));
  DCHECK_LE(config->key_id().size(), sizeof(drm_info->identifier));

  if (config->iv().size() > sizeof(drm_info->initialization_vector) ||
      config->key_id().size() > sizeof(drm_info->identifier)) {
    return;
  }

  memcpy(drm_info->initialization_vector, &config->iv()[0],
               config->iv().size());
  drm_info->initialization_vector_size = config->iv().size();
  memcpy(drm_info->identifier, &config->key_id()[0],
               config->key_id().size());
  drm_info->identifier_size = config->key_id().size();
  drm_info->subsample_count = config->subsamples().size();

  if (drm_info->subsample_count > 0) {
    COMPILE_ASSERT(sizeof(SbDrmSubSampleMapping) == sizeof(SubsampleEntry),
                   SubSampleEntrySizesMatch);
    drm_info->subsample_mapping =
        reinterpret_cast<const SbDrmSubSampleMapping*>(
            &config->subsamples()[0]);
  } else {
    drm_info->subsample_count = 1;
    drm_info->subsample_mapping = subsample_mapping;
    subsample_mapping->clear_byte_count = 0;
    subsample_mapping->encrypted_byte_count = buffer->data_size();
  }

#if SB_API_VERSION >= 12
  if (buffer->decrypt_config()->HasPattern()) {
    drm_info->encryption_pattern.crypt_byte_block =
        config->encryption_pattern()->crypt_byte_block();
    drm_info->encryption_pattern.skip_byte_block =
        config->encryption_pattern()->skip_byte_block();
  }
#else   // SB_API_VERSION >= 12
  if (buffer->decrypt_config()->HasPattern()) {
    DCHECK_EQ(config->encryption_pattern()->crypt_byte_block(), 0);
    DCHECK_EQ(config->encryption_pattern()->skip_byte_block(), 0);
  }
#endif  // SB_API_VERSION >= 12
}

// Ensure that the enums in starboard/media.h match enums in gfx::ColorSpace.
#define ENUM_EQ(a, b) \
  COMPILE_ASSERT(static_cast<int>(a) == static_cast<int>(b), mismatching_enums)

// Ensure PrimaryId enums convert correctly.
ENUM_EQ(kSbMediaPrimaryIdReserved0, gfx::ColorSpace::kPrimaryIdReserved0);
ENUM_EQ(kSbMediaPrimaryIdBt709, gfx::ColorSpace::kPrimaryIdBt709);
ENUM_EQ(kSbMediaPrimaryIdUnspecified, gfx::ColorSpace::kPrimaryIdUnspecified);
ENUM_EQ(kSbMediaPrimaryIdReserved, gfx::ColorSpace::kPrimaryIdReserved);
ENUM_EQ(kSbMediaPrimaryIdBt470M, gfx::ColorSpace::kPrimaryIdBt470M);
ENUM_EQ(kSbMediaPrimaryIdBt470Bg, gfx::ColorSpace::kPrimaryIdBt470Bg);
ENUM_EQ(kSbMediaPrimaryIdSmpte170M, gfx::ColorSpace::kPrimaryIdSmpte170M);
ENUM_EQ(kSbMediaPrimaryIdSmpte240M, gfx::ColorSpace::kPrimaryIdSmpte240M);
ENUM_EQ(kSbMediaPrimaryIdFilm, gfx::ColorSpace::kPrimaryIdFilm);
ENUM_EQ(kSbMediaPrimaryIdBt2020, gfx::ColorSpace::kPrimaryIdBt2020);
ENUM_EQ(kSbMediaPrimaryIdSmpteSt4281, gfx::ColorSpace::kPrimaryIdSmpteSt4281);
ENUM_EQ(kSbMediaPrimaryIdSmpteSt4312, gfx::ColorSpace::kPrimaryIdSmpteSt4312);
ENUM_EQ(kSbMediaPrimaryIdSmpteSt4321, gfx::ColorSpace::kPrimaryIdSmpteSt4321);
ENUM_EQ(kSbMediaPrimaryIdLastStandardValue,
        gfx::ColorSpace::kPrimaryIdLastStandardValue);
ENUM_EQ(kSbMediaPrimaryIdUnknown, gfx::ColorSpace::kPrimaryIdUnknown);
ENUM_EQ(kSbMediaPrimaryIdXyzD50, gfx::ColorSpace::kPrimaryIdXyzD50);
ENUM_EQ(kSbMediaPrimaryIdCustom, gfx::ColorSpace::kPrimaryIdCustom);
ENUM_EQ(kSbMediaPrimaryIdLast, gfx::ColorSpace::kPrimaryIdLast);

// Ensure TransferId enums convert correctly.
ENUM_EQ(kSbMediaTransferIdReserved0, gfx::ColorSpace::kTransferIdReserved0);
ENUM_EQ(kSbMediaTransferIdBt709, gfx::ColorSpace::kTransferIdBt709);
ENUM_EQ(kSbMediaTransferIdUnspecified, gfx::ColorSpace::kTransferIdUnspecified);
ENUM_EQ(kSbMediaTransferIdReserved, gfx::ColorSpace::kTransferIdReserved);
ENUM_EQ(kSbMediaTransferIdGamma22, gfx::ColorSpace::kTransferIdGamma22);
ENUM_EQ(kSbMediaTransferIdGamma28, gfx::ColorSpace::kTransferIdGamma28);
ENUM_EQ(kSbMediaTransferIdSmpte170M, gfx::ColorSpace::kTransferIdSmpte170M);
ENUM_EQ(kSbMediaTransferIdSmpte240M, gfx::ColorSpace::kTransferIdSmpte240M);
ENUM_EQ(kSbMediaTransferIdLinear, gfx::ColorSpace::kTransferIdLinear);
ENUM_EQ(kSbMediaTransferIdLog, gfx::ColorSpace::kTransferIdLog);
ENUM_EQ(kSbMediaTransferIdLogSqrt, gfx::ColorSpace::kTransferIdLogSqrt);
ENUM_EQ(kSbMediaTransferIdIec6196624, gfx::ColorSpace::kTransferIdIec6196624);
ENUM_EQ(kSbMediaTransferIdBt1361Ecg, gfx::ColorSpace::kTransferIdBt1361Ecg);
ENUM_EQ(kSbMediaTransferIdIec6196621, gfx::ColorSpace::kTransferIdIec6196621);
ENUM_EQ(kSbMediaTransferId10BitBt2020, gfx::ColorSpace::kTransferId10BitBt2020);
ENUM_EQ(kSbMediaTransferId12BitBt2020, gfx::ColorSpace::kTransferId12BitBt2020);
ENUM_EQ(kSbMediaTransferIdSmpteSt2084, gfx::ColorSpace::kTransferIdSmpteSt2084);
ENUM_EQ(kSbMediaTransferIdSmpteSt4281, gfx::ColorSpace::kTransferIdSmpteSt4281);
ENUM_EQ(kSbMediaTransferIdAribStdB67, gfx::ColorSpace::kTransferIdAribStdB67);
ENUM_EQ(kSbMediaTransferIdLastStandardValue,
        gfx::ColorSpace::kTransferIdLastStandardValue);
ENUM_EQ(kSbMediaTransferIdUnknown, gfx::ColorSpace::kTransferIdUnknown);
ENUM_EQ(kSbMediaTransferIdGamma24, gfx::ColorSpace::kTransferIdGamma24);
ENUM_EQ(kSbMediaTransferIdSmpteSt2084NonHdr,
        gfx::ColorSpace::kTransferIdSmpteSt2084NonHdr);
ENUM_EQ(kSbMediaTransferIdCustom, gfx::ColorSpace::kTransferIdCustom);
ENUM_EQ(kSbMediaTransferIdLast, gfx::ColorSpace::kTransferIdLast);

// Ensure MatrixId enums convert correctly.
ENUM_EQ(kSbMediaMatrixIdRgb, gfx::ColorSpace::kMatrixIdRgb);
ENUM_EQ(kSbMediaMatrixIdBt709, gfx::ColorSpace::kMatrixIdBt709);
ENUM_EQ(kSbMediaMatrixIdUnspecified, gfx::ColorSpace::kMatrixIdUnspecified);
ENUM_EQ(kSbMediaMatrixIdReserved, gfx::ColorSpace::kMatrixIdReserved);
ENUM_EQ(kSbMediaMatrixIdFcc, gfx::ColorSpace::kMatrixIdFcc);
ENUM_EQ(kSbMediaMatrixIdBt470Bg, gfx::ColorSpace::kMatrixIdBt470Bg);
ENUM_EQ(kSbMediaMatrixIdSmpte170M, gfx::ColorSpace::kMatrixIdSmpte170M);
ENUM_EQ(kSbMediaMatrixIdSmpte240M, gfx::ColorSpace::kMatrixIdSmpte240M);
ENUM_EQ(kSbMediaMatrixIdYCgCo, gfx::ColorSpace::kMatrixIdYCgCo);
ENUM_EQ(kSbMediaMatrixIdBt2020NonconstantLuminance,
        gfx::ColorSpace::kMatrixIdBt2020NonconstantLuminance);
ENUM_EQ(kSbMediaMatrixIdBt2020ConstantLuminance,
        gfx::ColorSpace::kMatrixIdBt2020ConstantLuminance);
ENUM_EQ(kSbMediaMatrixIdYDzDx, gfx::ColorSpace::kMatrixIdYDzDx);
ENUM_EQ(kSbMediaMatrixIdLastStandardValue,
        gfx::ColorSpace::kMatrixIdLastStandardValue);
ENUM_EQ(kSbMediaMatrixIdUnknown, gfx::ColorSpace::kMatrixIdUnknown);
ENUM_EQ(kSbMediaMatrixIdLast, gfx::ColorSpace::kMatrixIdLast);

// Ensure RangeId enums convert correctly.
ENUM_EQ(kSbMediaRangeIdUnspecified, gfx::ColorSpace::kRangeIdUnspecified);
ENUM_EQ(kSbMediaRangeIdLimited, gfx::ColorSpace::kRangeIdLimited);
ENUM_EQ(kSbMediaRangeIdFull, gfx::ColorSpace::kRangeIdFull);
ENUM_EQ(kSbMediaRangeIdDerived, gfx::ColorSpace::kRangeIdDerived);
ENUM_EQ(kSbMediaRangeIdLast, gfx::ColorSpace::kRangeIdLast);

SbMediaColorMetadata MediaToSbMediaColorMetadata(
    const WebMColorMetadata& webm_color_metadata) {
  SbMediaColorMetadata sb_media_color_metadata;

  // Copy the other color metadata below.
  sb_media_color_metadata.bits_per_channel = webm_color_metadata.BitsPerChannel;
  sb_media_color_metadata.chroma_subsampling_horizontal =
      webm_color_metadata.ChromaSubsamplingHorz;
  sb_media_color_metadata.chroma_subsampling_vertical =
      webm_color_metadata.ChromaSubsamplingVert;
  sb_media_color_metadata.cb_subsampling_horizontal =
      webm_color_metadata.CbSubsamplingHorz;
  sb_media_color_metadata.cb_subsampling_vertical =
      webm_color_metadata.CbSubsamplingVert;
  sb_media_color_metadata.chroma_siting_horizontal =
      webm_color_metadata.ChromaSitingHorz;
  sb_media_color_metadata.chroma_siting_vertical =
      webm_color_metadata.ChromaSitingVert;

  // Copy the HDR Metadata below.
  SbMediaMasteringMetadata sb_media_mastering_metadata;
  HDRMetadata hdr_metadata = webm_color_metadata.hdr_metadata;
  MasteringMetadata mastering_metadata = hdr_metadata.mastering_metadata;

  sb_media_mastering_metadata.primary_r_chromaticity_x =
      mastering_metadata.primary_r_chromaticity_x;
  sb_media_mastering_metadata.primary_r_chromaticity_y =
      mastering_metadata.primary_r_chromaticity_y;

  sb_media_mastering_metadata.primary_g_chromaticity_x =
      mastering_metadata.primary_g_chromaticity_x;
  sb_media_mastering_metadata.primary_g_chromaticity_y =
      mastering_metadata.primary_g_chromaticity_y;

  sb_media_mastering_metadata.primary_b_chromaticity_x =
      mastering_metadata.primary_b_chromaticity_x;
  sb_media_mastering_metadata.primary_b_chromaticity_y =
      mastering_metadata.primary_b_chromaticity_y;

  sb_media_mastering_metadata.white_point_chromaticity_x =
      mastering_metadata.white_point_chromaticity_x;
  sb_media_mastering_metadata.white_point_chromaticity_y =
      mastering_metadata.white_point_chromaticity_y;

  sb_media_mastering_metadata.luminance_max = mastering_metadata.luminance_max;
  sb_media_mastering_metadata.luminance_min = mastering_metadata.luminance_min;

  sb_media_color_metadata.mastering_metadata = sb_media_mastering_metadata;
  sb_media_color_metadata.max_cll = hdr_metadata.max_cll;
  sb_media_color_metadata.max_fall = hdr_metadata.max_fall;

  // Copy the color space below.
  gfx::ColorSpace color_space = webm_color_metadata.color_space;
  sb_media_color_metadata.primaries =
      static_cast<SbMediaPrimaryId>(color_space.primaries());
  sb_media_color_metadata.transfer =
      static_cast<SbMediaTransferId>(color_space.transfer());
  sb_media_color_metadata.matrix =
      static_cast<SbMediaMatrixId>(color_space.matrix());
  sb_media_color_metadata.range =
      static_cast<SbMediaRangeId>(color_space.range());
  if (sb_media_color_metadata.primaries == kSbMediaPrimaryIdCustom) {
    const float* custom_primary_matrix = color_space.custom_primary_matrix();
    memcpy(sb_media_color_metadata.custom_primary_matrix,
           custom_primary_matrix,
           sizeof(sb_media_color_metadata.custom_primary_matrix));
  }

  return sb_media_color_metadata;
}

}  // namespace media
}  // namespace cobalt
