Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1248507 - p10. Detect and report when FFMpeg/Linux fails to load …
Browse files Browse the repository at this point in the history
…- r=jya

If the FFmpeg decoder module cannot be started, the failure is recorded in the
DecoderDoctorDiagnostics structure.
In this case, on Linux if there are no suitable decoders for any requested
format, a "platform decoder not found" notification is sent to Chrome (a
separate bug will implement the actual front-end notification), and logged to
the web console.

Note: All front-end notifications (that could display a notification bar) are
currently disabled by default. Set the following pref to true to enable them:
"media.decoderdoctor.enable-notification-bar".

MozReview-Commit-ID: CdaX7QUdWtd
  • Loading branch information
squelart committed Apr 19, 2016
1 parent 2034fd1 commit 487d08e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
37 changes: 30 additions & 7 deletions dom/media/DecoderDoctorDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -299,22 +304,40 @@ 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(", ");
}
formats += diag.mFormat;
}
}
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());
Expand All @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions dom/media/DecoderDoctorDiagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ class DecoderDoctorDiagnostics
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
Expand Down
22 changes: 21 additions & 1 deletion dom/media/platforms/PDMFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include "mozilla/CDMProxy.h"
#endif

#include "DecoderDoctorDiagnostics.h"

namespace mozilla {

extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -335,6 +347,14 @@ already_AddRefed<PlatformDecoderModule>
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<PlatformDecoderModule> pdm;
for (auto& current : mCurrentPDMs) {
if (current->SupportsMimeType(aMimeType, aDiagnostics)) {
Expand Down
2 changes: 2 additions & 0 deletions dom/media/platforms/PDMFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class PDMFactory final {

nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
RefPtr<PlatformDecoderModule> mEMEPDM;

bool mFFmpegFailedToLoad = false;
};

} // namespace mozilla
Expand Down

0 comments on commit 487d08e

Please sign in to comment.