// Copyright 2012 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/mime_util_internal.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "media/base/media.h"
#include "media/base/media_client.h"
#include "media/base/media_switches.h"
#include "media/base/supported_types.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/media_buildflags.h"

#if defined(OS_ANDROID)
#include "base/android/build_info.h"

// TODO(dalecurtis): This include is not allowed by media/base since
// media/base/android is technically a different component. We should move
// mime_util*.{cc,h} out of media/base to fix this.
#include "media/base/android/media_codec_util.h"  // nogncheck
#endif

namespace media {
namespace internal {

// A map from codec string to MimeUtil::Codec.
using StringToCodecMap = base::flat_map<std::string, MimeUtil::Codec>;

// Wrapped to avoid static initializer startup cost.
const StringToCodecMap& GetStringToCodecMap() {
  static const base::NoDestructor<StringToCodecMap> kStringToCodecMap({
      // We only allow this for WAV so it isn't ambiguous.
      {"1", MimeUtil::PCM},
      // avc1/avc3.XXXXXX may be unambiguous; handled by
      // ParseAVCCodecId(). hev1/hvc1.XXXXXX may be unambiguous;
      // handled by ParseHEVCCodecID(). vp9, vp9.0,
      // vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by
      // ParseVp9CodecID().
      {"mp3", MimeUtil::MP3},
      // Following is the list of RFC 6381 compliant audio codec
      // strings:
      //   mp4a.66     - MPEG-2 AAC MAIN
      //   mp4a.67     - MPEG-2 AAC LC
      //   mp4a.68     - MPEG-2 AAC SSR
      //   mp4a.69     - MPEG-2 extension to MPEG-1 (MP3)
      //   mp4a.6B     - MPEG-1 audio (MP3)
      //   mp4a.40.2   - MPEG-4 AAC LC
      //   mp4a.40.02  - MPEG-4 AAC LC (leading 0 in aud-oti for
      //                 compatibility)
      //   mp4a.40.5   - MPEG-4 HE-AAC v1 (AAC LC + SBR)
      //   mp4a.40.05  - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0
      //                 in aud-oti for compatibility)
      //   mp4a.40.29  - MPEG-4 HE-AAC v2 (AAC LC + SBR + PS)
      {"mp4a.66", MimeUtil::MPEG2_AAC},
      {"mp4a.67", MimeUtil::MPEG2_AAC},
      {"mp4a.68", MimeUtil::MPEG2_AAC},
      {"mp4a.69", MimeUtil::MP3},
      {"mp4a.6B", MimeUtil::MP3},
      {"mp4a.40.2", MimeUtil::MPEG4_AAC},
      {"mp4a.40.02", MimeUtil::MPEG4_AAC},
      {"mp4a.40.5", MimeUtil::MPEG4_AAC},
      {"mp4a.40.05", MimeUtil::MPEG4_AAC},
      {"mp4a.40.29", MimeUtil::MPEG4_AAC},
      {"mp4a.40.42", MimeUtil::MPEG4_XHE_AAC},
      // TODO(servolk): Strictly speaking only mp4a.A5 and mp4a.A6
      // codec ids are valid according to RFC 6381 section 3.3, 3.4.
      // Lower-case oti (mp4a.a5 and mp4a.a6) should be rejected. But
      // we used to allow those in older versions of Chromecast
      // firmware and some apps (notably MPL) depend on those codec
      // types being supported, so they should be allowed for now
      // (crbug.com/564960).
      {"ac-3", MimeUtil::AC3},
      {"mp4a.a5", MimeUtil::AC3},
      {"mp4a.A5", MimeUtil::AC3},
      {"ec-3", MimeUtil::EAC3},
      {"mp4a.a6", MimeUtil::EAC3},
      {"mp4a.A6", MimeUtil::EAC3},
      {"vorbis", MimeUtil::VORBIS},
      {"opus", MimeUtil::OPUS},
      {"flac", MimeUtil::FLAC},
      {"vp8", MimeUtil::VP8},
      {"vp8.0", MimeUtil::VP8},
      {"theora", MimeUtil::THEORA},
  });

  return *kStringToCodecMap;
}

static bool ParseVp9CodecID(const std::string& mime_type_lower_case,
                            const std::string& codec_id,
                            VideoCodecProfile* out_profile,
                            uint8_t* out_level,
                            VideoColorSpace* out_color_space) {
  if (ParseNewStyleVp9CodecID(codec_id, out_profile, out_level,
                              out_color_space)) {
    // New style (e.g. vp09.00.10.08) is accepted with any mime type (including
    // empty mime type).
    return true;
  }

  // Legacy style (e.g. "vp9") is ambiguous about codec profile, and is only
  // valid with video/webm for legacy reasons.
  if (mime_type_lower_case == "video/webm")
    return ParseLegacyVp9CodecID(codec_id, out_profile, out_level);

  return false;
}

static bool IsValidH264Level(uint8_t level_idc) {
  // Valid levels taken from Table A-1 in ISO/IEC 14496-10.
  // Level_idc represents the standard level represented as decimal number
  // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2
  return ((level_idc >= 10 && level_idc <= 13) ||
          (level_idc >= 20 && level_idc <= 22) ||
          (level_idc >= 30 && level_idc <= 32) ||
          (level_idc >= 40 && level_idc <= 42) ||
          (level_idc >= 50 && level_idc <= 52));
}

// Make a default ParsedCodecResult. Values should indicate "unspecified"
// where possible. Color space is an exception where we choose a default value
// because most codec strings will not describe a color space.
static MimeUtil::ParsedCodecResult MakeDefaultParsedCodecResult() {
  return {
      MimeUtil::INVALID_CODEC, false, VIDEO_CODEC_PROFILE_UNKNOWN, 0,
      // We choose 709 as default color space elsewhere, so defaulting to 709
      // here as well. See here for context: https://crrev.com/1221903003/
      VideoColorSpace::REC709()};
}

MimeUtil::MimeUtil() {
#if defined(OS_ANDROID)
  // When the unified media pipeline is enabled, we need support for both GPU
  // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport().
  // When the Android pipeline is used, we only need access to MediaCodec.
  platform_info_.has_platform_decoders = HasPlatformDecoderSupport();
#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
  platform_info_.has_platform_dv_decoder =
      MediaCodecUtil::IsDolbyVisionDecoderAvailable();
#endif
  platform_info_.has_platform_vp8_decoder =
      MediaCodecUtil::IsVp8DecoderAvailable();
  platform_info_.has_platform_vp9_decoder =
      MediaCodecUtil::IsVp9DecoderAvailable();
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  platform_info_.has_platform_hevc_decoder =
      MediaCodecUtil::IsHEVCDecoderAvailable();
#endif
  platform_info_.has_platform_opus_decoder =
      MediaCodecUtil::IsOpusDecoderAvailable();
#endif

  InitializeMimeTypeMaps();
}

MimeUtil::~MimeUtil() = default;

AudioCodec MimeUtilToAudioCodec(MimeUtil::Codec codec) {
  switch (codec) {
    case MimeUtil::PCM:
      return AudioCodec::kPCM;
    case MimeUtil::MP3:
      return AudioCodec::kMP3;
    case MimeUtil::AC3:
      return AudioCodec::kAC3;
    case MimeUtil::EAC3:
      return AudioCodec::kEAC3;
    case MimeUtil::MPEG2_AAC:
    case MimeUtil::MPEG4_AAC:
    case MimeUtil::MPEG4_XHE_AAC:
      return AudioCodec::kAAC;
    case MimeUtil::MPEG_H_AUDIO:
      return AudioCodec::kMpegHAudio;
    case MimeUtil::VORBIS:
      return AudioCodec::kVorbis;
    case MimeUtil::OPUS:
      return AudioCodec::kOpus;
    case MimeUtil::FLAC:
      return AudioCodec::kFLAC;
    case MimeUtil::IAMF:
      return AudioCodec::kIAMF;
    default:
      break;
  }
  return AudioCodec::kUnknown;
}

VideoCodec MimeUtilToVideoCodec(MimeUtil::Codec codec) {
  switch (codec) {
    case MimeUtil::AV1:
      return VideoCodec::kAV1;
    case MimeUtil::H264:
      return VideoCodec::kH264;
    case MimeUtil::HEVC:
      return VideoCodec::kHEVC;
    case MimeUtil::VP8:
      return VideoCodec::kVP8;
    case MimeUtil::VP9:
      return VideoCodec::kVP9;
    case MimeUtil::THEORA:
      return VideoCodec::kTheora;
    case MimeUtil::DOLBY_VISION:
      return VideoCodec::kDolbyVision;
    default:
      break;
  }
  return VideoCodec::kUnknown;
}

SupportsType MimeUtil::AreSupportedCodecs(
    const std::vector<ParsedCodecResult>& parsed_codecs,
    const std::string& mime_type_lower_case,
    bool is_encrypted) const {
  DCHECK(!parsed_codecs.empty());
  DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);

