зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1248507 - p10. Detect and report when FFMpeg/Linux fails to load - 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
This commit is contained in:
Родитель
e6882cd324
Коммит
5d11be9eef
|
@ -290,7 +290,12 @@ DecoderDoctorDocumentWatcher::ReportAnalysis(
|
||||||
params,
|
params,
|
||||||
ArrayLength(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
|
void
|
||||||
|
@ -299,11 +304,19 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
bool canPlay = false;
|
bool canPlay = false;
|
||||||
|
#if defined(MOZ_FFMPEG)
|
||||||
|
bool PlatformDecoderNeeded = false;
|
||||||
|
#endif
|
||||||
nsAutoString formats;
|
nsAutoString formats;
|
||||||
for (auto& diag : mDiagnosticsSequence) {
|
for (auto& diag : mDiagnosticsSequence) {
|
||||||
if (diag.mDecoderDoctorDiagnostics.CanPlay()) {
|
if (diag.mDecoderDoctorDiagnostics.CanPlay()) {
|
||||||
canPlay = true;
|
canPlay = true;
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(MOZ_FFMPEG)
|
||||||
|
if (diag.mDecoderDoctorDiagnostics.DidFFmpegFailToLoad()) {
|
||||||
|
PlatformDecoderNeeded = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!formats.IsEmpty()) {
|
if (!formats.IsEmpty()) {
|
||||||
formats += NS_LITERAL_STRING(", ");
|
formats += NS_LITERAL_STRING(", ");
|
||||||
}
|
}
|
||||||
|
@ -311,10 +324,20 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!canPlay) {
|
if (!canPlay) {
|
||||||
DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Cannot play media, formats: %s",
|
#if defined(MOZ_FFMPEG)
|
||||||
this, mDocument, NS_ConvertUTF16toUTF8(formats).get());
|
if (PlatformDecoderNeeded) {
|
||||||
ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play,
|
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - formats: %s -> Cannot play media because platform decoder was not found",
|
||||||
"MediaCannotPlayNoDecoders", formats);
|
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()) {
|
} else if (!formats.IsEmpty()) {
|
||||||
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Can play media, but no decoders for some requested formats: %s",
|
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::Notify() - Can play media, but no decoders for some requested formats: %s",
|
||||||
this, mDocument, NS_ConvertUTF16toUTF8(formats).get());
|
this, mDocument, NS_ConvertUTF16toUTF8(formats).get());
|
||||||
|
@ -340,9 +363,9 @@ DecoderDoctorDocumentWatcher::AddDiagnostics(const nsAString& aFormat,
|
||||||
return;
|
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(),
|
this, mDocument, NS_ConvertUTF16toUTF8(aFormat).get(),
|
||||||
aCallSite, aDiagnostics.CanPlay());
|
aCallSite, aDiagnostics.CanPlay(), aDiagnostics.DidFFmpegFailToLoad());
|
||||||
mDiagnosticsSequence.AppendElement(
|
mDiagnosticsSequence.AppendElement(
|
||||||
Diagnostics(Move(aDiagnostics), aFormat, aCallSite));
|
Diagnostics(Move(aDiagnostics), aFormat, aCallSite));
|
||||||
EnsureTimerIsStarted();
|
EnsureTimerIsStarted();
|
||||||
|
|
|
@ -44,9 +44,14 @@ public:
|
||||||
void SetCanPlay() { mCanPlay = true; }
|
void SetCanPlay() { mCanPlay = true; }
|
||||||
bool CanPlay() const { return mCanPlay; }
|
bool CanPlay() const { return mCanPlay; }
|
||||||
|
|
||||||
|
void SetFFmpegFailedToLoad() { mFFmpegFailedToLoad = true; }
|
||||||
|
bool DidFFmpegFailToLoad() const { return mFFmpegFailedToLoad; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// True if there is at least one decoder that can play the media.
|
// True if there is at least one decoder that can play the media.
|
||||||
bool mCanPlay = false;
|
bool mCanPlay = false;
|
||||||
|
|
||||||
|
bool mFFmpegFailedToLoad = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "mozilla/CDMProxy.h"
|
#include "mozilla/CDMProxy.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "DecoderDoctorDiagnostics.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
|
extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
|
||||||
|
@ -160,6 +162,14 @@ PDMFactory::CreateDecoder(const TrackInfo& aConfig,
|
||||||
aImageContainer);
|
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) {
|
for (auto& current : mCurrentPDMs) {
|
||||||
if (!current->SupportsMimeType(aConfig.mMimeType, aDiagnostics)) {
|
if (!current->SupportsMimeType(aConfig.mMimeType, aDiagnostics)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -292,7 +302,9 @@ PDMFactory::CreatePDMs()
|
||||||
#ifdef MOZ_FFMPEG
|
#ifdef MOZ_FFMPEG
|
||||||
if (sFFmpegDecoderEnabled) {
|
if (sFFmpegDecoderEnabled) {
|
||||||
m = FFmpegRuntimeLinker::CreateDecoderModule();
|
m = FFmpegRuntimeLinker::CreateDecoderModule();
|
||||||
StartupPDM(m);
|
if (!StartupPDM(m)) {
|
||||||
|
mFFmpegFailedToLoad = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef MOZ_APPLEMEDIA
|
#ifdef MOZ_APPLEMEDIA
|
||||||
|
@ -335,6 +347,14 @@ already_AddRefed<PlatformDecoderModule>
|
||||||
PDMFactory::GetDecoder(const nsACString& aMimeType,
|
PDMFactory::GetDecoder(const nsACString& aMimeType,
|
||||||
DecoderDoctorDiagnostics* aDiagnostics) const
|
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;
|
RefPtr<PlatformDecoderModule> pdm;
|
||||||
for (auto& current : mCurrentPDMs) {
|
for (auto& current : mCurrentPDMs) {
|
||||||
if (current->SupportsMimeType(aMimeType, aDiagnostics)) {
|
if (current->SupportsMimeType(aMimeType, aDiagnostics)) {
|
||||||
|
|
|
@ -94,6 +94,8 @@ private:
|
||||||
|
|
||||||
nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
|
nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
|
||||||
RefPtr<PlatformDecoderModule> mEMEPDM;
|
RefPtr<PlatformDecoderModule> mEMEPDM;
|
||||||
|
|
||||||
|
bool mFFmpegFailedToLoad = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
Загрузка…
Ссылка в новой задаче