Bug 1343437 - 'media.playback.warnings-as-errors' pref - r?jya
If 'media.playback.warnings-as-errors' is true, demuxing and decoding warnings
(i.e., non-fatal errors) will be treated as errors, causing playback to fail.
Currently set to false by default.
This could be later changed to catch and diagnose more issues.
MozReview-Commit-ID: BTaZ6TbIbNG
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -5,17 +5,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AutoTaskQueue.h"
#include "mozilla/SizePrintfMacros.h"
#include "Layers.h"
#include "MediaData.h"
#include "MediaInfo.h"
#include "MediaFormatReader.h"
-#include "MediaPrefs.h"
#include "MediaResource.h"
#include "VideoUtils.h"
#include "VideoFrameContainer.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/CDMProxy.h"
#include "mozilla/ClearOnShutdown.h"
@@ -1328,16 +1327,21 @@ MediaFormatReader::AsyncReadMetadata()
}
void
MediaFormatReader::OnDemuxerInitDone(const MediaResult& aResult)
{
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.Complete();
+ if (NS_FAILED(aResult) && MediaPrefs::MediaWarningsAsErrors()) {
+ mMetadataPromise.Reject(aResult, __func__);
+ return;
+ }
+
mDemuxerInitDone = true;
UniquePtr<MetadataTags> tags(MakeUnique<MetadataTags>());
RefPtr<PDMFactory> platform;
if (!IsWaitingOnCDMResource()) {
platform = new PDMFactory();
}
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -10,16 +10,17 @@
#include "mozilla/Atomics.h"
#include "mozilla/Maybe.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/Mutex.h"
#include "MediaEventSource.h"
#include "MediaDataDemuxer.h"
#include "MediaDecoderReader.h"
+#include "MediaPrefs.h"
#include "nsAutoPtr.h"
#include "PDMFactory.h"
namespace mozilla {
class CDMProxy;
class MediaFormatReader final : public MediaDecoderReader
@@ -281,18 +282,19 @@ private:
Maybe<MediaResult> mError;
bool HasFatalError() const
{
if (!mError.isSome()) {
return false;
}
if (mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR) {
// Allow decode errors to be non-fatal, but give up
- // if we have too many.
- return mNumOfConsecutiveError > mMaxConsecutiveError;
+ // if we have too many, or if warnings should be treated as errors.
+ return mNumOfConsecutiveError > mMaxConsecutiveError
+ || MediaPrefs::MediaWarningsAsErrors();
} else if (mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) {
// If the caller asked for a new decoder we shouldn't treat
// it as fatal.
return false;
} else {
// All other error types are fatal
return true;
}
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -176,16 +176,19 @@ private:
#endif
#if defined(OS_LINUX)
DECL_MEDIA_PREF("media.rust.mp4parser", EnableRustMP4Parser, bool, true);
#else
DECL_MEDIA_PREF("media.rust.mp4parser", EnableRustMP4Parser, bool, false);
#endif
+ // Error/warning handling, Decoder Doctor
+ DECL_MEDIA_PREF("media.playback.warnings-as-errors", MediaWarningsAsErrors, bool, false);
+
public:
// Manage the singleton:
static MediaPrefs& GetSingleton();
static bool SingletonExists();
private:
template<class T> friend class StaticAutoPtr;
static StaticAutoPtr<MediaPrefs> sInstance;
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TrackBuffersManager.h"
#include "ContainerParser.h"
+#include "MediaPrefs.h"
#include "MediaSourceDemuxer.h"
#include "MediaSourceUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/StateMirroring.h"
#include "SourceBufferResource.h"
#include "SourceBuffer.h"
#include "WebMDemuxer.h"
@@ -853,16 +854,22 @@ TrackBuffersManager::ResetDemuxingState(
->Track(mDemuxerInitRequest);
}
void
TrackBuffersManager::OnDemuxerResetDone(const MediaResult& aResult)
{
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.Complete();
+
+ if (NS_FAILED(aResult) && MediaPrefs::MediaWarningsAsErrors()) {
+ RejectAppend(aResult, __func__);
+ return;
+ }
+
// mInputDemuxer shouldn't have been destroyed while a demuxer init/reset
// request was being processed. See bug 1239983.
MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer);
if (aResult != NS_OK && mParentDecoder) {
RefPtr<TrackBuffersManager> self = this;
mAbstractMainThread->Dispatch(NS_NewRunnableFunction([self, aResult] () {
if (self->mParentDecoder && self->mParentDecoder->GetOwner()) {
@@ -951,16 +958,21 @@ TrackBuffersManager::InitializationSegme
void
TrackBuffersManager::OnDemuxerInitDone(const MediaResult& aResult)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer, "mInputDemuxer has been destroyed");
mDemuxerInitRequest.Complete();
+ if (NS_FAILED(aResult) && MediaPrefs::MediaWarningsAsErrors()) {
+ RejectAppend(aResult, __func__);
+ return;
+ }
+
MediaInfo info;
uint32_t numVideos = mInputDemuxer->GetNumberTracks(TrackInfo::kVideoTrack);
if (numVideos) {
// We currently only handle the first video track.
mVideoTracks.mDemuxer =
mInputDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
MOZ_ASSERT(mVideoTracks.mDemuxer);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -595,16 +595,19 @@ pref("media.video_stats.enabled", true);
// Whether to check the decoder supports recycling.
pref("media.decoder.recycle.enabled", false);
// Log level for cubeb, the audio input/output system. Valid values are
// "verbose", "normal" and "" (log disabled).
pref("media.cubeb.log_level", "");
+// Set to true to force demux/decode warnings to be treated as errors.
+pref("media.playback.warnings-as-errors", false);
+
// Weather we allow AMD switchable graphics
pref("layers.amd-switchable-gfx.enabled", true);
// Whether to use async panning and zooming
pref("layers.async-pan-zoom.enabled", true);
// Whether to enable event region building during painting
pref("layout.event-regions.enabled", false);