  SupportsType combined_result = IsSupported;

  for (const auto& parsed_codec : parsed_codecs) {
    // Make conservative guesses to resolve ambiguity before checking platform
    // support. Historically we allowed some ambiguity in H264 and VP9 codec
    // strings, so we must continue to allow going forward. DO NOT ADD NEW
    // SUPPORT FOR MORE AMBIGUOUS STRINGS.
    VideoCodecProfile video_profile = parsed_codec.video_profile;
    uint8_t video_level = parsed_codec.video_level;
    if (parsed_codec.is_ambiguous) {
      switch (parsed_codec.codec) {
        case MimeUtil::H264:
          if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)
            video_profile = H264PROFILE_BASELINE;
          if (!IsValidH264Level(video_level))
            video_level = 10;
          break;
        case MimeUtil::VP9:
          if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)
            video_profile = VP9PROFILE_PROFILE0;
          if (video_level == 0)
            video_level = 10;
          break;
        case MimeUtil::MPEG4_AAC:
          // Nothing to do for AAC; no notion of profile / level to guess.
          break;
        default:
          NOTREACHED()
              << "Only VP9, H264, and AAC codec strings can be ambiguous.";
      }
    }

    // Check platform support.
    SupportsType result = IsCodecSupported(
        mime_type_lower_case, parsed_codec.codec, video_profile, video_level,
        parsed_codec.video_color_space, is_encrypted);
    if (result == IsNotSupported) {
      DVLOG(2) << __func__ << ": Codec " << parsed_codec.codec
               << " not supported by platform.";
      return IsNotSupported;
    }

