Bug 848994 - p6. Analyze Windows issues - r=cpearce

Analyze the diagnostics information gathered so far, and dispatch
notifications as appropriate.
The most important case in this bug is when Widevine is requested but WMF and
Silverlight are missing.
The generic case of WMF missing (when needed to play) is there too.

Note: Currently no notifications are actually sent to the front-end by default,
the following patch will add filtering to allow/prevent targeted notifications.

MozReview-Commit-ID: EB9PKrMgKSr
This commit is contained in:
Gerald Squelart 2016-04-22 13:42:11 +10:00
Родитель 04d6608e8c
Коммит e23866c192
2 изменённых файлов: 85 добавлений и 27 удалений

Просмотреть файл

@ -107,11 +107,14 @@ MediaLoadSourceMediaNotMatched=Specified "media" attribute of "%1$S" does not ma
MediaLoadUnsupportedMimeType=HTTP "Content-Type" of "%1$S" is not supported. Load of media resource %2$S failed.
# LOCALIZATION NOTE: %S is the URL of the media resource which failed to load because of error in decoding.
MediaLoadDecodeError=Media resource %S could not be decoded.
MediaWidevineNoWMFNoSilverlight=Trying to play Widevine with no Windows Media Foundation (nor Silverlight fallback), see https://support.mozilla.org/kb/fix-video-audio-problems-firefox-windows
# LOCALIZATION NOTE: %S is a comma-separated list of codecs (e.g. 'video/mp4, video/webm')
MediaCannotPlayNoDecoders=Cannot play media. No decoders for requested formats: %S
MediaWMFNeeded=To play video formats %S, you need to install extra Microsoft software, see https://support.mozilla.org/kb/fix-video-audio-problems-firefox-windows
# LOCALIZATION NOTE: %S is a comma-separated list of codecs (e.g. 'video/mp4, video/webm')
MediaPlatformDecoderNotFound=The video on this page can't be played. Your system may not have the required video codecs for: %S
# LOCALIZATION NOTE: %S is a comma-separated list of codecs (e.g. 'video/mp4, video/webm')
MediaCannotPlayNoDecoders=Cannot play media. No decoders for requested formats: %S
# LOCALIZATION NOTE: %S is a comma-separated list of codecs (e.g. 'video/mp4, video/webm')
MediaNoDecoders=No decoders for some of the requested formats: %S
# LOCALIZATION NOTE: Do not translate "MediaRecorder".
MediaRecorderMultiTracksNotSupported=MediaRecorder does not support recording multiple tracks of the same type at this time.

Просмотреть файл

