Bug 1293963 - phase-1 shipping; r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Mon, 05 Sep 2016 11:53:34 +0800
changeset 409809 80acc1ce4ddfc3a9483ac2712a40fcd02493dc67
parent 409126 38cf3424509fb51e32f8fa32dcc58b60b0445033
child 530419 7539a96af3cbadd0a7b687a6f8bc84d30ad5a2fa
push id28555
push userbmo:kaku@mozilla.com
push dateMon, 05 Sep 2016 07:39:00 +0000
reviewersjwwang
bugs1293963
milestone51.0a1
Bug 1293963 - phase-1 shipping; r?jwwang MozReview-Commit-ID: L7BZ2D2VHjG
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
dom/media/MediaPrefs.h
modules/libpref/init/all.js
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1376,24 +1376,20 @@ ReportRecoveryTelemetry(const TimeStamp&
 
 void MediaDecoderStateMachine::VisibilityChanged()
 {
   MOZ_ASSERT(OnTaskQueue());
   DECODER_LOG("VisibilityChanged: mIsVisible=%d, "
               "mVideoDecodeSuspended=%c, mIsReaderSuspended=%d",
               mIsVisible.Ref(), mVideoDecodeSuspended ? 'T' : 'F', mIsReaderSuspended.Ref());
 
-  if (!HasVideo()) {
+  if (!ShouldEnableSuspendVideoDecoder()) {
     return;
   }
 
-  // If not playing then there's nothing to do.
-  if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING) {
-    return;
-  }
 
   // Start timer to trigger suspended decoding state when going invisible.
   if (!mIsVisible) {
     TimeStamp target = TimeStamp::Now() + SuspendBackgroundVideoDelay();
 
     RefPtr<MediaDecoderStateMachine> self = this;
     mVideoDecodeSuspendTimer.Ensure(target,
                                     [=]() { self->OnSuspendTimerResolved(); },
@@ -1441,16 +1437,41 @@ void MediaDecoderStateMachine::Visibilit
 
     InitiateSeek(Move(seekJob))
       ->Then(AbstractThread::MainThread(), __func__,
              [start, info, hw](){ ReportRecoveryTelemetry(start, info, hw); },
              [](){});
   }
 }
 
+bool
+MediaDecoderStateMachine::ShouldEnableSuspendVideoDecoder() const
+{
+  MOZ_ASSERT(OnTaskQueue());
+
+  if (!HasVideo()) {
+    return false;
+  }
+
+  // If not playing then there's nothing to do.
+  if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING) {
+    return false;
+  }
+
+  // Criteria of enabling the suspend-video-decoder feature in phase-1:
+  // (1) videos without audio track.
+  // (2) videos with audio track and smaller than certain resolution.
+  if (HasAudio() &&
+      mInfo.mVideo.mImage.height > (int)MediaPrefs::MDSMSuspendBackgroundVideoResolutionUpperBound()) {
+    return false;
+  }
+
+  return true;
+}
+
 void MediaDecoderStateMachine::BufferedRangeUpdated()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   // While playing an unseekable stream of unknown duration, mObservedDuration
   // is updated (in AdvanceFrame()) as we play. But if data is being downloaded
   // faster than played, mObserved won't reflect the end of playable data
   // since we haven't played the frame at the end of buffered data. So update
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -467,16 +467,20 @@ protected:
   void StartMediaSink();
 
   // Notification method invoked when mPlayState changes.
   void PlayStateChanged();
 
   // Notification method invoked when mIsVisible changes.
   void VisibilityChanged();
 
+  // Collect all the policy used to check whether the suspend-video-decode
+  // feature should be enabled or not for this video file.
+  bool ShouldEnableSuspendVideoDecoder() const;
+
   // Sets internal state which causes playback of media to pause.
   // The decoder monitor must be held.
   void StopPlayback();
 
   // If the conditions are right, sets internal state which causes playback
   // of media to begin or resume.
   // Must be called with the decode monitor held.
   void MaybeStartPlayback();
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -130,16 +130,17 @@ private:
   DECL_MEDIA_PREF("media.decoder.fuzzing.dont-delay-inputexhausted", PDMFuzzingDelayInputExhausted, bool, true);
   DECL_MEDIA_PREF("media.gmp.decoder.enabled",                PDMGMPEnabled, bool, true);
   DECL_MEDIA_PREF("media.gmp.decoder.aac",                    GMPAACPreferred, uint32_t, 0);
   DECL_MEDIA_PREF("media.gmp.decoder.h264",                   GMPH264Preferred, uint32_t, 0);
 
   // MediaDecoderStateMachine
   DECL_MEDIA_PREF("media.suspend-bkgnd-video.enabled",        MDSMSuspendBackgroundVideoEnabled, bool, false);
   DECL_MEDIA_PREF("media.suspend-bkgnd-video.delay-ms",       MDSMSuspendBackgroundVideoDelay, AtomicUint32, SUSPEND_BACKGROUND_VIDEO_DELAY_MS);
+  DECL_MEDIA_PREF("media.suspend-bkgnd-video.resolution-upperbound",  MDSMSuspendBackgroundVideoResolutionUpperBound, AtomicUint32, 480);
 
   // WebSpeech
   DECL_MEDIA_PREF("media.webspeech.synth.force_global_queue", WebSpeechForceGlobal, bool, false);
   DECL_MEDIA_PREF("media.webspeech.test.enable",              WebSpeechTestEnabled, bool, false);
   DECL_MEDIA_PREF("media.webspeech.test.fake_fsm_events",     WebSpeechFakeFSMEvents, bool, false);
   DECL_MEDIA_PREF(TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE,   WebSpeechFakeRecognitionService, bool, false);
   DECL_MEDIA_PREF("media.webspeech.recognition.enable",       WebSpeechRecognitionEnabled, bool, false);
   DECL_MEDIA_PREF("media.webspeech.recognition.force_enable", WebSpeechRecognitionForceEnabled, bool, false);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -385,26 +385,27 @@ pref("media.gmp.storage.version.expected
 // Filter what triggers user notifications.
 // See DecoderDoctorDocumentWatcher::ReportAnalysis for details.
 pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMFNoSilverlight");
 // Whether we report partial failures.
 pref("media.decoder-doctor.verbose", false);
 // Whether DD should consider WMF-disabled a WMF failure, useful for testing.
 pref("media.decoder-doctor.wmf-disabled-is-failure", false);
 
-// Whether to suspend decoding of videos in background tabs.
-#ifdef NIGHTLY_BUILD
+// Whether to suspend decoding of invisible videos or not.
 pref("media.suspend-bkgnd-video.enabled", true);
-#else
-pref("media.suspend-bkgnd-video.enabled", false);
-#endif
+
 // Delay, in ms, from time window goes to background to suspending
 // video decoders. Defaults to 10 seconds.
 pref("media.suspend-bkgnd-video.delay-ms", 10000);
 
+// The resolution upper bound used in phase 1.
+// Videos with audio track but larger than this resolution will not be suspended.
+pref("media.suspend-bkgnd-video.resolution-upperbound", 480);
+
 #ifdef MOZ_WEBRTC
 pref("media.navigator.enabled", true);
 pref("media.navigator.video.enabled", true);
 pref("media.navigator.load_adapt", true);
 pref("media.navigator.load_adapt.measure_interval",1000);
 pref("media.navigator.load_adapt.avg_seconds",3);
 pref("media.navigator.load_adapt.high_load","0.90");
 pref("media.navigator.load_adapt.low_load","0.40");