    // If any codec is "MayBeSupported", return Maybe for the combined result.
    if (result == MayBeSupported ||
        // Downgrade to MayBeSupported if we had to guess the meaning of one of
        // the codec strings. Do not downgrade for VP9 because we historically
        // returned "Probably" for the old "vp9" string and cannot change to
        // returning "Maybe" as this will break sites.
        (result == IsSupported && parsed_codec.is_ambiguous &&
         parsed_codec.codec != MimeUtil::VP9)) {
      combined_result = MayBeSupported;
    }
  }

  return combined_result;
}

void MimeUtil::InitializeMimeTypeMaps() {
  AddSupportedMediaFormats();
}

// Each call to AddContainerWithCodecs() contains a media type
// (https://en.wikipedia.org/wiki/Media_type) and corresponding media codec(s)
// supported by these types/containers.
void MimeUtil::AddSupportedMediaFormats() {
  const CodecSet wav_codecs{PCM};
  const CodecSet ogg_audio_codecs{FLAC, OPUS, VORBIS};

  CodecSet ogg_video_codecs{VP8};
#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
  ogg_video_codecs.emplace(THEORA);
#endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)

  CodecSet ogg_codecs(ogg_audio_codecs);
  ogg_codecs.insert(ogg_video_codecs.begin(), ogg_video_codecs.end());

  const CodecSet webm_audio_codecs{OPUS, VORBIS};
  CodecSet webm_video_codecs{VP8, VP9};
#if BUILDFLAG(ENABLE_AV1_DECODER)
  webm_video_codecs.emplace(AV1);
#endif

  CodecSet webm_codecs(webm_audio_codecs);
  webm_codecs.insert(webm_video_codecs.begin(), webm_video_codecs.end());

  const CodecSet mp3_codecs{MP3};

  CodecSet mp4_audio_codecs{FLAC, MP3, OPUS};

  // Only VP9 with valid codec string vp09.xx.xx.xx.xx.xx.xx.xx is supported.
  // See ParseVp9CodecID for details.
  CodecSet mp4_video_codecs;
  mp4_video_codecs.emplace(VP9);

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
  const CodecSet aac{MPEG2_AAC, MPEG4_AAC, MPEG4_XHE_AAC};
  mp4_audio_codecs.insert(aac.begin(), aac.end());

  CodecSet avc_and_aac(aac);
  avc_and_aac.emplace(H264);

#if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
  mp4_audio_codecs.emplace(AC3);
  mp4_audio_codecs.emplace(EAC3);
#endif  // BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)

#if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
  mp4_audio_codecs.emplace(MPEG_H_AUDIO);
#endif  // BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)

  mp4_video_codecs.emplace(H264);
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  mp4_video_codecs.emplace(HEVC);
#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)

#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
  mp4_video_codecs.emplace(DOLBY_VISION);
#endif  // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(ENABLE_AV1_DECODER)
  mp4_video_codecs.emplace(AV1);
#endif

#if BUILDFLAG(ENABLE_PLATFORM_IAMF_AUDIO)
  mp4_audio_codecs.emplace(IAMF);
#endif  // BUILDFLAG(ENABLE_PLATFORM_IAMF_AUDIO)

  CodecSet mp4_codecs(mp4_audio_codecs);
  mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end());

  const CodecSet implicit_codec;
  AddContainerWithCodecs("audio/wav", wav_codecs);
  AddContainerWithCodecs("audio/x-wav", wav_codecs);
  AddContainerWithCodecs("audio/webm", webm_audio_codecs);
  DCHECK(!webm_video_codecs.empty());
  AddContainerWithCodecs("video/webm", webm_codecs);
  AddContainerWithCodecs("audio/ogg", ogg_audio_codecs);
  // video/ogg is only supported if an appropriate video codec is supported.
  // Note: This assumes such codecs cannot be later excluded.
  if (!ogg_video_codecs.empty())
    AddContainerWithCodecs("video/ogg", ogg_codecs);
  // TODO(ddorwin): Should the application type support Opus?
  AddContainerWithCodecs("application/ogg", ogg_codecs);
  AddContainerWithCodecs("audio/flac", implicit_codec);
  AddContainerWithCodecs("audio/mpeg", mp3_codecs);  // Allow "mp3".
  AddContainerWithCodecs("audio/mp3", implicit_codec);
  AddContainerWithCodecs("audio/x-mp3", implicit_codec);
  AddContainerWithCodecs("audio/mp4", mp4_audio_codecs);
  DCHECK(!mp4_video_codecs.empty());
  AddContainerWithCodecs("video/mp4", mp4_codecs);

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
  AddContainerWithCodecs("audio/aac", implicit_codec);  // AAC / ADTS.
  // These strings are supported for backwards compatibility only and thus only
  // support the codecs needed for compatibility.
  AddContainerWithCodecs("audio/x-m4a", aac);
  AddContainerWithCodecs("video/x-m4v", avc_and_aac);

  CodecSet video_3gpp_codecs(aac);
  video_3gpp_codecs.emplace(H264);
  AddContainerWithCodecs("video/3gpp", video_3gpp_codecs);

