diff --git a/dom/media/DecoderDoctorDiagnostics.cpp b/dom/media/DecoderDoctorDiagnostics.cpp index 0c3ff55fa5e9..3d247ee8ae5b 100644 --- a/dom/media/DecoderDoctorDiagnostics.cpp +++ b/dom/media/DecoderDoctorDiagnostics.cpp @@ -290,7 +290,12 @@ DecoderDoctorDocumentWatcher::ReportAnalysis( params, ArrayLength(params)); - DispatchNotification(mDocument->GetInnerWindow(), aNotificationType, aFormats); + // For now, disable all front-end notifications by default. + // TODO: Future bugs will use finer-grained filtering instead. + if (Preferences::GetBool("media.decoderdoctor.enable-notification-bar", false)) { + DispatchNotification( + mDocument->GetInnerWindow(), aNotificationType, aFormats); + } } void @@ -299,11 +304,19 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis() MOZ_ASSERT(NS_IsMainThread()); bool canPlay = false; +#if defined(MOZ_FFMPEG) + bool PlatformDecoderNeeded = false; +#endif nsAutoString formats; for (auto& diag : mDiagnosticsSequence) { if (diag.mDecoderDoctorDiagnostics.CanPlay()) { canPlay = true; } else { +#if defined(MOZ_FFMPEG) + if (diag.mDecoderDoctorDiagnostics.DidFFmpegFailToLoad()) { + PlatformDecoderNeeded = true; + } +#endif if (!formats.IsEmpty()) { formats += NS_LITERAL_STRING(", "); } @@ -311,10 +324,20 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis() } } if (!canPlay) { - DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Cannot play media, formats: %s", - this, mDocument, NS_ConvertUTF16toUTF8(formats).get()); - ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play, - "MediaCannotPlayNoDecoders", formats); +#if defined(MOZ_FFMPEG) + if (PlatformDecoderNeeded) { + DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - formats: %s -> Cannot play media because platform decoder was not found", + this, mDocument, NS_ConvertUTF16toUTF8(formats).get()); + ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found, + "MediaPlatformDecoderNotFound", formats); + } else +#endif + { + DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Cannot play media, formats: %s", + this, mDocument, NS_ConvertUTF16toUTF8(formats).get()); + ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play, + "MediaCannotPlayNoDecoders", formats); + } } else if (!formats.IsEmpty()) { DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Can play media, but no decoders for some requested formats: %s", this, mDocument, NS_ConvertUTF16toUTF8(formats).get()); @@ -340,9 +363,9 @@ DecoderDoctorDocumentWatcher::AddDiagnostics(const nsAString& aFormat, return; } - DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::AddDiagnostics(format='%s', call site '%s', can play=%d)", + DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::AddDiagnostics(format='%s', call site '%s', can play=%d, platform lib failed to load=%d)", this, mDocument, NS_ConvertUTF16toUTF8(aFormat).get(), - aCallSite, aDiagnostics.CanPlay()); + aCallSite, aDiagnostics.CanPlay(), aDiagnostics.DidFFmpegFailToLoad()); mDiagnosticsSequence.AppendElement( Diagnostics(Move(aDiagnostics), aFormat, aCallSite)); EnsureTimerIsStarted(); diff --git a/dom/media/DecoderDoctorDiagnostics.h b/dom/media/DecoderDoctorDiagnostics.h index cffb8d01dd91..b2e9347af3b1 100644 --- a/dom/media/DecoderDoctorDiagnostics.h +++ b/dom/media/DecoderDoctorDiagnostics.h @@ -44,9 +44,14 @@ public: void SetCanPlay() { mCanPlay = true; } bool CanPlay() const { return mCanPlay; } + void SetFFmpegFailedToLoad() { mFFmpegFailedToLoad = true; } + bool DidFFmpegFailToLoad() const { return mFFmpegFailedToLoad; } + private: // True if there is at least one decoder that can play the media. bool mCanPlay = false; + + bool mFFmpegFailedToLoad = false; }; } // namespace mozilla diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp index f363d4669940..b32b0d4043d2 100644 --- a/dom/media/platforms/PDMFactory.cpp +++ b/dom/media/platforms/PDMFactory.cpp @@ -42,6 +42,8 @@ #include "mozilla/CDMProxy.h" #endif +#include "DecoderDoctorDiagnostics.h" + namespace mozilla { extern already_AddRefed CreateAgnosticDecoderModule(); @@ -160,6 +162,14 @@ PDMFactory::CreateDecoder(const TrackInfo& aConfig, aImageContainer); } + if (aDiagnostics) { + // If libraries failed to load, the following loop over mCurrentPDMs + // will not even try to use them. So we record failures now. + if (mFFmpegFailedToLoad) { + aDiagnostics->SetFFmpegFailedToLoad(); + } + } + for (auto& current : mCurrentPDMs) { if (!current->SupportsMimeType(aConfig.mMimeType, aDiagnostics)) { continue; @@ -292,7 +302,9 @@ PDMFactory::CreatePDMs() #ifdef MOZ_FFMPEG if (sFFmpegDecoderEnabled) { m = FFmpegRuntimeLinker::CreateDecoderModule(); - StartupPDM(m); + if (!StartupPDM(m)) { + mFFmpegFailedToLoad = true; + } } #endif #ifdef MOZ_APPLEMEDIA @@ -335,6 +347,14 @@ already_AddRefed PDMFactory::GetDecoder(const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const { + if (aDiagnostics) { + // If libraries failed to load, the following loop over mCurrentPDMs + // will not even try to use them. So we record failures now. + if (mFFmpegFailedToLoad) { + aDiagnostics->SetFFmpegFailedToLoad(); + } + } + RefPtr pdm; for (auto& current : mCurrentPDMs) { if (current->SupportsMimeType(aMimeType, aDiagnostics)) { diff --git a/dom/media/platforms/PDMFactory.h b/dom/media/platforms/PDMFactory.h index 3c433c0b2870..b4048614837d 100644 --- a/dom/media/platforms/PDMFactory.h +++ b/dom/media/platforms/PDMFactory.h @@ -94,6 +94,8 @@ private: nsTArray> mCurrentPDMs; RefPtr mEMEPDM; + + bool mFFmpegFailedToLoad = false; }; } // namespace mozilla