Bug 1595603 - part2 : delay seeking task when media is inactive r=bryce
When media element is inactive, asking MDSM to seek is actually useless, because all the data we decode won't be showed to user. In addition, we have to store extra pending events for `seeking` and `seeked`, which might result in memory overflow if the inactive page is calling `seek()` all the time. Therfore, we should delay all seeking tasks while media is inactive, and perform the latest seeking task when media becomes active. Differential Revision: https://phabricator.services.mozilla.com/D58918
This commit is contained in:
@@ -6526,6 +6526,7 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aSuspendElement) {
|
||||
if (mDecoder) {
|
||||
mDecoder->Pause();
|
||||
mDecoder->Suspend();
|
||||
mDecoder->SetDelaySeekMode(true);
|
||||
}
|
||||
mEventDeliveryPaused = true;
|
||||
// We won't want to resume media element from the bfcache.
|
||||
@@ -6540,6 +6541,7 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aSuspendElement) {
|
||||
if (!mPaused && !mDecoder->IsEnded()) {
|
||||
mDecoder->Play();
|
||||
}
|
||||
mDecoder->SetDelaySeekMode(false);
|
||||
}
|
||||
if (mEventDeliveryPaused) {
|
||||
mEventDeliveryPaused = false;
|
||||
|
||||
@@ -630,7 +630,6 @@ void MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType) {
|
||||
auto time = TimeUnit::FromSeconds(aTime);
|
||||
|
||||
mLogicalPosition = aTime;
|
||||
|
||||
mLogicallySeeking = true;
|
||||
SeekTarget target = SeekTarget(time, aSeekType);
|
||||
CallSeek(target);
|
||||
@@ -641,6 +640,20 @@ void MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType) {
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::SetDelaySeekMode(bool aShouldDelaySeek) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG("SetDelaySeekMode, shouldDelaySeek=%d", aShouldDelaySeek);
|
||||
if (mShouldDelaySeek == aShouldDelaySeek) {
|
||||
return;
|
||||
}
|
||||
mShouldDelaySeek = aShouldDelaySeek;
|
||||
if (!mShouldDelaySeek && mDelayedSeekTarget) {
|
||||
Seek(mDelayedSeekTarget->GetTime().ToSeconds(),
|
||||
mDelayedSeekTarget->GetType());
|
||||
mDelayedSeekTarget.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::DiscardOngoingSeekIfExists() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
@@ -650,8 +663,13 @@ void MediaDecoder::DiscardOngoingSeekIfExists() {
|
||||
void MediaDecoder::CallSeek(const SeekTarget& aTarget) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
if (mShouldDelaySeek) {
|
||||
LOG("Delay seek to %f and store it to delayed seek target",
|
||||
mDelayedSeekTarget->GetTime().ToSeconds());
|
||||
mDelayedSeekTarget = Some(aTarget);
|
||||
return;
|
||||
}
|
||||
DiscardOngoingSeekIfExists();
|
||||
|
||||
mDecoderStateMachine->InvokeSeek(aTarget)
|
||||
->Then(mAbstractMainThread, __func__, this, &MediaDecoder::OnSeekResolved,
|
||||
&MediaDecoder::OnSeekRejected)
|
||||
|
||||
@@ -159,6 +159,14 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
||||
|
||||
bool GetMinimizePreroll() const { return mMinimizePreroll; }
|
||||
|
||||
// When we enable delay seek mode, media decoder won't actually ask MDSM to do
|
||||
// seeking. During this period, we would store the latest seeking target and
|
||||
// perform the seek to that target when we leave the mode. If we have any
|
||||
// delayed seeks stored `IsSeeking()` will return true. E.g. During delay
|
||||
// seeking mode, if we get seek target to 5s, 10s, 7s. When we stop delaying
|
||||
// seeking, we would only seek to 7s.
|
||||
void SetDelaySeekMode(bool aShouldDelaySeek);
|
||||
|
||||
// All MediaStream-related data is protected by mReentrantMonitor.
|
||||
// We have at most one DecodedStreamData per MediaDecoder. Its stream
|
||||
// is used as the input for each ProcessedMediaTrack created by calls to
|
||||
@@ -664,6 +672,11 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
||||
// background.
|
||||
bool mIsBackgroundVideoDecodingAllowed;
|
||||
|
||||
// True if we want to delay seeking, and and save the latest seeking target to
|
||||
// resume to when we stop delaying seeking.
|
||||
bool mShouldDelaySeek = false;
|
||||
Maybe<SeekTarget> mDelayedSeekTarget;
|
||||
|
||||
public:
|
||||
AbstractCanonical<double>* CanonicalVolume() { return &mVolume; }
|
||||
AbstractCanonical<bool>* CanonicalPreservesPitch() {
|
||||
|
||||
@@ -57,6 +57,7 @@ struct SeekTarget {
|
||||
bool IsAccurate() const { return mType == SeekTarget::Type::Accurate; }
|
||||
bool IsNextFrame() const { return mType == SeekTarget::Type::NextFrame; }
|
||||
bool IsVideoOnly() const { return mVideoOnly; }
|
||||
Type GetType() const { return mType; }
|
||||
|
||||
private:
|
||||
// Seek target time.
|
||||
|
||||
Reference in New Issue
Block a user