#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
  CodecSet mp2t_codecs{H264, MPEG2_AAC, MPEG4_AAC, MP3};
  AddContainerWithCodecs("video/mp2t", mp2t_codecs);
#endif  // BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
#if defined(OS_ANDROID)
  if (base::FeatureList::IsEnabled(kCanPlayHls)) {
    // HTTP Live Streaming (HLS).
    CodecSet hls_codecs{H264,
                        // TODO(ddorwin): Is any MP3 codec string variant
                        // included in real queries?
                        MP3,
                        // Android HLS only supports MPEG4_AAC (missing demuxer
                        // support for MPEG2_AAC)
                        MPEG4_AAC};
    AddContainerWithCodecs("application/x-mpegurl", hls_codecs);
    AddContainerWithCodecs("application/vnd.apple.mpegurl", hls_codecs);
    AddContainerWithCodecs("audio/mpegurl", hls_codecs);
    // Not documented by Apple, but unfortunately used extensively by Apple and
    // others for both audio-only and audio+video playlists. See
    // https://crbug.com/675552 for details and examples.
    AddContainerWithCodecs("audio/x-mpegurl", hls_codecs);
  }
#endif  // defined(OS_ANDROID)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
}

void MimeUtil::AddContainerWithCodecs(const std::string& mime_type,
                                      const CodecSet& codecs) {
  media_format_map_[mime_type] = codecs;
}

bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
  return media_format_map_.find(base::ToLowerASCII(mime_type)) !=
         media_format_map_.end();
}

