// 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;
    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

  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
  }

  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

  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
