Bug 1345403 part 1 - Track decoder tainting; r=jwwang

Some uses of media elements should 'taint' the element so that the video doesn't participate in video decode suspending.
Add the infrastructure to track the taint status on MediaDecoder and mirror the status to MediaDecoderStateMachine.

MozReview-Commit-ID: Ik6aDIzrZaO

--HG--
extra : rebase_source : 1dfdedea63d18918ef7b529a87f3afeb1592b149
extra : source : 1ac0f1b9264706f65e04528757bd60028331d31f
This commit is contained in:
Kaku Kuo 2017-03-08 19:28:13 +08:00
parent 9e6a8900f0
commit af6e44d1d0
4 changed files with 57 additions and 9 deletions

View File

@ -427,6 +427,7 @@ MediaDecoder::MediaDecoder(MediaDecoderOwner* aOwner)
, INIT_CANONICAL(mPlaybackRateReliable, true)
, INIT_CANONICAL(mDecoderPosition, 0)
, INIT_CANONICAL(mIsVisible, !aOwner->IsHidden())
, INIT_CANONICAL(mHasSuspendTaint, false)
, mTelemetryReported(false)
, mIsMediaElement(!!aOwner->GetMediaElement())
, mElement(aOwner->GetMediaElement())
@ -1309,6 +1310,20 @@ MediaDecoder::SetForcedHidden(bool aForcedHidden)
SetElementVisibility(mElementVisible);
}
void
MediaDecoder::SetSuspendTaint(bool aTainted)
{
MOZ_ASSERT(NS_IsMainThread());
mHasSuspendTaint = aTainted;
}
bool
MediaDecoder::HasSuspendTaint() const
{
MOZ_ASSERT(NS_IsMainThread());
return mHasSuspendTaint;
}
void
MediaDecoder::UpdateEstimatedMediaDuration(int64_t aDuration)
{

View File

@ -377,6 +377,12 @@ private:
// Called from HTMLMediaElement when testing of video decode suspend from mochitests.
void SetForcedHidden(bool aForcedHidden);
// Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
void SetSuspendTaint(bool aTaint);
// Returns true if the decoder can't participate in suspend-video-decoder.
bool HasSuspendTaint() const;
/******
* The following methods must only be called on the main
* thread.
@ -803,6 +809,10 @@ protected:
// True if the decoder is visible.
Canonical<bool> mIsVisible;
// True if the decoder has a suspend taint - meaning suspend-video-decoder is
// disabled.
Canonical<bool> mHasSuspendTaint;
public:
AbstractCanonical<media::NullableTimeUnit>* CanonicalDurationOrNull() override;
AbstractCanonical<double>* CanonicalVolume() { return &mVolume; }
@ -845,6 +855,7 @@ public:
return &mDecoderPosition;
}
AbstractCanonical<bool>* CanonicalIsVisible() { return &mIsVisible; }
AbstractCanonical<bool>* CanonicalHasSuspendTaint() { return &mHasSuspendTaint; }
private:
// Notify owner when the audible state changed

View File

@ -765,12 +765,20 @@ public:
void HandleVideoSuspendTimeout() override
{
if (mMaster->HasVideo()) {
// No video, so nothing to suspend.
if (!mMaster->HasVideo()) {
return;
}
// The decoder is tainted, so suspend-video-decoder is disabled.
if (mMaster->mHasSuspendTaint) {
return;
}
mMaster->mVideoDecodeSuspended = true;
mMaster->mOnPlaybackEvent.Notify(MediaEventType::EnterVideoSuspend);
Reader()->SetVideoBlankDecode(true);
}
}
void HandlePlayStateChanged(MediaDecoder::PlayState aPlayState) override
{
@ -1758,12 +1766,20 @@ public:
void HandleVideoSuspendTimeout() override
{
if (mMaster->HasVideo()) {
// No video, so nothing to suspend.
if (!mMaster->HasVideo()) {
return;
}
// The decoder is tainted, so nothing to suspend.
if (mMaster->mHasSuspendTaint) {
return;
}
mMaster->mVideoDecodeSuspended = true;
mMaster->mOnPlaybackEvent.Notify(MediaEventType::EnterVideoSuspend);
Reader()->SetVideoBlankDecode(true);
}
}
private:
void DispatchDecodeTasksIfNeeded();
@ -2541,6 +2557,7 @@ ShutdownState::Enter()
master->mPlaybackRateReliable.DisconnectIfConnected();
master->mDecoderPosition.DisconnectIfConnected();
master->mIsVisible.DisconnectIfConnected();
master->mHasSuspendTaint.DisconnectIfConnected();
master->mDuration.DisconnectAll();
master->mIsShutdown.DisconnectAll();
@ -2608,6 +2625,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
INIT_MIRROR(mPlaybackRateReliable, true),
INIT_MIRROR(mDecoderPosition, 0),
INIT_MIRROR(mIsVisible, true),
INIT_MIRROR(mHasSuspendTaint, false),
INIT_CANONICAL(mDuration, NullableTimeUnit()),
INIT_CANONICAL(mIsShutdown, false),
INIT_CANONICAL(mNextFrameStatus, MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE),
@ -2679,6 +2697,7 @@ MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder)
if (MediaPrefs::MDSMSuspendBackgroundVideoEnabled()) {
mIsVisible.Connect(aDecoder->CanonicalIsVisible());
mHasSuspendTaint.Connect(aDecoder->CanonicalHasSuspendTaint());
mWatchManager.Watch(mIsVisible,
&MediaDecoderStateMachine::VisibilityChanged);
}

View File

@ -738,6 +738,9 @@ private:
// IsVisible, mirrored from the media decoder.
Mirror<bool> mIsVisible;
// HasSuspendTaint, mirrored from the media decoder.
Mirror<bool> mHasSuspendTaint;
// Duration of the media. This is guaranteed to be non-null after we finish
// decoding the first frame.
Canonical<media::NullableTimeUnit> mDuration;