void MimeUtil::SplitCodecs(const std::string& codecs,
                           std::vector<std::string>* codecs_out) const {
  *codecs_out =
      base::SplitString(base::TrimString(codecs, "\"", base::TRIM_ALL), ",",
                        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  // Convert empty or all-whitespace input to 0 results.
  if (codecs_out->size() == 1 && (*codecs_out)[0].empty())
    codecs_out->clear();
}

void MimeUtil::StripCodecs(std::vector<std::string>* codecs) const {
  // Strip everything past the first '.'
  for (auto it = codecs->begin(); it != codecs->end(); ++it) {
    size_t found = it->find_first_of('.');
    if (found != std::string::npos)
      it->resize(found);
  }
}

bool MimeUtil::ParseVideoCodecString(const std::string& mime_type,
                                     const std::string& codec_id,
                                     bool* out_is_ambiguous,
                                     VideoCodec* out_codec,
                                     VideoCodecProfile* out_profile,
                                     uint8_t* out_level,
                                     VideoColorSpace* out_color_space) const {
  DCHECK(out_is_ambiguous);
  DCHECK(out_codec);
  DCHECK(out_profile);
  DCHECK(out_level);
  DCHECK(out_color_space);

  // Internal parsing API expects a vector of codecs.
  std::vector<ParsedCodecResult> parsed_results;
  std::vector<std::string> codec_strings;
  if (!codec_id.empty())
    codec_strings.push_back(codec_id);

  if (!ParseCodecStrings(base::ToLowerASCII(mime_type), codec_strings,
                         &parsed_results)) {
    DVLOG(3) << __func__ << " Failed to parse mime/codec pair: "
             << (mime_type.empty() ? "<empty mime>" : mime_type) << "; "
             << codec_id;
    return false;
  }

  CHECK_EQ(1U, parsed_results.size());
  *out_is_ambiguous = parsed_results[0].is_ambiguous;
  *out_codec = MimeUtilToVideoCodec(parsed_results[0].codec);
  *out_profile = parsed_results[0].video_profile;
  *out_level = parsed_results[0].video_level;
  *out_color_space = parsed_results[0].video_color_space;

  if (*out_codec == VideoCodec::kUnknown) {
    DVLOG(3) << __func__ << " Codec string " << codec_id
             << " is not a VIDEO codec.";
    return false;
  }

  return true;
}

bool MimeUtil::ParseAudioCodecString(const std::string& mime_type,
                                     const std::string& codec_id,
                                     bool* out_is_ambiguous,
                                     AudioCodec* out_codec) const {
  DCHECK(out_is_ambiguous);
  DCHECK(out_codec);

  // Internal parsing API expects a vector of codecs.
  std::vector<ParsedCodecResult> parsed_results;
  std::vector<std::string> codec_strings;
  if (!codec_id.empty())
    codec_strings.push_back(codec_id);

  if (!ParseCodecStrings(base::ToLowerASCII(mime_type), codec_strings,
                         &parsed_results)) {
    DVLOG(3) << __func__ << " Failed to parse mime/codec pair:"
             << (mime_type.empty() ? "<empty mime>" : mime_type) << "; "
             << codec_id;
    return false;
  }

  CHECK_EQ(1U, parsed_results.size());
  *out_is_ambiguous = parsed_results[0].is_ambiguous;
  *out_codec = MimeUtilToAudioCodec(parsed_results[0].codec);

  if (*out_codec == AudioCodec::kUnknown) {
    DVLOG(3) << __func__ << " Codec string " << codec_id
             << " is not an AUDIO codec.";
    return false;
  }

  return true;
}

SupportsType MimeUtil::IsSupportedMediaFormat(
    const std::string& mime_type,
    const std::vector<std::string>& codecs,
    bool is_encrypted) const {
  const std::string mime_type_lower_case = base::ToLowerASCII(mime_type);
  std::vector<ParsedCodecResult> parsed_results;
  if (!ParseCodecStrings(mime_type_lower_case, codecs, &parsed_results)) {
    DVLOG(3) << __func__ << " Media format unsupported; codec parsing failed "
             << mime_type << " " << base::JoinString(codecs, ",");
    return IsNotSupported;
  }

  if (parsed_results.empty()) {
    NOTREACHED() << __func__ << " Successful parsing should output results.";
    return IsNotSupported;
  }

  // We get here if the mime type expects to get a codecs parameter
  // but none was provided and no default codec was implied. In this case
  // the best we can do is say "maybe" because we don't have enough
  // information.
  if (codecs.empty() && parsed_results.size() == 1 &&
      parsed_results[0].codec == INVALID_CODEC) {
    DCHECK(parsed_results[0].is_ambiguous);
    return MayBeSupported;
  }

  return AreSupportedCodecs(parsed_results, mime_type_lower_case, is_encrypted);
}

// static
bool MimeUtil::IsCodecSupportedOnAndroid(
    Codec codec,
    const std::string& mime_type_lower_case,
    bool is_encrypted,
    VideoCodecProfile video_profile,
    const PlatformInfo& platform_info) {
  DVLOG(3) << __func__;
  DCHECK_NE(mime_type_lower_case, "");

  // Encrypted block support is never available without platform decoders.
  if (is_encrypted && !platform_info.has_platform_decoders)
    return false;

  // NOTE: We do not account for Media Source Extensions (MSE) within these
  // checks since it has its own isTypeSupported() which will handle platform
  // specific codec rejections.  See http://crbug.com/587303.

  switch (codec) {
    // ----------------------------------------------------------------------
    // The following codecs are never supported.
    // ----------------------------------------------------------------------
    case INVALID_CODEC:
    case THEORA:
      return false;

    // ----------------------------------------------------------------------
    // The remaining codecs may be supported depending on platform abilities.
    // ----------------------------------------------------------------------
    case AV1:
      return BUILDFLAG(ENABLE_AV1_DECODER);

    case MPEG2_AAC:
      // MPEG2_AAC cannot be used in HLS (mpegurl suffix), but this is enforced
      // in the parsing step by excluding MPEG2_AAC from the list of
      // valid codecs to be used with HLS mime types.
      DCHECK(!base::EndsWith(mime_type_lower_case, "mpegurl",
                             base::CompareCase::SENSITIVE));
      FALLTHROUGH;
    case PCM:
    case MP3:
    case MPEG4_AAC:
    case FLAC:
    case VORBIS:
      // These codecs are always supported; via a platform decoder (when used
      // with MSE/EME), a software decoder (the unified pipeline), or with
      // MediaPlayer.
      DCHECK(!is_encrypted || platform_info.has_platform_decoders);
      return true;

    case MPEG4_XHE_AAC:
      // xHE-AAC is only supported via MediaCodec.
      return platform_info.has_platform_decoders;

    case MPEG_H_AUDIO:
      return false;

    case OPUS:
      // If clear, the unified pipeline can always decode Opus in software.
      if (!is_encrypted)
        return true;

      // Otherwise, platform support is required.
      if (!platform_info.has_platform_opus_decoder) {
        DVLOG(3) << "Platform does not support opus";
        return false;
      }

      DCHECK(!is_encrypted || platform_info.has_platform_decoders);
      return true;

    case H264:
      // When content is not encrypted we fall back to MediaPlayer, thus we
      // always support H264. For EME we need MediaCodec.
      return !is_encrypted || platform_info.has_platform_decoders;

    case HEVC:
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
      return platform_info.has_platform_decoders &&
             platform_info.has_platform_hevc_decoder;
#else
      return false;
#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)

    case VP8:
      // If clear, the unified pipeline can always decode VP8 in software.
      return is_encrypted ? platform_info.has_platform_vp8_decoder : true;

    case VP9: {
#if !defined(STARBOARD)
      // Cobalt doesn't support `kReportVp9AsAnUnsupportedMimeType` command line
      // switch.
      if (base::CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kReportVp9AsAnUnsupportedMimeType)) {
        return false;
      }
#endif  // !defined(STARBOARD)

      // If clear, the unified pipeline can always decode VP9.0,1 in software.
      // If we don't know the profile, then support is ambiguous, but default to
      // true for historical reasons.
      if (!is_encrypted && (video_profile == VP9PROFILE_PROFILE0 ||
                            video_profile == VP9PROFILE_PROFILE1 ||
                            video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)) {
        return true;
      }

      if (!platform_info.has_platform_vp9_decoder)
        return false;

      return true;
    }

    case DOLBY_VISION:
#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
      return platform_info.has_platform_dv_decoder;
#else
      return false;
#endif

    case AC3:
    case EAC3:
#if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
      return true;
#else
      return false;
#endif
    case IAMF:
      return false;
  }

  return false;
}

