Esempio n. 1
0
static bool
CheckContentType(const nsAString& aContentType,
                 mozilla::Function<bool(const nsAString&)> aSubtypeFilter,
                 mozilla::Function<bool(const nsAString&)> aCodecFilter)
{
    nsContentTypeParser parser(aContentType);
    nsAutoString mimeType;
    nsresult rv = parser.GetType(mimeType);
    if (NS_FAILED(rv) || !aSubtypeFilter(mimeType)) {
        return false;
    }

    nsString codecsStr;
    parser.GetParameter("codecs", codecsStr);
    nsTArray<nsString> codecs;
    if (!ParseCodecsString(codecsStr, codecs)) {
        return false;
    }
    for (const nsString& codec : codecs) {
        if (!aCodecFilter(codec)) {
            return false;
        }
    }
    return true;
}
Esempio n. 2
0
bool ParseMIMETypeString(const nsAString& aMIMEType,
                         nsString& aOutContainerType,
                         nsTArray<nsString>& aOutCodecs) {
  nsContentTypeParser parser(aMIMEType);
  nsresult rv = parser.GetType(aOutContainerType);
  if (NS_FAILED(rv)) {
    return false;
  }

  nsString codecsStr;
  parser.GetParameter("codecs", codecsStr);
  return ParseCodecsString(codecsStr, aOutCodecs);
}
Esempio n. 3
0
/* static */
bool
OggDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
                               const nsAString& aCodecs)
{
  if (!IsEnabled()) {
    return false;
  }

  const bool isOggAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/ogg");
  const bool isOggVideo =
    aMIMETypeExcludingCodecs.EqualsASCII("video/ogg") ||
    aMIMETypeExcludingCodecs.EqualsASCII("application/ogg");

  if (!isOggAudio && !isOggVideo) {
    return false;
  }

  nsTArray<nsCString> codecMimes;
  if (aCodecs.IsEmpty()) {
    // WebM guarantees that the only codecs it contained are vp8, vp9, opus or vorbis.
    return true;
  }
  // Verify that all the codecs specified are ones that we expect that
  // we can play.
  nsTArray<nsString> codecs;
  if (!ParseCodecsString(aCodecs, codecs)) {
    return false;
  }
  for (const nsString& codec : codecs) {
    if ((IsOpusEnabled() && codec.EqualsLiteral("opus")) ||
        codec.EqualsLiteral("vorbis") ||
        (MediaPrefs::FlacInOgg() && codec.EqualsLiteral("flac"))) {
      continue;
    }
    // Note: Only accept Theora in a video content type, not in an audio
    // content type.
    if (isOggVideo && codec.EqualsLiteral("theora")) {
      continue;
    }
    // Some unsupported codec.
    return false;
  }
  return true;
}
Esempio n. 4
0
/* static */
bool
WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
                                const nsAString& aCodecs)
{
  if (!IsEnabled()) {
    return false;
  }

  const bool isWebMAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/webm");
  const bool isWebMVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/webm");
  if (!isWebMAudio && !isWebMVideo) {
    return false;
  }

  nsTArray<nsCString> codecMimes;
  if (aCodecs.IsEmpty()) {
    // WebM guarantees that the only codecs it contained are vp8, vp9, opus or vorbis.
    return true;
  }
  // Verify that all the codecs specified are ones that we expect that
  // we can play.
  nsTArray<nsString> codecs;
  if (!ParseCodecsString(aCodecs, codecs)) {
    return false;
  }
  for (const nsString& codec : codecs) {
    if (codec.EqualsLiteral("opus") || codec.EqualsLiteral("vorbis")) {
      continue;
    }
    // Note: Only accept VP8/VP9 in a video content type, not in an audio
    // content type.
    if (isWebMVideo &&
        (codec.EqualsLiteral("vp8") || codec.EqualsLiteral("vp8.0") ||
         codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0"))) {

      continue;
    }
    // Some unsupported codec.
    return false;
  }
  return true;
}
Esempio n. 5
0
/* static */
bool
MP4Decoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
                               const nsAString& aCodecs,
                               DecoderDoctorDiagnostics* aDiagnostics)
{
  if (!IsEnabled()) {
    return false;
  }

  // Whitelist MP4 types, so they explicitly match what we encounter on
  // the web, as opposed to what we use internally (i.e. what our demuxers
  // etc output).
  const bool isMP4Audio = aMIMETypeExcludingCodecs.EqualsASCII("audio/mp4") ||
                          aMIMETypeExcludingCodecs.EqualsASCII("audio/x-m4a") ||
                          aMIMETypeExcludingCodecs.EqualsASCII("audio/opus");
  const bool isMP4Video =
  // On B2G, treat 3GPP as MP4 when Gonk PDM is available.
#ifdef MOZ_GONK_MEDIACODEC
    aMIMETypeExcludingCodecs.EqualsASCII(VIDEO_3GPP) ||
#endif
    aMIMETypeExcludingCodecs.EqualsASCII("video/mp4") ||
    aMIMETypeExcludingCodecs.EqualsASCII("video/quicktime") ||
    aMIMETypeExcludingCodecs.EqualsASCII("video/x-m4v");
  if (!isMP4Audio && !isMP4Video) {
    return false;
  }

  nsTArray<nsCString> codecMimes;
  if (aCodecs.IsEmpty()) {
    // No codecs specified. Assume AAC/H.264
    if (isMP4Audio) {
      codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
    } else {
      MOZ_ASSERT(isMP4Video);
      codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
    }
  } else {
    // Verify that all the codecs specified are ones that we expect that
    // we can play.
    nsTArray<nsString> codecs;
    if (!ParseCodecsString(aCodecs, codecs)) {
      return false;
    }
    for (const nsString& codec : codecs) {
      if (IsAACCodecString(codec)) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
        continue;
      }
      if (codec.EqualsLiteral("mp3")) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mpeg"));
        continue;
      }
      // Note: Only accept H.264 in a video content type, not in an audio
      // content type.
      if (IsWhitelistedH264Codec(codec) && isMP4Video) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
        continue;
      }
      // Some unsupported codec.
      return false;
    }
  }

  // Verify that we have a PDM that supports the whitelisted types.
  RefPtr<PDMFactory> platform = new PDMFactory();
  for (const nsCString& codecMime : codecMimes) {
    if (!platform->SupportsMimeType(codecMime, aDiagnostics)) {
      return false;
    }
  }

  return true;
}
/* static */
bool
MP4Decoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
                               const nsAString& aCodecs)
{
  if (!IsEnabled()) {
    return false;
  }

  // Whitelist MP4 types, so they explicitly match what we encounter on
  // the web, as opposed to what we use internally (i.e. what our demuxers
  // etc output).
  const bool isMP4Audio = aMIMETypeExcludingCodecs.EqualsASCII("audio/mp4") ||
                          aMIMETypeExcludingCodecs.EqualsASCII("audio/x-m4a");
  const bool isMP4Video = aMIMETypeExcludingCodecs.EqualsASCII("video/mp4") ||
#ifdef XP_LINUX
                          aMIMETypeExcludingCodecs.EqualsASCII("video/quicktime") ||
#endif
                          aMIMETypeExcludingCodecs.EqualsASCII("video/x-m4v");
  if (!isMP4Audio && !isMP4Video) {
    return false;
  }

  #ifdef MOZ_GONK_MEDIACODEC
  if (aMIMETypeExcludingCodecs.EqualsASCII(VIDEO_3GPP)) {
    return Preferences::GetBool("media.gonk.enabled", false);
  }
#endif

  nsTArray<nsCString> codecMimes;
  if (aCodecs.IsEmpty()) {
    // No codecs specified. Assume AAC/H.264
    if (isMP4Audio) {
      codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
    } else {
      MOZ_ASSERT(isMP4Video);
      codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
    }
  } else {
    // Verify that all the codecs specified are ones that we expect that
    // we can play.
    nsTArray<nsString> codecs;
    if (!ParseCodecsString(aCodecs, codecs)) {
      return false;
    }
    for (const nsString& codec : codecs) {
      if (IsAACCodecString(codec)) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
        continue;
      }
      if (codec.EqualsLiteral("mp3")) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mpeg"));
        continue;
      }
      // Note: Only accept H.264 in a video content type, not in an audio
      // content type.
      if (IsWhitelistedH264Codec(codec) && isMP4Video) {
        codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
        continue;
      }
      // Some unsupported codec.
      return false;
    }
  }

  // Verify that we have a PDM that supports the whitelisted types.
  PlatformDecoderModule::Init();
  nsRefPtr<PlatformDecoderModule> platform = PlatformDecoderModule::Create();
  if (!platform) {
    return false;
  }
  for (const nsCString& codecMime : codecMimes) {
    if (!platform->SupportsMimeType(codecMime)) {
      return false;
    }
  }

  return true;
}