static CanPlayStatus CanHandleMediaType(const MediaContentType& aType, DecoderDoctorDiagnostics* aDiagnostics) { MOZ_ASSERT(NS_IsMainThread()); if (IsHttpLiveStreamingType(aType.GetMIMEType())) { Telemetry::Accumulate(Telemetry::MEDIA_HLS_CANPLAY_REQUESTED, true); } if (aType.HaveCodecs()) { CanPlayStatus result = CanHandleCodecsType(aType, aDiagnostics); if (result == CANPLAY_NO || result == CANPLAY_YES) { return result; } } if (IsOggTypeAndEnabled(aType.GetMIMEType())) { return CANPLAY_MAYBE; } if (IsWaveSupportedType(aType.GetMIMEType())) { return CANPLAY_MAYBE; } if (DecoderTraits::IsMP4TypeAndEnabled(aType.GetMIMEType(), aDiagnostics)) { return CANPLAY_MAYBE; } #if !defined(MOZ_OMX_WEBM_DECODER) if (DecoderTraits::IsWebMTypeAndEnabled(aType.GetMIMEType())) { return CANPLAY_MAYBE; } #endif if (IsMP3SupportedType(aType.GetMIMEType())) { return CANPLAY_MAYBE; } if (IsAACSupportedType(aType.GetMIMEType())) { return CANPLAY_MAYBE; } if (IsFlacSupportedType(aType.GetMIMEType())) { return CANPLAY_MAYBE; } #ifdef MOZ_DIRECTSHOW if (DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), nullptr)) { return CANPLAY_MAYBE; } #endif #ifdef MOZ_ANDROID_OMX if (MediaDecoder::IsAndroidMediaPluginEnabled() && EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), nullptr)) { return CANPLAY_MAYBE; } #endif return CANPLAY_NO; }
static CanPlayStatus CanHandleCodecsType(const MediaContentType& aType, DecoderDoctorDiagnostics* aDiagnostics) { // We should have been given a codecs string, though it may be empty. MOZ_ASSERT(aType.HaveCodecs()); char const* const* codecList = nullptr; if (IsOggTypeAndEnabled(aType.GetMIMEType())) { if (IsOggSupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } else { // We can only reach this position if a particular codec was requested, // ogg is supported and working: the codec must be invalid. return CANPLAY_NO; } } if (IsWaveSupportedType(aType.GetMIMEType())) { if (IsWaveSupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } else { // We can only reach this position if a particular codec was requested, // ogg is supported and working: the codec must be invalid. return CANPLAY_NO; } } #if !defined(MOZ_OMX_WEBM_DECODER) if (DecoderTraits::IsWebMTypeAndEnabled(aType.GetMIMEType())) { if (IsWebMSupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } else { // We can only reach this position if a particular codec was requested, // webm is supported and working: the codec must be invalid. return CANPLAY_NO; } } #endif #ifdef MOZ_FMP4 if (DecoderTraits::IsMP4TypeAndEnabled(aType.GetMIMEType(), aDiagnostics)) { if (IsMP4SupportedType(aType, aDiagnostics)) { return CANPLAY_YES; } else { // We can only reach this position if a particular codec was requested, // fmp4 is supported and working: the codec must be invalid. return CANPLAY_NO; } } #endif if (IsMP3SupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } if (IsAACSupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } if (IsFlacSupportedType(aType.GetMIMEType(), aType.GetCodecs())) { return CANPLAY_YES; } #ifdef MOZ_DIRECTSHOW DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), &codecList); #endif #ifdef MOZ_ANDROID_OMX if (MediaDecoder::IsAndroidMediaPluginEnabled()) { EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), &codecList); } #endif if (!codecList) { return CANPLAY_MAYBE; } // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description // of the 'codecs' parameter nsCharSeparatedTokenizer tokenizer(aType.GetCodecs(), ','); bool expectMoreTokens = false; while (tokenizer.hasMoreTokens()) { const nsSubstring& token = tokenizer.nextToken(); if (!CodecListContains(codecList, token)) { // Totally unsupported codec return CANPLAY_NO; } expectMoreTokens = tokenizer.separatorAfterCurrentToken(); } if (expectMoreTokens) { // Last codec name was empty return CANPLAY_NO; } return CANPLAY_YES; }