// Copyright 2017 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/base/supported_types.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "media/base/media_client.h"
#include "media/base/media_switches.h"
#include "media/media_buildflags.h"
#include "ui/display/display_switches.h"

#if BUILDFLAG(ENABLE_LIBVPX)
#include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
#include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h"
#endif

namespace media {

bool IsSupportedAudioType(const AudioType& type) {
  MediaClient* media_client = GetMediaClient();
  if (media_client)
    return media_client->IsSupportedAudioType(type);

  return IsDefaultSupportedAudioType(type);
}

bool IsSupportedVideoType(const VideoType& type) {
  MediaClient* media_client = GetMediaClient();
  if (media_client)
    return media_client->IsSupportedVideoType(type);

  return IsDefaultSupportedVideoType(type);
}

bool IsColorSpaceSupported(const media::VideoColorSpace& color_space) {
  switch (color_space.primaries) {
    case media::VideoColorSpace::PrimaryID::EBU_3213_E:
    case media::VideoColorSpace::PrimaryID::INVALID:
      return false;

    // Transfers supported before color management.
    case media::VideoColorSpace::PrimaryID::BT709:
    case media::VideoColorSpace::PrimaryID::UNSPECIFIED:
    case media::VideoColorSpace::PrimaryID::BT470M:
    case media::VideoColorSpace::PrimaryID::BT470BG:
    case media::VideoColorSpace::PrimaryID::SMPTE170M:
      break;

    // Supported with color management.
    case media::VideoColorSpace::PrimaryID::SMPTE240M:
    case media::VideoColorSpace::PrimaryID::FILM:
    case media::VideoColorSpace::PrimaryID::BT2020:
    case media::VideoColorSpace::PrimaryID::SMPTEST428_1:
    case media::VideoColorSpace::PrimaryID::SMPTEST431_2:
    case media::VideoColorSpace::PrimaryID::SMPTEST432_1:
      break;
  }

  switch (color_space.transfer) {
    // Transfers supported before color management.
    case media::VideoColorSpace::TransferID::UNSPECIFIED:
    case media::VideoColorSpace::TransferID::GAMMA22:
    case media::VideoColorSpace::TransferID::BT709:
    case media::VideoColorSpace::TransferID::SMPTE170M:
    case media::VideoColorSpace::TransferID::BT2020_10:
    case media::VideoColorSpace::TransferID::BT2020_12:
    case media::VideoColorSpace::TransferID::IEC61966_2_1:
      break;

    // Supported with color management.
    case media::VideoColorSpace::TransferID::GAMMA28:
    case media::VideoColorSpace::TransferID::SMPTE240M:
    case media::VideoColorSpace::TransferID::LINEAR:
    case media::VideoColorSpace::TransferID::LOG:
    case media::VideoColorSpace::TransferID::LOG_SQRT:
    case media::VideoColorSpace::TransferID::BT1361_ECG:
    case media::VideoColorSpace::TransferID::SMPTEST2084:
    case media::VideoColorSpace::TransferID::IEC61966_2_4:
    case media::VideoColorSpace::TransferID::SMPTEST428_1:
    case media::VideoColorSpace::TransferID::ARIB_STD_B67:
      break;

    // Never supported.
    case media::VideoColorSpace::TransferID::INVALID:
      return false;
  }

  switch (color_space.matrix) {
    // Supported before color management.
    case media::VideoColorSpace::MatrixID::BT709:
    case media::VideoColorSpace::MatrixID::UNSPECIFIED:
    case media::VideoColorSpace::MatrixID::BT470BG:
    case media::VideoColorSpace::MatrixID::SMPTE170M:
    case media::VideoColorSpace::MatrixID::BT2020_NCL:
      break;

    // Supported with color management.
    case media::VideoColorSpace::MatrixID::RGB:
    case media::VideoColorSpace::MatrixID::FCC:
    case media::VideoColorSpace::MatrixID::SMPTE240M:
    case media::VideoColorSpace::MatrixID::YCOCG:
    case media::VideoColorSpace::MatrixID::YDZDX:
    case media::VideoColorSpace::MatrixID::BT2020_CL:
      break;

    // Never supported.
    case media::VideoColorSpace::MatrixID::INVALID:
      return false;
  }

  if (color_space.range == gfx::ColorSpace::RangeID::INVALID)
    return false;

  return true;
}

bool IsVp9ProfileSupported(VideoCodecProfile profile) {
#if BUILDFLAG(ENABLE_LIBVPX)
  // High bit depth capabilities may be toggled via LibVPX config flags.
  static bool vpx_supports_high_bit_depth =
      (vpx_codec_get_caps(vpx_codec_vp9_dx()) & VPX_CODEC_CAP_HIGHBITDEPTH) !=
      0;

  switch (profile) {
    // LibVPX always supports Profiles 0 and 1.
    case VP9PROFILE_PROFILE0:
    case VP9PROFILE_PROFILE1:
      return true;
    case VP9PROFILE_PROFILE2:
    case VP9PROFILE_PROFILE3:
      return vpx_supports_high_bit_depth;
    default:
      NOTREACHED();
  }
#endif
  return false;
}

bool IsAudioCodecProprietary(AudioCodec codec) {
  switch (codec) {
    case media::kCodecAAC:
    case media::kCodecAC3:
    case media::kCodecEAC3:
    case media::kCodecAMR_NB:
    case media::kCodecAMR_WB:
    case media::kCodecGSM_MS:
    case media::kCodecALAC:
    case media::kCodecMpegHAudio:
      return true;

    case media::kCodecFLAC:
    case media::kCodecMP3:
    case media::kCodecOpus:
    case media::kCodecVorbis:
    case media::kCodecPCM:
    case media::kCodecPCM_MULAW:
    case media::kCodecPCM_S16BE:
    case media::kCodecPCM_S24BE:
    case media::kCodecPCM_ALAW:
    case media::kUnknownAudioCodec:
      return false;
  }
}

bool IsDefaultSupportedAudioType(const AudioType& type) {
#if !BUILDFLAG(USE_PROPRIETARY_CODECS)
  if (IsAudioCodecProprietary(type.codec))
    return false;
#endif

  switch (type.codec) {
    case media::kCodecAAC:
    case media::kCodecFLAC:
    case media::kCodecMP3:
    case media::kCodecOpus:
    case media::kCodecPCM:
    case media::kCodecPCM_MULAW:
    case media::kCodecPCM_S16BE:
    case media::kCodecPCM_S24BE:
    case media::kCodecPCM_ALAW:
    case media::kCodecVorbis:
      return true;

    case media::kCodecAMR_NB:
    case media::kCodecAMR_WB:
    case media::kCodecGSM_MS:
#if defined(OS_CHROMEOS)
      return true;
#else
      return false;
#endif

    case media::kCodecEAC3:
    case media::kCodecALAC:
    case media::kCodecAC3:
    case media::kCodecMpegHAudio:
    case media::kUnknownAudioCodec:
      return false;
  }

  NOTREACHED();
  return false;
}

bool IsVideoCodecProprietary(VideoCodec codec) {
  switch (codec) {
    case kCodecVC1:
    case kCodecH264:
    case kCodecMPEG2:
    case kCodecMPEG4:
    case kCodecHEVC:
    case kCodecDolbyVision:
      return true;
    case kUnknownVideoCodec:
    case kCodecTheora:
    case kCodecVP8:
    case kCodecVP9:
    case kCodecAV1:
      return false;
  }
}

// TODO(chcunningham): Add platform specific logic for Android (move from
// MimeUtilIntenral).
bool IsDefaultSupportedVideoType(const VideoType& type) {
#if !BUILDFLAG(USE_PROPRIETARY_CODECS)
  if (IsVideoCodecProprietary(type.codec))
    return false;
#endif

  switch (type.codec) {
    case media::kCodecAV1:
#if BUILDFLAG(ENABLE_AV1_DECODER)
      return IsColorSpaceSupported(type.color_space);
#else
      return false;
#endif

    case media::kCodecVP9:
      // Color management required for HDR to not look terrible.
      return IsColorSpaceSupported(type.color_space) &&
             IsVp9ProfileSupported(type.profile);
    case media::kCodecH264:
    case media::kCodecVP8:
    case media::kCodecTheora:
      return true;

    case media::kUnknownVideoCodec:
    case media::kCodecVC1:
    case media::kCodecMPEG2:
    case media::kCodecHEVC:
    case media::kCodecDolbyVision:
      return false;

    case media::kCodecMPEG4:
#if defined(OS_CHROMEOS)
      return true;
#else
      return false;
#endif
  }

  NOTREACHED();
  return false;
}

}  // namespace media
