зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1122228 - Use document's status change to trigger MediaDecoderStateMachine's dormant status change r=cpearce
This commit is contained in:
Родитель
a9545c0e64
Коммит
4f96a3066c
|
@ -2524,15 +2524,13 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
|
|||
// It's value may have changed, so update it.
|
||||
UpdatePreloadAction();
|
||||
}
|
||||
mElementInTreeState = ELEMENT_INTREE;
|
||||
|
||||
if (mDecoder) {
|
||||
// When the MediaElement is binding to tree, the dormant status is
|
||||
// aligned to document's hidden status.
|
||||
nsIDocument* ownerDoc = OwnerDoc();
|
||||
if (ownerDoc) {
|
||||
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
|
||||
}
|
||||
mDecoder->NotifyOwnerActivityChanged();
|
||||
}
|
||||
mElementInTreeState = ELEMENT_INTREE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -2543,12 +2541,14 @@ void HTMLMediaElement::UnbindFromTree(bool aDeep,
|
|||
if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY)
|
||||
Pause();
|
||||
|
||||
if (mDecoder) {
|
||||
mDecoder->SetDormantIfNecessary(true);
|
||||
}
|
||||
mElementInTreeState = ELEMENT_NOT_INTREE_HAD_INTREE;
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
if (mDecoder) {
|
||||
MOZ_ASSERT(IsHidden());
|
||||
mDecoder->NotifyOwnerActivityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -3519,6 +3519,21 @@ void HTMLMediaElement::CheckAutoplayDataReady()
|
|||
}
|
||||
}
|
||||
|
||||
bool HTMLMediaElement::IsActive()
|
||||
{
|
||||
nsIDocument* ownerDoc = OwnerDoc();
|
||||
return ownerDoc && ownerDoc->IsActive() && ownerDoc->IsVisible();
|
||||
}
|
||||
|
||||
bool HTMLMediaElement::IsHidden()
|
||||
{
|
||||
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
|
||||
return true;
|
||||
}
|
||||
nsIDocument* ownerDoc = OwnerDoc();
|
||||
return !ownerDoc || ownerDoc->Hidden();
|
||||
}
|
||||
|
||||
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
|
||||
{
|
||||
if (mVideoFrameContainer)
|
||||
|
@ -3698,15 +3713,7 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
|
|||
|
||||
if (mDecoder) {
|
||||
mDecoder->SetElementVisibility(!ownerDoc->Hidden());
|
||||
|
||||
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
|
||||
mDecoder->SetDormantIfNecessary(true);
|
||||
} else if (mElementInTreeState == ELEMENT_NOT_INTREE ||
|
||||
mElementInTreeState == ELEMENT_INTREE) {
|
||||
// The MediaElement had never been binded to tree, or in the tree now,
|
||||
// align to document.
|
||||
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
|
||||
}
|
||||
mDecoder->NotifyOwnerActivityChanged();
|
||||
}
|
||||
|
||||
// SetVisibilityState will update mMuted with MUTED_BY_AUDIO_CHANNEL via the
|
||||
|
@ -3716,10 +3723,9 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
|
|||
AutoNoJSAPI nojsapi;
|
||||
mAudioChannelAgent->SetVisibilityState(!ownerDoc->Hidden());
|
||||
}
|
||||
bool suspendEvents = !ownerDoc->IsActive() || !ownerDoc->IsVisible();
|
||||
bool pauseElement = suspendEvents || (mMuted & MUTED_BY_AUDIO_CHANNEL);
|
||||
bool pauseElement = !IsActive() || (mMuted & MUTED_BY_AUDIO_CHANNEL);
|
||||
|
||||
SuspendOrResumeElement(pauseElement, suspendEvents);
|
||||
SuspendOrResumeElement(pauseElement, !IsActive());
|
||||
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
|
|
@ -211,6 +211,10 @@ public:
|
|||
// suspended the channel.
|
||||
virtual void NotifySuspendedByCache(bool aIsSuspended) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsActive() MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsHidden() MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// Called by the media decoder and the video frame to get the
|
||||
// ImageContainer containing the video data.
|
||||
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
@ -374,7 +378,7 @@ public:
|
|||
|
||||
// Called by the media decoder object, on the main thread,
|
||||
// when the connection between Rtsp server and client gets lost.
|
||||
void ResetConnectionState() MOZ_FINAL MOZ_OVERRIDE;
|
||||
virtual void ResetConnectionState() MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// XPCOM GetPreload() is OK
|
||||
void SetPreload(const nsAString& aValue, ErrorResult& aRv)
|
||||
|
|
|
@ -118,7 +118,7 @@ NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)
|
|||
|
||||
NS_IMPL_ISUPPORTS(MediaDecoder, nsIObserver)
|
||||
|
||||
void MediaDecoder::SetDormantIfNecessary(bool aDormant)
|
||||
void MediaDecoder::NotifyOwnerActivityChanged()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
@ -129,7 +129,28 @@ void MediaDecoder::SetDormantIfNecessary(bool aDormant)
|
|||
return;
|
||||
}
|
||||
|
||||
if(aDormant) {
|
||||
if (!mOwner) {
|
||||
NS_WARNING("MediaDecoder without a decoder owner, can't update dormant");
|
||||
return;
|
||||
}
|
||||
|
||||
bool prevDormant = mIsDormant;
|
||||
mIsDormant = false;
|
||||
if (!mOwner->IsActive() && mOwner->GetVideoFrameContainer()) {
|
||||
mIsDormant = true;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (mOwner->IsHidden() && mOwner->GetVideoFrameContainer()) {
|
||||
mIsDormant = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prevDormant == mIsDormant) {
|
||||
// No update to dormant state
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsDormant) {
|
||||
// enter dormant state
|
||||
mDecoderStateMachine->SetDormant(true);
|
||||
|
||||
|
@ -450,7 +471,8 @@ MediaDecoder::MediaDecoder() :
|
|||
mShuttingDown(false),
|
||||
mPausedForPlaybackRateNull(false),
|
||||
mMinimizePreroll(false),
|
||||
mMediaTracksConstructed(false)
|
||||
mMediaTracksConstructed(false),
|
||||
mIsDormant(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MediaDecoder);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
|
|
@ -360,11 +360,12 @@ public:
|
|||
// called.
|
||||
virtual nsresult Play();
|
||||
|
||||
// Set/Unset dormant state if necessary.
|
||||
// Notify activity of the decoder owner is changed.
|
||||
// Based on the activity, dormant state is updated.
|
||||
// Dormant state is a state to free all scarce media resources
|
||||
// (like hw video codec), did not decoding and stay dormant.
|
||||
// It is used to share scarece media resources in system.
|
||||
virtual void SetDormantIfNecessary(bool aDormant);
|
||||
virtual void NotifyOwnerActivityChanged();
|
||||
|
||||
// Pause video playback.
|
||||
virtual void Pause();
|
||||
|
@ -1215,6 +1216,9 @@ protected:
|
|||
// Stores media info, including info of audio tracks and video tracks, should
|
||||
// only be accessed from main thread.
|
||||
nsAutoPtr<MediaInfo> mInfo;
|
||||
|
||||
// True if MediaDecoder is in dormant state.
|
||||
bool mIsDormant;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -120,6 +120,12 @@ public:
|
|||
// HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA.
|
||||
virtual void UpdateReadyStateForData(NextFrameStatus aNextFrame) = 0;
|
||||
|
||||
// Check if the decoder owner is active.
|
||||
virtual bool IsActive() = 0;
|
||||
|
||||
// Check if the decoder owner is hidden.
|
||||
virtual bool IsHidden() = 0;
|
||||
|
||||
// Called by the media decoder and the video frame to get the
|
||||
// ImageContainer containing the video data.
|
||||
virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче