Bug 1343437 - 'media.playback.warnings-as-errors' pref - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Fri, 03 Mar 2017 16:10:48 +1100
changeset 560825 520d1afa8740579915b4db629c409654f93cfa46
parent 560824 bd91a8ad1e0a9c721ed2114da3da429aa0484fc1
child 560826 0f0824d4def213e0f1e311106a0546cbf056bae7
push id53551
push usergsquelart@mozilla.com
push dateTue, 11 Apr 2017 23:47:44 +0000
reviewersjya
bugs1343437
milestone55.0a1
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
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/MediaPrefs.h
dom/media/mediasource/TrackBuffersManager.cpp
modules/libpref/init/all.js
--- 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);