Bug 1293963 - phase-1 shipping; r?jwwang
MozReview-Commit-ID: L7BZ2D2VHjG
--- 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");