bool MimeUtil::ParseCodecStrings(
    const std::string& mime_type_lower_case,
    const std::vector<std::string>& codecs,
    std::vector<ParsedCodecResult>* out_results) const {
  DCHECK(out_results);

  // Nothing to parse.
  if (mime_type_lower_case.empty() && codecs.empty())
    return false;

  // When mime type is provided, it may imply a codec or only be valid with
  // certain codecs.
  const CodecSet* valid_codecs_for_mime;
  if (!mime_type_lower_case.empty()) {
    // Reject unrecognized mime types.
    auto it_media_format_map = media_format_map_.find(mime_type_lower_case);
    if (it_media_format_map == media_format_map_.end()) {
      DVLOG(3) << __func__
               << " Unrecognized mime type: " << mime_type_lower_case;
      return false;
    }

    valid_codecs_for_mime = &it_media_format_map->second;
    if (valid_codecs_for_mime->empty()) {
      // We get here if the mimetype does not expect a codecs parameter.
      if (!codecs.empty()) {
        DVLOG(3) << __func__
                 << " Codecs unexpected for mime type:" << mime_type_lower_case;
        return false;
      }

      // Determine implied codec for mime type.
      ParsedCodecResult implied_result = MakeDefaultParsedCodecResult();
      if (!GetDefaultCodec(mime_type_lower_case, &implied_result.codec)) {
        NOTREACHED() << " Mime types must offer a default codec if no explicit "
                        "codecs are expected";
        return false;
      }
      out_results->push_back(implied_result);
      return true;
    }

    if (codecs.empty()) {
      // We get here if the mimetype expects to get a codecs parameter,
      // but didn't get one. If |mime_type_lower_case| does not have a default
      // codec, the string is considered ambiguous.
      ParsedCodecResult implied_result = MakeDefaultParsedCodecResult();
      implied_result.is_ambiguous =
          !GetDefaultCodec(mime_type_lower_case, &implied_result.codec);
      out_results->push_back(implied_result);
      return true;
    }
  }

  // All empty cases handled above.
  DCHECK(!codecs.empty());

  for (std::string codec_string : codecs) {
    ParsedCodecResult result;

#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
    if (mime_type_lower_case == "video/mp2t")
      codec_string = TranslateLegacyAvc1CodecIds(codec_string);
#endif

    if (!ParseCodecHelper(mime_type_lower_case, codec_string, &result)) {
      DVLOG(3) << __func__ << " Failed to parse mime/codec pair: "
               << (mime_type_lower_case.empty() ? "<empty mime>"
                                                : mime_type_lower_case)
               << "; " << codec_string;
      return false;
    }
    DCHECK_NE(INVALID_CODEC, result.codec);

    // If mime type given, fail if mime + codec is not a valid combination.
    if (!mime_type_lower_case.empty() &&
        !valid_codecs_for_mime->contains(result.codec)) {
      DVLOG(3) << __func__
               << " Incompatible mime/codec pair: " << mime_type_lower_case
               << "; " << codec_string;
      return false;
    }

    out_results->push_back(result);
  }

  return true;
}

