mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1123452 - Make Mp4Reader enter dormant state when it is idle and its document is hidden. r=cpearce
This commit is contained in:
parent
b86c52f82a
commit
9c64ff755d
@ -36,6 +36,9 @@
|
|||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
// Default timeout msecs until try to enter dormant state by heuristic.
|
||||||
|
static const int DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS = 60000;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
// Number of estimated seconds worth of data we need to have buffered
|
// Number of estimated seconds worth of data we need to have buffered
|
||||||
@ -123,27 +126,55 @@ void MediaDecoder::NotifyOwnerActivityChanged()
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||||
|
|
||||||
if (!mDecoderStateMachine ||
|
|
||||||
!mDecoderStateMachine->IsDormantNeeded() ||
|
|
||||||
mPlayState == PLAY_STATE_SHUTDOWN) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mOwner) {
|
if (!mOwner) {
|
||||||
NS_WARNING("MediaDecoder without a decoder owner, can't update dormant");
|
NS_WARNING("MediaDecoder without a decoder owner, can't update dormant");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateDormantState(false /* aDormantTimeout */, false /* aActivity */);
|
||||||
|
// Start dormant timer if necessary
|
||||||
|
StartDormantTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaDecoder::UpdateDormantState(bool aDormantTimeout, bool aActivity)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||||
|
|
||||||
|
if (!mDecoderStateMachine ||
|
||||||
|
!mOwner->GetVideoFrameContainer() ||
|
||||||
|
!mDecoderStateMachine->IsDormantNeeded() ||
|
||||||
|
mPlayState == PLAY_STATE_SHUTDOWN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool prevDormant = mIsDormant;
|
bool prevDormant = mIsDormant;
|
||||||
mIsDormant = false;
|
mIsDormant = false;
|
||||||
if (!mOwner->IsActive() && mOwner->GetVideoFrameContainer()) {
|
if (!mOwner->IsActive()) {
|
||||||
mIsDormant = true;
|
mIsDormant = true;
|
||||||
}
|
}
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
if (mOwner->IsHidden() && mOwner->GetVideoFrameContainer()) {
|
if (mOwner->IsHidden()) {
|
||||||
mIsDormant = true;
|
mIsDormant = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// Try to enable dormant by idle heuristic, when the owner is hidden.
|
||||||
|
bool prevHeuristicDormant = mIsHeuristicDormant;
|
||||||
|
mIsHeuristicDormant = false;
|
||||||
|
if (mIsHeuristicDormantSupported && mOwner->IsHidden()) {
|
||||||
|
if (aDormantTimeout && !aActivity &&
|
||||||
|
(mPlayState == PLAY_STATE_PAUSED || mPlayState == PLAY_STATE_ENDED)) {
|
||||||
|
// Enable heuristic dormant
|
||||||
|
mIsHeuristicDormant = true;
|
||||||
|
} else if(prevHeuristicDormant && !aActivity) {
|
||||||
|
// Continue heuristic dormant
|
||||||
|
mIsHeuristicDormant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIsHeuristicDormant) {
|
||||||
|
mIsDormant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (prevDormant == mIsDormant) {
|
if (prevDormant == mIsDormant) {
|
||||||
// No update to dormant state
|
// No update to dormant state
|
||||||
@ -167,6 +198,47 @@ void MediaDecoder::NotifyOwnerActivityChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaDecoder::DormantTimerExpired(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aClosure);
|
||||||
|
MediaDecoder* decoder = static_cast<MediaDecoder*>(aClosure);
|
||||||
|
ReentrantMonitorAutoEnter mon(decoder->GetReentrantMonitor());
|
||||||
|
decoder->UpdateDormantState(true /* aDormantTimeout */,
|
||||||
|
false /* aActivity */);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaDecoder::StartDormantTimer()
|
||||||
|
{
|
||||||
|
if (!mIsHeuristicDormantSupported) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIsHeuristicDormant ||
|
||||||
|
mShuttingDown ||
|
||||||
|
!mOwner ||
|
||||||
|
!mOwner->IsHidden() ||
|
||||||
|
(mPlayState != PLAY_STATE_PAUSED &&
|
||||||
|
mPlayState != PLAY_STATE_ENDED))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mDormantTimer) {
|
||||||
|
mDormantTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||||
|
}
|
||||||
|
mDormantTimer->InitWithFuncCallback(&MediaDecoder::DormantTimerExpired,
|
||||||
|
this,
|
||||||
|
mHeuristicDormantTimeout,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaDecoder::CancelDormantTimer()
|
||||||
|
{
|
||||||
|
if (mDormantTimer) {
|
||||||
|
mDormantTimer->Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MediaDecoder::Pause()
|
void MediaDecoder::Pause()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
@ -472,7 +544,13 @@ MediaDecoder::MediaDecoder() :
|
|||||||
mPausedForPlaybackRateNull(false),
|
mPausedForPlaybackRateNull(false),
|
||||||
mMinimizePreroll(false),
|
mMinimizePreroll(false),
|
||||||
mMediaTracksConstructed(false),
|
mMediaTracksConstructed(false),
|
||||||
mIsDormant(false)
|
mIsDormant(false),
|
||||||
|
mIsHeuristicDormantSupported(
|
||||||
|
Preferences::GetBool("media.decoder.heuristic.dormant.enabled", false)),
|
||||||
|
mHeuristicDormantTimeout(
|
||||||
|
Preferences::GetInt("media.decoder.heuristic.dormant.timeout",
|
||||||
|
DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS)),
|
||||||
|
mIsHeuristicDormant(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(MediaDecoder);
|
MOZ_COUNT_CTOR(MediaDecoder);
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
@ -521,6 +599,8 @@ void MediaDecoder::Shutdown()
|
|||||||
mResource->Close();
|
mResource->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CancelDormantTimer();
|
||||||
|
|
||||||
ChangeState(PLAY_STATE_SHUTDOWN);
|
ChangeState(PLAY_STATE_SHUTDOWN);
|
||||||
|
|
||||||
mOwner = nullptr;
|
mOwner = nullptr;
|
||||||
@ -622,6 +702,8 @@ nsresult MediaDecoder::Play()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||||
|
UpdateDormantState(false /* aDormantTimeout */, true /* aActivity */);
|
||||||
|
|
||||||
NS_ASSERTION(mDecoderStateMachine != nullptr, "Should have state machine.");
|
NS_ASSERTION(mDecoderStateMachine != nullptr, "Should have state machine.");
|
||||||
if (mPausedForPlaybackRateNull) {
|
if (mPausedForPlaybackRateNull) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -644,6 +726,7 @@ nsresult MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType)
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||||
|
UpdateDormantState(false /* aDormantTimeout */, true /* aActivity */);
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(aTime >= 0.0, "Cannot seek to a negative value.");
|
NS_ABORT_IF_FALSE(aTime >= 0.0, "Cannot seek to a negative value.");
|
||||||
|
|
||||||
@ -1192,6 +1275,10 @@ void MediaDecoder::ChangeState(PlayState aState)
|
|||||||
|
|
||||||
ApplyStateToStateMachine(mPlayState);
|
ApplyStateToStateMachine(mPlayState);
|
||||||
|
|
||||||
|
CancelDormantTimer();
|
||||||
|
// Start dormant timer if necessary
|
||||||
|
StartDormantTimer();
|
||||||
|
|
||||||
GetReentrantMonitor().NotifyAll();
|
GetReentrantMonitor().NotifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,7 @@ destroying the MediaDecoder object.
|
|||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsITimer.h"
|
||||||
#include "MediaResource.h"
|
#include "MediaResource.h"
|
||||||
#include "mozilla/dom/AudioChannelBinding.h"
|
#include "mozilla/dom/AudioChannelBinding.h"
|
||||||
#include "mozilla/gfx/Rect.h"
|
#include "mozilla/gfx/Rect.h"
|
||||||
@ -367,6 +368,8 @@ public:
|
|||||||
// It is used to share scarece media resources in system.
|
// It is used to share scarece media resources in system.
|
||||||
virtual void NotifyOwnerActivityChanged();
|
virtual void NotifyOwnerActivityChanged();
|
||||||
|
|
||||||
|
void UpdateDormantState(bool aDormantTimeout, bool aActivity);
|
||||||
|
|
||||||
// Pause video playback.
|
// Pause video playback.
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
// Adjust the speed of the playback, optionally with pitch correction,
|
// Adjust the speed of the playback, optionally with pitch correction,
|
||||||
@ -1022,6 +1025,14 @@ protected:
|
|||||||
virtual ~MediaDecoder();
|
virtual ~MediaDecoder();
|
||||||
void SetStateMachineParameters();
|
void SetStateMachineParameters();
|
||||||
|
|
||||||
|
static void DormantTimerExpired(nsITimer *aTimer, void *aClosure);
|
||||||
|
|
||||||
|
// Start a timer for heuristic dormant.
|
||||||
|
void StartDormantTimer();
|
||||||
|
|
||||||
|
// Cancel a timer for heuristic dormant.
|
||||||
|
void CancelDormantTimer();
|
||||||
|
|
||||||
/******
|
/******
|
||||||
* The following members should be accessed with the decoder lock held.
|
* The following members should be accessed with the decoder lock held.
|
||||||
******/
|
******/
|
||||||
@ -1219,6 +1230,18 @@ protected:
|
|||||||
|
|
||||||
// True if MediaDecoder is in dormant state.
|
// True if MediaDecoder is in dormant state.
|
||||||
bool mIsDormant;
|
bool mIsDormant;
|
||||||
|
|
||||||
|
// True if heuristic dormant is supported.
|
||||||
|
const bool mIsHeuristicDormantSupported;
|
||||||
|
|
||||||
|
// Timeout ms of heuristic dormant timer.
|
||||||
|
const int mHeuristicDormantTimeout;
|
||||||
|
|
||||||
|
// True if MediaDecoder is in dormant by heuristic.
|
||||||
|
bool mIsHeuristicDormant;
|
||||||
|
|
||||||
|
// Timer to schedule updating dormant state.
|
||||||
|
nsCOMPtr<nsITimer> mDormantTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
Loading…
Reference in New Issue
Block a user