@ -266,7 +266,7 @@ void
DecoderDoctorDocumentWatcher::ReportAnalysis(
dom::DecoderDoctorNotificationType aNotificationType,
const char* aReportStringId,
const nsAString& aFormats)
const nsAString& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
@ -274,23 +274,24 @@ DecoderDoctorDocumentWatcher::ReportAnalysis(
return;
}
const char16_t* params[] = { aFormats.Data() };
// 'params' will only be forwarded for non-empty strings.
const char16_t* params[1] = { aParams.Data() };
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::ReportAnalysis() ReportToConsole - aMsg='%s' params[0]='%s'",
this, mDocument, aReportStringId,
NS_ConvertUTF16toUTF8(params[0]).get());
aParams.IsEmpty() ? "<no params>" : NS_ConvertUTF16toUTF8(params[0]).get());
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Media"),
mDocument,
nsContentUtils::eDOM_PROPERTIES,
aReportStringId,
params,
ArrayLength(params));
aParams.IsEmpty() ? nullptr : params,
aParams.IsEmpty() ? 0 : 1);
// 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);
mDocument->GetInnerWindow(), aNotificationType, aParams);
}
}
@ -321,41 +322,67 @@ CheckSilverlight()
return eNoSilverlight;
}
static void AppendToStringList(nsAString& list, const nsAString& item)
{
if (!list.IsEmpty()) {
list += NS_LITERAL_STRING(", ");
}
list += item;
}
void
DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
{
MOZ_ASSERT(NS_IsMainThread());
bool canPlay = false;
#if defined(XP_WIN)
bool WMFNeeded = false;
#endif
#if defined(MOZ_FFMPEG)
bool FFMpegNeeded = false;
#endif
nsAutoString playableFormats;
nsAutoString unplayableFormats;
nsAutoString supportedKeySystems;
nsAutoString unsupportedKeySystems;
DecoderDoctorDiagnostics::KeySystemIssue lastKeySystemIssue =
DecoderDoctorDiagnostics::eUnset;
for (auto& diag : mDiagnosticsSequence) {
switch (diag.mDecoderDoctorDiagnostics.Type()) {
case DecoderDoctorDiagnostics::eFormatSupportCheck:
if (diag.mDecoderDoctorDiagnostics.CanPlay()) {
canPlay = true;
AppendToStringList(playableFormats,
diag.mDecoderDoctorDiagnostics.Format());
} else {
#if defined(XP_WIN)
if (diag.mDecoderDoctorDiagnostics.DidWMFFailToLoad()) {
WMFNeeded = true;
}
#endif
#if defined(MOZ_FFMPEG)
if (diag.mDecoderDoctorDiagnostics.DidFFmpegFailToLoad()) {
FFMpegNeeded = true;
}
#endif
if (!unplayableFormats.IsEmpty()) {
unplayableFormats += NS_LITERAL_STRING(", ");
}
unplayableFormats += diag.mDecoderDoctorDiagnostics.Format();
AppendToStringList(unplayableFormats,
diag.mDecoderDoctorDiagnostics.Format());
}
break;
case DecoderDoctorDiagnostics::eMediaKeySystemAccessRequest:
if (!diag.mDecoderDoctorDiagnostics.IsKeySystemSupported()) {
if (!unsupportedKeySystems.IsEmpty()) {
unsupportedKeySystems += NS_LITERAL_STRING(", ");
if (diag.mDecoderDoctorDiagnostics.IsKeySystemSupported()) {
AppendToStringList(supportedKeySystems,
diag.mDecoderDoctorDiagnostics.KeySystem());
} else {
AppendToStringList(unsupportedKeySystems,
diag.mDecoderDoctorDiagnostics.KeySystem());
DecoderDoctorDiagnostics::KeySystemIssue issue =
diag.mDecoderDoctorDiagnostics.GetKeySystemIssue();
if (issue != DecoderDoctorDiagnostics::eUnset) {
lastKeySystemIssue = issue;
}
unsupportedKeySystems += diag.mDecoderDoctorDiagnostics.KeySystem();
}
break;
default:
@ -367,22 +394,50 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
}
}
if (!canPlay) {
// Look at Key System issues first, as they may influence format checks.
if (!unsupportedKeySystems.IsEmpty() && supportedKeySystems.IsEmpty()) {
// No supported key systems!
switch (lastKeySystemIssue) {
case DecoderDoctorDiagnostics::eWidevineWithNoWMF:
if (CheckSilverlight() != eSilverlightEnabled) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unsupported key systems: %s, widevine without WMF nor Silverlight",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaWidevineNoWMFNoSilverlight", NS_LITERAL_STRING(""));
return;
}
break;
default:
break;
}
}
if (!canPlay && !unplayableFormats.IsEmpty()) {
#if defined(XP_WIN)
if (WMFNeeded) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - formats: %s -> Cannot play media because WMF was not found",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaWMFNeeded", unplayableFormats);
return;
}
#endif
#if defined(MOZ_FFMPEG)
if (FFMpegNeeded) {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because platform decoder was not found",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaPlatformDecoderNotFound", unplayableFormats);
} else
#endif
{
DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Cannot play media, unplayable formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play,
"MediaCannotPlayNoDecoders", unplayableFormats);
return;
}
} else if (!unplayableFormats.IsEmpty()) {
#endif
DD_WARN("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Cannot play media, unplayable formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
ReportAnalysis(dom::DecoderDoctorNotificationType::Cannot_play,
"MediaCannotPlayNoDecoders", unplayableFormats);
return;
}
if (!unplayableFormats.IsEmpty()) {
DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Can play media, but no decoders for some requested formats: %s",
this, mDocument, NS_ConvertUTF16toUTF8(unplayableFormats).get());
if (Preferences::GetBool("media.decoderdoctor.verbose", false)) {
@ -390,10 +445,10 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
dom::DecoderDoctorNotificationType::Can_play_but_some_missing_decoders,
"MediaNoDecoders", unplayableFormats);
}
} else {
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Can play media, decoders available for all requested formats",
this, mDocument);
return;
}
DD_DEBUG("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - Can play media, decoders available for all requested formats",
this, mDocument);
}
void