Bug 571822 - Fire timeupdate event less frequently than once per frame - r=kinetik a=blocking2.0

This commit is contained in:
Chris Double 2010-09-10 17:49:26 +12:00
Родитель 59fc7690ce
Коммит 2b061fde1c
4 изменённых файлов: 81 добавлений и 4 удалений

Просмотреть файл

@ -145,6 +145,8 @@ void nsBuiltinDecoder::Shutdown()
mShuttingDown = PR_TRUE;
StopTimeUpdate();
// This changes the decoder state to SHUTDOWN and does other things
// necessary to unblock the state machine thread if it's blocked, so
// the asynchronous shutdown in nsDestroyStateMachine won't deadlock.
@ -387,6 +389,8 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
if (resourceIsLoaded) {
ResourceLoaded();
}
StartTimeUpdate();
}
void nsBuiltinDecoder::ResourceLoaded()
@ -773,7 +777,7 @@ void nsBuiltinDecoder::PlaybackPositionChanged()
Invalidate();
if (mElement && lastTime != mCurrentTime) {
mElement->DispatchEvent(NS_LITERAL_STRING("timeupdate"));
FireTimeUpdate();
}
}

Просмотреть файл

@ -68,12 +68,14 @@
// Number of milliseconds of no data before a stall event is fired as defined by spec
#define STALL_MS 3000
// Number of milliseconds between timeupdate events as defined by spec
#define TIMEUPDATE_MS 250
nsMediaDecoder::nsMediaDecoder() :
mElement(0),
mRGBWidth(-1),
mRGBHeight(-1),
mProgressTime(),
mDataTime(),
mLastCurrentTime(0.0),
mVideoUpdateLock(nsnull),
mPixelAspectRatio(1.0),
mFrameBufferLength(0),
@ -235,6 +237,54 @@ nsresult nsMediaDecoder::StopProgress()
return rv;
}
static void TimeUpdateCallback(nsITimer* aTimer, void* aClosure)
{
nsMediaDecoder* decoder = static_cast<nsMediaDecoder*>(aClosure);
decoder->FireTimeUpdate();
}
void nsMediaDecoder::FireTimeUpdate()
{
if (!mElement)
return;
TimeStamp now = TimeStamp::Now();
float time = GetCurrentTime();
// If TIMEUPDATE_MS has passed since the last timeupdate event fired and the time
// has changed, fire a timeupdate event.
if ((mTimeUpdateTime.IsNull() ||
now - mTimeUpdateTime >= TimeDuration::FromMilliseconds(TIMEUPDATE_MS)) &&
mLastCurrentTime != time) {
mElement->DispatchEvent(NS_LITERAL_STRING("timeupdate"));
mTimeUpdateTime = now;
mLastCurrentTime = time;
}
}
nsresult nsMediaDecoder::StartTimeUpdate()
{
if (mTimeUpdateTimer)
return NS_OK;
mTimeUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
return mTimeUpdateTimer->InitWithFuncCallback(TimeUpdateCallback,
this,
TIMEUPDATE_MS,
nsITimer::TYPE_REPEATING_SLACK);
}
nsresult nsMediaDecoder::StopTimeUpdate()
{
if (!mTimeUpdateTimer)
return NS_OK;
nsresult rv = mTimeUpdateTimer->Cancel();
mTimeUpdateTimer = nsnull;
return rv;
}
void nsMediaDecoder::SetVideoData(const gfxIntSize& aSize,
float aPixelAspectRatio,
Image* aImage)

Просмотреть файл

@ -205,6 +205,10 @@ public:
// than the result of downloaded data.
virtual void Progress(PRBool aTimer);
// Fire timeupdate events if needed according to the time constraints
// outlined in the specification.
virtual void FireTimeUpdate();
// Called by nsMediaStream when the "cache suspended" status changes.
// If nsMediaStream::IsSuspendedByCache returns true, then the decoder
// should stop buffering or otherwise waiting for download progress and
@ -285,6 +289,12 @@ protected:
// Stop progress information timer.
nsresult StopProgress();
// Start timer to send timeupdate event
nsresult StartTimeUpdate();
// Stop timeupdate timer
nsresult StopTimeUpdate();
// Ensures our media stream has been pinned.
void PinForSeek();
@ -295,6 +305,9 @@ protected:
// Timer used for updating progress events
nsCOMPtr<nsITimer> mProgressTimer;
// Timer used for updating timeupdate events
nsCOMPtr<nsITimer> mTimeUpdateTimer;
// This should only ever be accessed from the main thread.
// It is set in Init and cleared in Shutdown when the element goes away.
// The decoder does not add a reference the element.
@ -309,6 +322,10 @@ protected:
// main thread only.
TimeStamp mProgressTime;
// Time that the last timeupdate event was fired. Read/Write from the
// main thread only.
TimeStamp mTimeUpdateTime;
// Time that data was last read from the media resource. Used for
// computing if the download has stalled and to rate limit progress events
// when data is arriving slower than PROGRESS_MS. A value of null indicates
@ -316,6 +333,10 @@ protected:
// more data is received. Read/Write from the main thread only.
TimeStamp mDataTime;
// Media 'currentTime' value when the last timeupdate event occurred.
// Read/Write from the main thread only.
float mLastCurrentTime;
// Lock around the video RGB, width and size data. This
// is used in the decoder backend threads and the main thread
// to ensure that repainting the video does not use these

Просмотреть файл

@ -1433,6 +1433,7 @@ nsWaveDecoder::MetadataLoaded()
} else {
StartProgress();
}
StartTimeUpdate();
}
void
@ -1552,6 +1553,7 @@ nsWaveDecoder::Shutdown()
return;
mShuttingDown = PR_TRUE;
StopTimeUpdate();
nsMediaDecoder::Shutdown();
@ -1678,7 +1680,7 @@ nsWaveDecoder::PlaybackPositionChanged()
if (mElement && lastTime != mCurrentTime) {
UpdateReadyStateForData();
mElement->DispatchEvent(NS_LITERAL_STRING("timeupdate"));
FireTimeUpdate();
}
}