bool MimeUtil::ParseCodecHelper(const std::string& mime_type_lower_case,
                                const std::string& codec_id,
                                ParsedCodecResult* out_result) const {
  DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
  DCHECK(out_result);

  *out_result = MakeDefaultParsedCodecResult();

  // Simple codecs can be found in the codec map.
  auto itr = GetStringToCodecMap().find(codec_id);
  if (itr != GetStringToCodecMap().end()) {
    out_result->codec = itr->second;

    // Even "simple" video codecs should have an associated profile.
    if (MimeUtilToVideoCodec(out_result->codec) != VideoCodec::kUnknown) {
      switch (out_result->codec) {
        case Codec::VP8:
          out_result->video_profile = VP8PROFILE_ANY;
          break;
        case Codec::THEORA:
          out_result->video_profile = THEORAPROFILE_ANY;
          break;
        default:
          NOTREACHED();
      }
    }

    return true;
  }

  // Check codec string against short list of allowed ambiguous codecs.
  // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT
  // INCREASE PLACES WHERE |ambiguous_codec_string| = true.
  // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId().
  if (codec_id == "avc1" || codec_id == "avc3") {
    out_result->codec = MimeUtil::H264;
    out_result->is_ambiguous = true;
    return true;
  } else if (codec_id == "mp4a.40") {
    out_result->codec = MimeUtil::MPEG4_AAC;
    out_result->is_ambiguous = true;
    return true;
  }

  // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is
  // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the
  // only ones that are not added to the |kStringToCodecMap| and require
  // parsing.
  VideoCodecProfile* out_profile = &out_result->video_profile;
  uint8_t* out_level = &out_result->video_level;
  VideoColorSpace* out_color_space = &out_result->video_color_space;
  if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level,
                      out_color_space)) {
    out_result->codec = MimeUtil::VP9;
    // Original VP9 codec string did not describe the profile.
    if (out_result->video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) {
      // New VP9 string should never be ambiguous.
      DCHECK(!base::StartsWith(codec_id, "vp09", base::CompareCase::SENSITIVE));
      out_result->is_ambiguous = true;
    }
    return true;
  }

#if BUILDFLAG(ENABLE_AV1_DECODER)
  if (ParseAv1CodecId(codec_id, out_profile, out_level, out_color_space)) {
    out_result->codec = MimeUtil::AV1;
    return true;
  }
#endif

  if (ParseAVCCodecId(codec_id, out_profile, out_level)) {
    out_result->codec = MimeUtil::H264;
    // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY.
    out_result->is_ambiguous = !IsValidH264Level(*out_level);
    return true;
  }

