diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 542b6cab4c45..33a5a9748719 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -9,9 +9,6 @@
#endif
#include "mozilla/dom/HTMLMediaElement.h"
-
-#include
-
#include "AudioDeviceInfo.h"
#include "AudioStreamTrack.h"
#include "AutoplayPolicy.h"
@@ -2082,60 +2079,6 @@ double HTMLMediaElement::VideoDecodeSuspendedTime() const {
return mDecoder ? mDecoder->GetVideoDecodeSuspendedTimeInSeconds() : -1.0;
}
-void HTMLMediaElement::SetFormatDiagnosticsReportForMimeType(
- const nsAString& aMimeType, DecoderDoctorReportType aType) {
- DecoderDoctorDiagnostics diagnostics;
- diagnostics.SetDecoderDoctorReportType(aType);
- diagnostics.StoreFormatDiagnostics(OwnerDoc(), aMimeType, false /* can play*/,
- __func__);
-}
-
-void HTMLMediaElement::SetDecodeError(const nsAString& aError,
- ErrorResult& aRv) {
- // The reason we use this map-ish structure is because we can't use
- // `CR.NS_ERROR.*` directly in test. In order to use them in test, we have to
- // add them into `xpc.msg`. As we won't use `CR.NS_ERROR.*` in the production
- // code, adding them to `xpc.msg` seems an overdesign and adding maintenance
- // effort (exposing them in CR also needs to add a description, which is
- // useless because we won't show them to users)
- static struct {
- const char* mName;
- nsresult mResult;
- } kSupportedErrorList[] = {
- {"NS_ERROR_DOM_MEDIA_ABORT_ERR", NS_ERROR_DOM_MEDIA_ABORT_ERR},
- {"NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR",
- NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR},
- {"NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR",
- NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR},
- {"NS_ERROR_DOM_MEDIA_DECODE_ERR", NS_ERROR_DOM_MEDIA_DECODE_ERR},
- {"NS_ERROR_DOM_MEDIA_FATAL_ERR", NS_ERROR_DOM_MEDIA_FATAL_ERR},
- {"NS_ERROR_DOM_MEDIA_METADATA_ERR", NS_ERROR_DOM_MEDIA_METADATA_ERR},
- {"NS_ERROR_DOM_MEDIA_OVERFLOW_ERR", NS_ERROR_DOM_MEDIA_OVERFLOW_ERR},
- {"NS_ERROR_DOM_MEDIA_MEDIASINK_ERR", NS_ERROR_DOM_MEDIA_MEDIASINK_ERR},
- {"NS_ERROR_DOM_MEDIA_DEMUXER_ERR", NS_ERROR_DOM_MEDIA_DEMUXER_ERR},
- {"NS_ERROR_DOM_MEDIA_CDM_ERR", NS_ERROR_DOM_MEDIA_CDM_ERR},
- {"NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR",
- NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR}
- };
- for (auto& error : kSupportedErrorList) {
- if (strcmp(error.mName, NS_ConvertUTF16toUTF8(aError).get()) == 0) {
- DecoderDoctorDiagnostics diagnostics;
- diagnostics.StoreDecodeError(OwnerDoc(), error.mResult, u""_ns, __func__);
- return;
- }
- }
- aRv.Throw(NS_ERROR_FAILURE);
- return;
-}
-
-void HTMLMediaElement::SetAudioSinkFailedStartup() {
- DecoderDoctorDiagnostics diagnostics;
- diagnostics.StoreEvent(OwnerDoc(),
- {DecoderDoctorEvent::eAudioSinkStartup,
- NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR},
- __func__);
-}
-
already_AddRefed HTMLMediaElement::GetCurrentImage() {
MarkAsTainted();
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index fbe1094195d4..3401ae8d0c72 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -22,7 +22,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/StateWatching.h"
#include "mozilla/WeakPtr.h"
-#include "mozilla/dom/DecoderDoctorNotificationBinding.h"
#include "mozilla/dom/HTMLMediaElementBinding.h"
#include "mozilla/dom/MediaDebugInfoBinding.h"
#include "mozilla/dom/MediaKeys.h"
@@ -655,12 +654,6 @@ class HTMLMediaElement : public nsGenericHTMLElement,
double InvisiblePlayTime() const;
double VideoDecodeSuspendedTime() const;
- // Test methods for decoder doctor.
- void SetFormatDiagnosticsReportForMimeType(const nsAString& aMimeType,
- DecoderDoctorReportType aType);
- void SetDecodeError(const nsAString& aError, ErrorResult& aRv);
- void SetAudioSinkFailedStartup();
-
// Synchronously, return the next video frame and mark the element unable to
// participate in decode suspending.
//
diff --git a/dom/media/doctor/DecoderDoctorDiagnostics.cpp b/dom/media/doctor/DecoderDoctorDiagnostics.cpp
index a51ad31a1c5a..bf9c6a4c1535 100644
--- a/dom/media/doctor/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/doctor/DecoderDoctorDiagnostics.cpp
@@ -6,13 +6,11 @@
#include "DecoderDoctorDiagnostics.h"
-#include
-
#include "VideoUtils.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
-#include "mozilla/StaticPrefs_media.h"
+#include "mozilla/dom/DecoderDoctorNotificationBinding.h"
#include "mozilla/dom/Document.h"
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
@@ -256,7 +254,7 @@ static const NotificationAndReportStringId sMediaWMFNeeded = {
dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaWMFNeeded",
{ReportParam::Formats}};
-static const NotificationAndReportStringId sMediaFFMpegNotFound = {
+static const NotificationAndReportStringId sMediaPlatformDecoderNotFound = {
dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaPlatformDecoderNotFound",
{ReportParam::Formats}};
@@ -286,12 +284,15 @@ static const NotificationAndReportStringId sMediaDecodeWarning = {
{ReportParam::ResourceURL, ReportParam::DecodeIssue}};
static const NotificationAndReportStringId* const
- sAllNotificationsAndReportStringIds[] = {
- &sMediaWidevineNoWMF, &sMediaWMFNeeded,
- &sMediaFFMpegNotFound, &sMediaCannotPlayNoDecoders,
- &sMediaNoDecoders, &sCannotInitializePulseAudio,
- &sUnsupportedLibavcodec, &sMediaDecodeError,
- &sMediaDecodeWarning};
+ sAllNotificationsAndReportStringIds[] = {&sMediaWidevineNoWMF,
+ &sMediaWMFNeeded,
+ &sMediaPlatformDecoderNotFound,
+ &sMediaCannotPlayNoDecoders,
+ &sMediaNoDecoders,
+ &sCannotInitializePulseAudio,
+ &sUnsupportedLibavcodec,
+ &sMediaDecodeError,
+ &sMediaDecodeWarning};
// Create a webcompat-friendly description of a MediaResult.
static nsString MediaResultDescription(const MediaResult& aResult,
@@ -305,55 +306,6 @@ static nsString MediaResultDescription(const MediaResult& aResult,
aResult.Message().get()));
}
-static bool IsNotificationAllowedOnPlatform(
- const NotificationAndReportStringId& aNotification) {
- // Allow all notifications during testing.
- if (StaticPrefs::media_decoder_doctor_testing()) {
- return true;
- }
- // These notifications are platform independent.
- if (aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Cannot_play ||
- aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::
- Can_play_but_some_missing_decoders ||
- aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Decode_error ||
- aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Decode_warning) {
- return true;
- }
-#if defined(XP_WIN)
- if (aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Platform_decoder_not_found) {
- return strcmp(sMediaWMFNeeded.mReportStringId,
- aNotification.mReportStringId) == 0 ||
- strcmp(sMediaWidevineNoWMF.mReportStringId,
- aNotification.mReportStringId) == 0;
- }
-#endif
-#if defined(MOZ_FFMPEG)
- if (aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Platform_decoder_not_found) {
- return strcmp(sMediaFFMpegNotFound.mReportStringId,
- aNotification.mReportStringId) == 0;
- }
- if (aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Unsupported_libavcodec) {
- return strcmp(sUnsupportedLibavcodec.mReportStringId,
- aNotification.mReportStringId) == 0;
- }
-#endif
-#ifdef MOZ_PULSEAUDIO
- if (aNotification.mNotificationType ==
- dom::DecoderDoctorNotificationType::Cannot_initialize_pulseaudio) {
- return strcmp(sCannotInitializePulseAudio.mReportStringId,
- aNotification.mReportStringId) == 0;
- }
-#endif
- return false;
-}
-
static void DispatchNotification(
nsISupports* aSubject, const NotificationAndReportStringId& aNotification,
bool aIsSolved, const nsAString& aFormats, const nsAString& aDecodeIssue,
@@ -413,11 +365,6 @@ static void ReportToConsole(dom::Document* aDocument,
? ""
: NS_ConvertUTF16toUTF8(aParams[0]).get(),
aParams.Length() < 2 ? "" : ", ...");
- if (StaticPrefs::media_decoder_doctor_testing()) {
- Unused << nsContentUtils::DispatchTrustedEvent(
- aDocument, ToSupports(aDocument), u"mozreportmediaerror"_ns,
- CanBubble::eNo, Cancelable::eNo);
- }
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "Media"_ns,
aDocument, nsContentUtils::eDOM_PROPERTIES,
aConsoleStringId, aParams);
@@ -477,13 +424,6 @@ static void ReportAnalysis(dom::Document* aDocument,
return;
}
- // Some errors should only appear on the specific platform. Eg. WMF related
- // error only happens on Windows.
- if (!IsNotificationAllowedOnPlatform(aNotification)) {
- DD_WARN("Platform doesn't support '%s'!", aNotification.mReportStringId);
- return;
- }
-
nsString decodeIssueDescription;
if (aDecodeIssue != NS_OK) {
decodeIssueDescription.Assign(
@@ -519,15 +459,8 @@ static void ReportAnalysis(dom::Document* aDocument,
ReportToConsole(aDocument, aNotification.mReportStringId, params);
}
- const bool allowNotification = AllowNotification(aNotification);
- const bool allowDecodeIssue =
- AllowDecodeIssue(aDecodeIssue, aDecodeIssueIsError);
- DD_INFO(
- "ReportAnalysis for %s (decodeResult=%s) [AllowNotification=%d, "
- "AllowDecodeIssue=%d]",
- aNotification.mReportStringId, aDecodeIssue.ErrorName().get(),
- allowNotification, allowDecodeIssue);
- if (allowNotification && allowDecodeIssue) {
+ if (AllowNotification(aNotification) &&
+ AllowDecodeIssue(aDecodeIssue, aDecodeIssueIsError)) {
DispatchNotification(aDocument->GetInnerWindow(), aNotification, aIsSolved,
aFormats, decodeIssueDescription, aDocURL,
aResourceURL);
@@ -556,31 +489,18 @@ static bool FormatsListContains(const nsAString& aList,
return StringListContains(aList, CleanItemForFormatsList(aItem));
}
-static const char* GetLinkStatusLibraryName() {
-#if defined(MOZ_FFMPEG)
- return FFmpegRuntimeLinker::LinkStatusLibraryName();
-#else
- return "no library (ffmpeg disabled during build)";
-#endif
-}
-
-static const char* GetLinkStatusString() {
-#if defined(MOZ_FFMPEG)
- return FFmpegRuntimeLinker::LinkStatusString();
-#else
- return "no link (ffmpeg disabled during build)";
-#endif
-}
-
void DecoderDoctorDocumentWatcher::SynthesizeAnalysis() {
MOZ_ASSERT(NS_IsMainThread());
nsAutoString playableFormats;
nsAutoString unplayableFormats;
// Subsets of unplayableFormats that require a specific platform decoder:
+#if defined(XP_WIN)
nsAutoString formatsRequiringWMF;
+#endif
+#if defined(MOZ_FFMPEG)
nsAutoString formatsRequiringFFMpeg;
- nsAutoString formatsLibAVCodecUnsupported;
+#endif
nsAutoString supportedKeySystems;
nsAutoString unsupportedKeySystems;
DecoderDoctorDiagnostics::KeySystemIssue lastKeySystemIssue =
@@ -601,16 +521,18 @@ void DecoderDoctorDocumentWatcher::SynthesizeAnalysis() {
} else {
AppendToFormatsList(unplayableFormats,
diag.mDecoderDoctorDiagnostics.Format());
+#if defined(XP_WIN)
if (diag.mDecoderDoctorDiagnostics.DidWMFFailToLoad()) {
AppendToFormatsList(formatsRequiringWMF,
diag.mDecoderDoctorDiagnostics.Format());
- } else if (diag.mDecoderDoctorDiagnostics.DidFFmpegNotFound()) {
+ }
+#endif
+#if defined(MOZ_FFMPEG)
+ if (diag.mDecoderDoctorDiagnostics.DidFFmpegFailToLoad()) {
AppendToFormatsList(formatsRequiringFFMpeg,
diag.mDecoderDoctorDiagnostics.Format());
- } else if (diag.mDecoderDoctorDiagnostics.IsLibAVCodecUnsupported()) {
- AppendToFormatsList(formatsLibAVCodecUnsupported,
- diag.mDecoderDoctorDiagnostics.Format());
}
+#endif
}
break;
case DecoderDoctorDiagnostics::eMediaKeySystemAccessRequest:
@@ -733,6 +655,7 @@ void DecoderDoctorDocumentWatcher::SynthesizeAnalysis() {
if (playableFormats.IsEmpty()) {
// No requested formats can be played. See if we can help the user, by
// going through expected decoders from most to least desirable.
+#if defined(XP_WIN)
if (!formatsRequiringWMF.IsEmpty()) {
DD_INFO(
"DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - "
@@ -742,32 +665,46 @@ void DecoderDoctorDocumentWatcher::SynthesizeAnalysis() {
ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
return;
}
+#endif
+#if defined(MOZ_FFMPEG)
if (!formatsRequiringFFMpeg.IsEmpty()) {
- MOZ_DIAGNOSTIC_ASSERT(formatsLibAVCodecUnsupported.IsEmpty());
- DD_INFO(
- "DecoderDoctorDocumentWatcher[%p, "
- "doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> "
- "Cannot play media because ffmpeg was not found (Reason: %s)",
- this, mDocument,
- NS_ConvertUTF16toUTF8(formatsRequiringFFMpeg).get(),
- GetLinkStatusString());
- ReportAnalysis(mDocument, sMediaFFMpegNotFound, false,
- formatsRequiringFFMpeg);
- return;
- }
- if (!formatsLibAVCodecUnsupported.IsEmpty()) {
- MOZ_DIAGNOSTIC_ASSERT(formatsRequiringFFMpeg.IsEmpty());
- DD_INFO(
- "DecoderDoctorDocumentWatcher[%p, "
- "doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> "
- "Cannot play media because of unsupported %s (Reason: %s)",
- this, mDocument,
- NS_ConvertUTF16toUTF8(formatsLibAVCodecUnsupported).get(),
- GetLinkStatusLibraryName(), GetLinkStatusString());
- ReportAnalysis(mDocument, sUnsupportedLibavcodec, false,
- formatsLibAVCodecUnsupported);
- return;
+ switch (FFmpegRuntimeLinker::LinkStatusCode()) {
+ case FFmpegRuntimeLinker::LinkStatus_INVALID_FFMPEG_CANDIDATE:
+ case FFmpegRuntimeLinker::LinkStatus_UNUSABLE_LIBAV57:
+ case FFmpegRuntimeLinker::LinkStatus_INVALID_LIBAV_CANDIDATE:
+ case FFmpegRuntimeLinker::LinkStatus_OBSOLETE_FFMPEG:
+ case FFmpegRuntimeLinker::LinkStatus_OBSOLETE_LIBAV:
+ case FFmpegRuntimeLinker::LinkStatus_INVALID_CANDIDATE:
+ DD_INFO(
+ "DecoderDoctorDocumentWatcher[%p, "
+ "doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> "
+ "Cannot play media because of unsupported %s (Reason: %s)",
+ this, mDocument,
+ NS_ConvertUTF16toUTF8(formatsRequiringFFMpeg).get(),
+ FFmpegRuntimeLinker::LinkStatusLibraryName(),
+ FFmpegRuntimeLinker::LinkStatusString());
+ ReportAnalysis(mDocument, sUnsupportedLibavcodec, false,
+ formatsRequiringFFMpeg);
+ return;
+ case FFmpegRuntimeLinker::LinkStatus_INIT:
+ MOZ_FALLTHROUGH_ASSERT("Unexpected LinkStatus_INIT");
+ case FFmpegRuntimeLinker::LinkStatus_SUCCEEDED:
+ MOZ_FALLTHROUGH_ASSERT("Unexpected LinkStatus_SUCCEEDED");
+ case FFmpegRuntimeLinker::LinkStatus_NOT_FOUND:
+ DD_INFO(
+ "DecoderDoctorDocumentWatcher[%p, "
+ "doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> "
+ "Cannot play media because platform decoder was not found "
+ "(Reason: %s)",
+ this, mDocument,
+ NS_ConvertUTF16toUTF8(formatsRequiringFFMpeg).get(),
+ FFmpegRuntimeLinker::LinkStatusString());
+ ReportAnalysis(mDocument, sMediaPlatformDecoderNotFound, false,
+ formatsRequiringFFMpeg);
+ return;
+ }
}
+#endif
DD_INFO(
"DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - "
"Cannot play media, unplayable formats: %s",
@@ -1030,6 +967,7 @@ void DecoderDoctorDiagnostics::StoreEvent(dom::Document* aDocument,
}
// Don't keep events for later processing, just handle them now.
+#ifdef MOZ_PULSEAUDIO
switch (aEvent.mDomain) {
case DecoderDoctorEvent::eAudioSinkStartup:
if (aEvent.mResult == NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR) {
@@ -1047,6 +985,7 @@ void DecoderDoctorDiagnostics::StoreEvent(dom::Document* aDocument,
}
break;
}
+#endif // MOZ_PULSEAUDIO
}
void DecoderDoctorDiagnostics::StoreDecodeError(dom::Document* aDocument,
@@ -1176,8 +1115,8 @@ nsCString DecoderDoctorDiagnostics::GetDescription() const {
if (mFlags.contains(Flags::WMFFailedToLoad)) {
s += ", Windows platform decoder failed to load";
}
- if (mFlags.contains(Flags::FFmpegNotFound)) {
- s += ", Linux platform decoder not found";
+ if (mFlags.contains(Flags::FFmpegFailedToLoad)) {
+ s += ", Linux platform decoder failed to load";
}
if (mFlags.contains(Flags::GMPPDMFailedToStartup)) {
s += ", GMP PDM failed to startup";
@@ -1226,56 +1165,4 @@ nsCString DecoderDoctorDiagnostics::GetDescription() const {
return s;
}
-static const char* ToDecoderDoctorReportTypeStr(
- const dom::DecoderDoctorReportType& aType) {
- switch (aType) {
- case dom::DecoderDoctorReportType::Mediawidevinenowmf:
- return sMediaWidevineNoWMF.mReportStringId;
- case dom::DecoderDoctorReportType::Mediawmfneeded:
- return sMediaWMFNeeded.mReportStringId;
- case dom::DecoderDoctorReportType::Mediaplatformdecodernotfound:
- return sMediaFFMpegNotFound.mReportStringId;
- case dom::DecoderDoctorReportType::Mediacannotplaynodecoders:
- return sMediaCannotPlayNoDecoders.mReportStringId;
- case dom::DecoderDoctorReportType::Medianodecoders:
- return sMediaNoDecoders.mReportStringId;
- case dom::DecoderDoctorReportType::Mediacannotinitializepulseaudio:
- return sCannotInitializePulseAudio.mReportStringId;
- case dom::DecoderDoctorReportType::Mediaunsupportedlibavcodec:
- return sUnsupportedLibavcodec.mReportStringId;
- case dom::DecoderDoctorReportType::Mediadecodeerror:
- return sMediaDecodeError.mReportStringId;
- case dom::DecoderDoctorReportType::Mediadecodewarning:
- return sMediaDecodeWarning.mReportStringId;
- default:
- DD_DEBUG("Invalid report type to str");
- return "invalid-report-type";
- }
-}
-
-void DecoderDoctorDiagnostics::SetDecoderDoctorReportType(
- const dom::DecoderDoctorReportType& aType) {
- DD_INFO("Set report type %s", ToDecoderDoctorReportTypeStr(aType));
- switch (aType) {
- case dom::DecoderDoctorReportType::Mediawmfneeded:
- SetWMFFailedToLoad();
- return;
- case dom::DecoderDoctorReportType::Mediaplatformdecodernotfound:
- SetFFmpegNotFound();
- return;
- case dom::DecoderDoctorReportType::Mediaunsupportedlibavcodec:
- SetLibAVCodecUnsupported();
- return;
- case dom::DecoderDoctorReportType::Mediacannotplaynodecoders:
- case dom::DecoderDoctorReportType::Medianodecoders:
- // Do nothing, because these type are related with can-play, which would
- // be handled in `StoreFormatDiagnostics()` when sending `false` in the
- // parameter for the canplay.
- return;
- default:
- DD_DEBUG("Not supported type");
- return;
- }
-}
-
} // namespace mozilla
diff --git a/dom/media/doctor/DecoderDoctorDiagnostics.h b/dom/media/doctor/DecoderDoctorDiagnostics.h
index dee63a6f1ad4..5c5cb547fa29 100644
--- a/dom/media/doctor/DecoderDoctorDiagnostics.h
+++ b/dom/media/doctor/DecoderDoctorDiagnostics.h
@@ -11,7 +11,6 @@
#include "mozilla/DefineEnum.h"
#include "mozilla/EnumSet.h"
#include "mozilla/EnumTypeTraits.h"
-#include "mozilla/dom/DecoderDoctorNotificationBinding.h"
#include "nsString.h"
namespace mozilla {
@@ -84,7 +83,7 @@ class DecoderDoctorDiagnostics {
// Methods to record diagnostic information:
MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(
- Flags, (CanPlay, WMFFailedToLoad, FFmpegNotFound, LibAVCodecUnsupported,
+ Flags, (CanPlay, WMFFailedToLoad, FFmpegFailedToLoad,
GMPPDMFailedToStartup, VideoNotSupported, AudioNotSupported));
using FlagsSet = mozilla::EnumSet;
@@ -97,14 +96,9 @@ class DecoderDoctorDiagnostics {
return mFlags.contains(Flags::WMFFailedToLoad);
}
- void SetFFmpegNotFound() { mFlags += Flags::FFmpegNotFound; }
- bool DidFFmpegNotFound() const {
- return mFlags.contains(Flags::FFmpegNotFound);
- }
-
- void SetLibAVCodecUnsupported() { mFlags += Flags::LibAVCodecUnsupported; }
- bool IsLibAVCodecUnsupported() const {
- return mFlags.contains(Flags::LibAVCodecUnsupported);
+ void SetFFmpegFailedToLoad() { mFlags += Flags::FFmpegFailedToLoad; }
+ bool DidFFmpegFailToLoad() const {
+ return mFlags.contains(Flags::FFmpegFailedToLoad);
}
void SetGMPPDMFailedToStartup() { mFlags += Flags::GMPPDMFailedToStartup; }
@@ -131,9 +125,6 @@ class DecoderDoctorDiagnostics {
const MediaResult& DecodeIssue() const { return mDecodeIssue; }
const nsString& DecodeIssueMediaSrc() const { return mDecodeIssueMediaSrc; }
- // This method is only used for testing.
- void SetDecoderDoctorReportType(const dom::DecoderDoctorReportType& aType);
-
private:
// Currently-known type of diagnostics. Set from one of the 'Store...'
// methods. This helps ensure diagnostics are only stored once, and makes it
diff --git a/dom/media/doctor/test/browser/browser.ini b/dom/media/doctor/test/browser/browser.ini
index a73320eb9a30..292289f59448 100644
--- a/dom/media/doctor/test/browser/browser.ini
+++ b/dom/media/doctor/test/browser/browser.ini
@@ -3,4 +3,3 @@ tags = decoderdoctor
support-files =
[browser_decoderDoctor.js]
-[browser_doctor_notification.js]
diff --git a/dom/media/doctor/test/browser/browser_doctor_notification.js b/dom/media/doctor/test/browser/browser_doctor_notification.js
deleted file mode 100644
index 5789622e2332..000000000000
--- a/dom/media/doctor/test/browser/browser_doctor_notification.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/**
- * This test is used to test whether the decoder doctor would report the error
- * on the notification banner (checking that by observing message) or on the web
- * console (checking that by listening to the test event).
- * Error should be reported after calling `DecoderDoctorDiagnostics::StoreXXX`
- * methods.
- * - StoreFormatDiagnostics() [for checking if type is supported]
- * - StoreDecodeError() [when decode error occurs]
- * - StoreEvent() [for reporting audio sink error]
- */
-
-// Only types being listed here would be allowed to display on a
-// notification banner. Otherwise, the error would only be showed on the
-// web console.
-var gAllowedNotificationTypes =
- "MediaWMFNeeded,MediaFFMpegNotFound,MediaUnsupportedLibavcodec,MediaDecodeError,MediaCannotInitializePulseAudio,";
-
-// Used to check if the mime type in the notification is equal to what we set
-// before. This mime type doesn't reflect the real world siutation, i.e. not
-// every error listed in this test would happen on this type. An example, ffmpeg
-// not found would only happen on H264/AAC media.
-const gMimeType = "video/mp4";
-
-add_task(async function setupTestingPref() {
- await SpecialPowers.pushPrefEnv({
- set: [
- ["media.decoder-doctor.testing", true],
- ["media.decoder-doctor.verbose", true],
- ["media.decoder-doctor.notifications-allowed", gAllowedNotificationTypes],
- ],
- });
- // transfer types to lower cases in order to match with `DecoderDoctorReportType`
- gAllowedNotificationTypes = gAllowedNotificationTypes.toLowerCase();
-});
-
-add_task(async function testWMFIsNeeded() {
- const tab = await createTab("about:blank");
- await setFormatDiagnosticsReportForMimeType(tab, {
- type: "platform-decoder-not-found",
- decoderDoctorReportId: "mediawmfneeded",
- formats: gMimeType,
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-add_task(async function testFFMpegNotFound() {
- const tab = await createTab("about:blank");
- await setFormatDiagnosticsReportForMimeType(tab, {
- type: "platform-decoder-not-found",
- decoderDoctorReportId: "mediaplatformdecodernotfound",
- formats: gMimeType,
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-add_task(async function testLibAVCodecUnsupported() {
- const tab = await createTab("about:blank");
- await setFormatDiagnosticsReportForMimeType(tab, {
- type: "unsupported-libavcodec",
- decoderDoctorReportId: "mediaunsupportedlibavcodec",
- formats: gMimeType,
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-add_task(async function testCanNotPlayNoDecoder() {
- const tab = await createTab("about:blank");
- await setFormatDiagnosticsReportForMimeType(tab, {
- type: "cannot-play",
- decoderDoctorReportId: "mediacannotplaynodecoders",
- formats: gMimeType,
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-add_task(async function testNoDecoder() {
- const tab = await createTab("about:blank");
- await setFormatDiagnosticsReportForMimeType(tab, {
- type: "can-play-but-some-missing-decoders",
- decoderDoctorReportId: "medianodecoders",
- formats: gMimeType,
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-const gErrorList = [
- "NS_ERROR_DOM_MEDIA_ABORT_ERR",
- "NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR",
- "NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR",
- "NS_ERROR_DOM_MEDIA_DECODE_ERR",
- "NS_ERROR_DOM_MEDIA_FATAL_ERR",
- "NS_ERROR_DOM_MEDIA_METADATA_ERR",
- "NS_ERROR_DOM_MEDIA_OVERFLOW_ERR",
- "NS_ERROR_DOM_MEDIA_MEDIASINK_ERR",
- "NS_ERROR_DOM_MEDIA_DEMUXER_ERR",
- "NS_ERROR_DOM_MEDIA_CDM_ERR",
- "NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR",
-];
-
-add_task(async function testDecodeError() {
- const type = "decode-error";
- const decoderDoctorReportId = "mediadecodeerror";
- for (let error of gErrorList) {
- const tab = await createTab("about:blank");
- info(`first to try if the error is not allowed to be reported`);
- // No error is allowed to be reported in the notification banner.
- await SpecialPowers.pushPrefEnv({
- set: [["media.decoder-doctor.decode-errors-allowed", ""]],
- });
- await setDecodeError(tab, {
- type,
- decoderDoctorReportId,
- error,
- shouldReportNotification: false,
- });
-
- // If the notification type is `MediaDecodeError` and the error type is
- // listed in the pref, then the error would be reported to the
- // notification banner.
- info(`Then to try if the error is allowed to be reported`);
- await SpecialPowers.pushPrefEnv({
- set: [["media.decoder-doctor.decode-errors-allowed", error]],
- });
- await setDecodeError(tab, {
- type,
- decoderDoctorReportId,
- error,
- shouldReportNotification: true,
- });
- BrowserTestUtils.removeTab(tab);
- }
-});
-
-add_task(async function testAudioSinkFailedStartup() {
- const tab = await createTab("about:blank");
- await setAudioSinkFailedStartup(tab, {
- type: "cannot-initialize-pulseaudio",
- decoderDoctorReportId: "mediacannotinitializepulseaudio",
- // This error comes with `*`, see `DecoderDoctorDiagnostics::StoreEvent`
- formats: "*",
- });
- BrowserTestUtils.removeTab(tab);
-});
-
-/**
- * Following are helper functions
- */
-async function createTab(url) {
- let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser, url);
- // Create observer in the content process in order to check the decoder
- // doctor's notification that would be sent when an error occurs.
- await SpecialPowers.spawn(tab.linkedBrowser, [], _ => {
- content._notificationName = "decoder-doctor-notification";
- content._obs = {
- observe(subject, topic, data) {
- let { type, decoderDoctorReportId, formats } = JSON.parse(data);
- decoderDoctorReportId = decoderDoctorReportId.toLowerCase();
- info(`received '${type}:${decoderDoctorReportId}:${formats}'`);
- if (!this._resolve) {
- ok(false, "receive unexpected notification?");
- }
- if (
- type == this._type &&
- decoderDoctorReportId == this._decoderDoctorReportId &&
- formats == this._formats
- ) {
- ok(true, `received correct notification`);
- Services.obs.removeObserver(content._obs, content._notificationName);
- this._resolve();
- this._resolve = null;
- }
- },
- // Return a promise that will be resolved once receiving a notification
- // which has equal data with the input parameters.
- waitFor({ type, decoderDoctorReportId, formats }) {
- if (this._resolve) {
- ok(false, "already has a pending promise!");
- return Promise.reject();
- }
- Services.obs.addObserver(content._obs, content._notificationName);
- return new Promise(resolve => {
- info(`waiting for '${type}:${decoderDoctorReportId}:${formats}'`);
- this._resolve = resolve;
- this._type = type;
- this._decoderDoctorReportId = decoderDoctorReportId;
- this._formats = formats;
- });
- },
- };
- content._waitForReport = (params, shouldReportNotification) => {
- const reportToConsolePromise = new Promise(r => {
- content.document.addEventListener(
- "mozreportmediaerror",
- _ => {
- r();
- },
- { once: true }
- );
- });
- const reportToNotificationBannerPromise = shouldReportNotification
- ? content._obs.waitFor(params)
- : Promise.resolve();
- info(
- `waitForConsole=true, waitForNotificationBanner=${shouldReportNotification}`
- );
- return Promise.all([
- reportToConsolePromise,
- reportToNotificationBannerPromise,
- ]);
- };
- });
- return tab;
-}
-
-async function setFormatDiagnosticsReportForMimeType(tab, params) {
- const shouldReportNotification = gAllowedNotificationTypes.includes(
- params.decoderDoctorReportId
- );
- await SpecialPowers.spawn(
- tab.linkedBrowser,
- [params, shouldReportNotification],
- async (params, shouldReportNotification) => {
- const video = content.document.createElement("video");
- SpecialPowers.wrap(video).setFormatDiagnosticsReportForMimeType(
- params.formats,
- params.decoderDoctorReportId
- );
- await content._waitForReport(params, shouldReportNotification);
- }
- );
- ok(true, `finished check for ${params.decoderDoctorReportId}`);
-}
-
-async function setDecodeError(tab, params) {
- info(`start check for ${params.error}`);
- await SpecialPowers.spawn(
- tab.linkedBrowser,
- [params],
- async (params, shouldReportNotification) => {
- const video = content.document.createElement("video");
- SpecialPowers.wrap(video).setDecodeError(params.error);
- await content._waitForReport(params, params.shouldReportNotification);
- }
- );
- ok(true, `finished check for ${params.error}`);
-}
-
-async function setAudioSinkFailedStartup(tab, params) {
- const shouldReportNotification = gAllowedNotificationTypes.includes(
- params.decoderDoctorReportId
- );
- await SpecialPowers.spawn(
- tab.linkedBrowser,
- [params, shouldReportNotification],
- async (params, shouldReportNotification) => {
- const video = content.document.createElement("video");
- const waitPromise = content._waitForReport(
- params,
- shouldReportNotification
- );
- SpecialPowers.wrap(video).setAudioSinkFailedStartup();
- await waitPromise;
- }
- );
-}
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index 0bc45a98d08f..ee8b0a1ee0c4 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -450,26 +450,6 @@ void PDMFactory::CreateGpuPDMs() {
#endif
}
-#if defined(MOZ_FFMPEG)
-static DecoderDoctorDiagnostics::Flags GetFailureFlagBasedOnFFmpegStatus(
- const FFmpegRuntimeLinker::LinkStatus& aStatus) {
- switch (aStatus) {
- case FFmpegRuntimeLinker::LinkStatus_INVALID_FFMPEG_CANDIDATE:
- case FFmpegRuntimeLinker::LinkStatus_UNUSABLE_LIBAV57:
- case FFmpegRuntimeLinker::LinkStatus_INVALID_LIBAV_CANDIDATE:
- case FFmpegRuntimeLinker::LinkStatus_OBSOLETE_FFMPEG:
- case FFmpegRuntimeLinker::LinkStatus_OBSOLETE_LIBAV:
- case FFmpegRuntimeLinker::LinkStatus_INVALID_CANDIDATE:
- return DecoderDoctorDiagnostics::Flags::LibAVCodecUnsupported;
- default:
- MOZ_DIAGNOSTIC_ASSERT(
- aStatus == FFmpegRuntimeLinker::LinkStatus_NOT_FOUND,
- "Only call this method when linker fails.");
- return DecoderDoctorDiagnostics::Flags::FFmpegNotFound;
- }
-}
-#endif
-
void PDMFactory::CreateRddPDMs() {
#ifdef XP_WIN
if (StaticPrefs::media_wmf_enabled() &&
@@ -492,8 +472,9 @@ void PDMFactory::CreateRddPDMs() {
if (StaticPrefs::media_ffmpeg_enabled() &&
StaticPrefs::media_rdd_ffmpeg_enabled() &&
!CreateAndStartupPDM()) {
- mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
- FFmpegRuntimeLinker::LinkStatusCode());
+ mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
+ } else {
+ mFailureFlags -= DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
}
#endif
CreateAndStartupPDM();
@@ -534,8 +515,7 @@ void PDMFactory::CreateContentPDMs() {
#ifdef MOZ_FFMPEG
if (StaticPrefs::media_ffmpeg_enabled() &&
!CreateAndStartupPDM()) {
- mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
- FFmpegRuntimeLinker::LinkStatusCode());
+ mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
}
#endif
#ifdef MOZ_WIDGET_ANDROID
@@ -580,8 +560,7 @@ void PDMFactory::CreateDefaultPDMs() {
#ifdef MOZ_FFMPEG
if (StaticPrefs::media_ffmpeg_enabled() &&
!CreateAndStartupPDM()) {
- mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
- FFmpegRuntimeLinker::LinkStatusCode());
+ mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
}
#endif
#ifdef MOZ_WIDGET_ANDROID
diff --git a/dom/webidl/DecoderDoctorNotification.webidl b/dom/webidl/DecoderDoctorNotification.webidl
index 6c6ad6835e46..911531c992bd 100644
--- a/dom/webidl/DecoderDoctorNotification.webidl
+++ b/dom/webidl/DecoderDoctorNotification.webidl
@@ -14,18 +14,6 @@ enum DecoderDoctorNotificationType {
"decode-warning",
};
-enum DecoderDoctorReportType {
- "mediawidevinenowmf",
- "mediawmfneeded",
- "mediaplatformdecodernotfound",
- "mediacannotplaynodecoders",
- "medianodecoders",
- "mediacannotinitializepulseaudio",
- "mediaunsupportedlibavcodec",
- "mediadecodeerror",
- "mediadecodewarning",
-};
-
[GenerateToJSON]
dictionary DecoderDoctorNotification {
required DecoderDoctorNotificationType type;
diff --git a/dom/webidl/HTMLMediaElement.webidl b/dom/webidl/HTMLMediaElement.webidl
index 601d651f9485..d7b52b8e79cf 100644
--- a/dom/webidl/HTMLMediaElement.webidl
+++ b/dom/webidl/HTMLMediaElement.webidl
@@ -204,18 +204,18 @@ partial interface HTMLMediaElement {
Promise seekToNextFrame();
};
-/* Internal testing only API */
+/*
+ * These APIs are testing only, they are used to simulate visibility changes to help debug and write
+ * tests about suspend-video-decoding.
+ *
+ * - SetVisible() is for simulating visibility changes.
+ * - HasSuspendTaint() is for querying that the element's decoder cannot suspend
+ * video decoding because it has been tainted by an operation, such as
+ * drawImage().
+ * - isVisible is a boolean value which indicate whether media element is visible.
+ * - isVideoDecodingSuspended() is used to know whether video decoding has suspended.
+ */
partial interface HTMLMediaElement {
- // These APIs are used to simulate visibility changes to help debug and write
- // tests about suspend-video-decoding.
- // - SetVisible() is for simulating visibility changes.
- // - HasSuspendTaint() is for querying that the element's decoder cannot suspend
- // video decoding because it has been tainted by an operation, such as
- // drawImage().
- // - isInViewPort is a boolean value which indicate whether media element is
- // in view port.
- // - isVideoDecodingSuspended() is used to know whether video decoding has
- // suspended.
[Pref="media.test.video-suspend"]
void setVisible(boolean aVisible);
@@ -236,16 +236,6 @@ partial interface HTMLMediaElement {
[ChromeOnly]
readonly attribute double videoDecodeSuspendedTime;
-
- // These APIs are used for decoder doctor tests.
- [ChromeOnly]
- void setFormatDiagnosticsReportForMimeType(DOMString mimeType, DecoderDoctorReportType error);
-
- [Throws, ChromeOnly]
- void setDecodeError(DOMString error);
-
- [ChromeOnly]
- void setAudioSinkFailedStartup();
};
/* Audio Output Devices API */
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
index 4a2930381403..46778e1355f6 100644
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -7516,11 +7516,6 @@
#endif # MOZ_WMF
-- name: media.decoder-doctor.testing
- type: bool
- value: false
- mirror: always
-
- name: media.hardware-video-decoding.force-enabled
type: bool
value: false
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 451c4fb9829f..bd6aa8ea764d 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -395,9 +395,9 @@ pref("media.gmp.storage.version.expected", 1);
// Filter what triggers user notifications.
// See DecoderDoctorDocumentWatcher::ReportAnalysis for details.
#ifdef NIGHTLY_BUILD
- pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec,MediaPlatformDecoderNotFound,MediaDecodeError");
+ pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec,MediaDecodeError");
#else
- pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec,MediaPlatformDecoderNotFound");
+ pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMF,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec");
#endif
pref("media.decoder-doctor.decode-errors-allowed", "");
pref("media.decoder-doctor.decode-warnings-allowed", "");