mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 22:32:51 +00:00
Backed out 8 changesets (bug 1691578) for bc failures on browser_decoderDoctor.js. CLOSED TREE
Backed out changeset c535dd429ada (bug 1691578) Backed out changeset 518eadda7826 (bug 1691578) Backed out changeset c181e29b13f2 (bug 1691578) Backed out changeset 23f6dcc3ceb5 (bug 1691578) Backed out changeset bfd3e4878545 (bug 1691578) Backed out changeset 214ab3a2f00b (bug 1691578) Backed out changeset 71a17ff3322c (bug 1691578) Backed out changeset 6aa662e8d06e (bug 1691578)
This commit is contained in:
parent
a38e77b0db
commit
424d49d43e
@ -9,9 +9,6 @@
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#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<layers::Image> HTMLMediaElement::GetCurrentImage() {
|
||||
MarkAsTainted();
|
||||
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -6,13 +6,11 @@
|
||||
|
||||
#include "DecoderDoctorDiagnostics.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
|
@ -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<Flags>;
|
||||
|
||||
@ -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
|
||||
|
@ -3,4 +3,3 @@ tags = decoderdoctor
|
||||
support-files =
|
||||
|
||||
[browser_decoderDoctor.js]
|
||||
[browser_doctor_notification.js]
|
||||
|
@ -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;
|
||||
}
|
||||
);
|
||||
}
|
@ -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<FFmpegRuntimeLinker>()) {
|
||||
mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
|
||||
FFmpegRuntimeLinker::LinkStatusCode());
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
|
||||
} else {
|
||||
mFailureFlags -= DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
|
||||
}
|
||||
#endif
|
||||
CreateAndStartupPDM<AgnosticDecoderModule>();
|
||||
@ -534,8 +515,7 @@ void PDMFactory::CreateContentPDMs() {
|
||||
#ifdef MOZ_FFMPEG
|
||||
if (StaticPrefs::media_ffmpeg_enabled() &&
|
||||
!CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
|
||||
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<FFmpegRuntimeLinker>()) {
|
||||
mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
|
||||
FFmpegRuntimeLinker::LinkStatusCode());
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
@ -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;
|
||||
|
@ -204,18 +204,18 @@ partial interface HTMLMediaElement {
|
||||
Promise<void> 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 */
|
||||
|
@ -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
|
||||
|
@ -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", "");
|
||||
|
Loading…
x
Reference in New Issue
Block a user