#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  if (ParseHEVCCodecId(codec_id, out_profile, out_level)) {
    out_result->codec = MimeUtil::HEVC;
    return true;
  }
#endif

#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
  if (ParseDolbyVisionCodecId(codec_id, out_profile, out_level)) {
    out_result->codec = MimeUtil::DOLBY_VISION;
    return true;
  }
#endif

#if BUILDFLAG(ENABLE_PLATFORM_MPEG_H_AUDIO)
  if (base::StartsWith(codec_id, "mhm1.", base::CompareCase::SENSITIVE) ||
      base::StartsWith(codec_id, "mha1.", base::CompareCase::SENSITIVE)) {
    out_result->codec = MimeUtil::MPEG_H_AUDIO;
    return true;
  }
#endif

#if BUILDFLAG(ENABLE_PLATFORM_IAMF_AUDIO)
  if (ParseIamfCodecId(codec_id.data(), nullptr, nullptr)) {
    out_result->codec = MimeUtil::IAMF;
    return true;
  }
#endif

  DVLOG(2) << __func__ << ": Unrecognized codec id \"" << codec_id << "\"";
  return false;
}

SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case,
                                        Codec codec,
                                        VideoCodecProfile video_profile,
                                        uint8_t video_level,
                                        const VideoColorSpace& color_space,
                                        bool is_encrypted) const {
  DVLOG(3) << __func__;

  DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
  DCHECK_NE(codec, INVALID_CODEC);

  VideoCodec video_codec = MimeUtilToVideoCodec(codec);
  if (video_codec != VideoCodec::kUnknown &&
      // Theora and VP8 do not have profiles/levels.
      video_codec != VideoCodec::kTheora && video_codec != VideoCodec::kVP8 &&
      // TODO(dalecurtis): AV1 has levels, but they aren't supported yet;
      // http://crbug.com/784993
      video_codec != VideoCodec::kAV1) {
    DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN);
    DCHECK_GT(video_level, 0);
  }

  // Check for cases of ambiguous platform support.
  // TODO(chcunningham): DELETE THIS. Platform should know its capabilities.
  // Answer should come from MediaClient.
  bool ambiguous_platform_support = false;
  if (codec == MimeUtil::H264) {
    switch (video_profile) {
      // Always supported
      case H264PROFILE_BASELINE:
      case H264PROFILE_MAIN:
      case H264PROFILE_HIGH:
        break;
// HIGH10PROFILE is supported through fallback to the ffmpeg decoder
// which is not available on Android, or if FFMPEG is not used.
#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
      case H264PROFILE_HIGH10PROFILE:
        // FFmpeg is not generally used for encrypted videos, so we do not
        // know whether 10-bit is supported.
        ambiguous_platform_support = is_encrypted;
        break;
#endif
      default:
        ambiguous_platform_support = true;
    }
  }

  AudioCodec audio_codec = MimeUtilToAudioCodec(codec);
  if (audio_codec != AudioCodec::kUnknown) {
    AudioCodecProfile audio_profile = AudioCodecProfile::kUnknown;
    if (codec == MPEG4_XHE_AAC)
      audio_profile = AudioCodecProfile::kXHE_AAC;

    if (!IsSupportedAudioType({audio_codec, audio_profile, false}))
      return IsNotSupported;
  }

  if (video_codec != VideoCodec::kUnknown) {
    if (!IsSupportedVideoType(
            {video_codec, video_profile, video_level, color_space})) {
      return IsNotSupported;
    }
  }

#if defined(OS_ANDROID)
  // TODO(chcunningham): Delete this. Android platform support should be
  // handled by (android specific) media::IsSupportedVideoType() above.
  if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted,
                                 video_profile, platform_info_)) {
    return IsNotSupported;
  }
#endif

  return ambiguous_platform_support ? MayBeSupported : IsSupported;
}

bool MimeUtil::GetDefaultCodec(const std::string& mime_type,
                               Codec* default_codec) const {
  // Codecs below are unambiguously implied by the mime type string. DO NOT add
  // default codecs for ambiguous mime types.

  if (mime_type == "audio/mpeg" || mime_type == "audio/mp3" ||
      mime_type == "audio/x-mp3") {
    *default_codec = MimeUtil::MP3;
    return true;
  }

  if (mime_type == "audio/aac") {
    *default_codec = MimeUtil::MPEG4_AAC;
    return true;
  }

  if (mime_type == "audio/flac") {
    *default_codec = MimeUtil::FLAC;
    return true;
  }

  return false;
}

}  // namespace internal
}  // namespace media
