Bug 493443. Set readyState to HAVE_CURRENT_DATA whenever the Ogg frame queue is empty or we're buffering/seeking, instead of trying to hardcode it based on other events like PlaybackEnded. r=doublec

--HG--
extra : rebase_source : 0b2f938e5f19cbb21258248da9da09e2a525db81
This commit is contained in:
Robert O'Callahan 2009-05-19 10:44:17 +12:00
parent 9d32e37a42
commit 08a4384325
3 changed files with 33 additions and 17 deletions

View File

@ -1276,7 +1276,6 @@ void nsHTMLMediaElement::NetworkError()
void nsHTMLMediaElement::PlaybackEnded()
{
NS_ASSERTION(mDecoder->IsEnded(), "Decoder fired ended, but not in ended state");
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("ended"));
}
@ -1336,9 +1335,7 @@ void nsHTMLMediaElement::UpdateReadyStateForData(NextFrameStatus aNextFrame)
nsMediaDecoder::Statistics stats = mDecoder->GetStatistics();
if (aNextFrame != NEXT_FRAME_AVAILABLE &&
!mDecoder->IsEnded() &&
stats.mDownloadPosition < stats.mTotalBytes) {
if (aNextFrame != NEXT_FRAME_AVAILABLE) {
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
if (!mWaitingFired && aNextFrame == NEXT_FRAME_UNAVAILABLE_BUFFERING) {
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("waiting"));

View File

@ -347,9 +347,17 @@ public:
// Must be called with the decode monitor held. Can be called by main
// thread.
PRBool IsBuffering() const {
PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mDecoder->GetMonitor());
return mState == nsOggDecodeStateMachine::DECODER_STATE_BUFFERING;
}
// Must be called with the decode monitor held. Can be called by main
// thread.
PRBool IsSeeking() const {
PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mDecoder->GetMonitor());
return mState == nsOggDecodeStateMachine::DECODER_STATE_SEEKING;
}
protected:
// Convert the OggPlay frame information into a format used by Gecko
// (RGB for video, float for sound, etc).The decoder monitor must be
@ -1288,6 +1296,14 @@ nsresult nsOggDecodeStateMachine::Run()
mStepDecodeThread = nsnull;
}
// Remove all frames decoded prior to seek from the queue
while (!mDecodedFrames.IsEmpty()) {
delete mDecodedFrames.Pop();
}
// SeekingStarted will do a UpdateReadyStateForData which will
// inform the element and its users that we have no frames
// to display
mon.Exit();
nsCOMPtr<nsIRunnable> startEvent =
NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStarted);
@ -1312,11 +1328,6 @@ nsresult nsOggDecodeStateMachine::Run()
if (mState == DECODER_STATE_SHUTDOWN)
continue;
// Remove all frames decoded prior to seek from the queue
while (!mDecodedFrames.IsEmpty()) {
delete mDecodedFrames.Pop();
}
OggPlayErrorCode r;
do {
mon.Exit();
@ -1428,12 +1439,15 @@ nsresult nsOggDecodeStateMachine::Run()
continue;
}
mon.Exit();
nsCOMPtr<nsIRunnable> event =
NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, PlaybackEnded);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
do {
NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
mon.Enter();
while (mState == DECODER_STATE_COMPLETED) {
mon.Wait();
} while (mState == DECODER_STATE_COMPLETED);
}
}
break;
}
@ -1935,6 +1949,7 @@ void nsOggDecoder::PlaybackEnded()
ChangeState(PLAY_STATE_ENDED);
if (mElement) {
UpdateReadyStateForData();
mElement->PlaybackEnded();
}
}
@ -2057,10 +2072,11 @@ void nsOggDecoder::UpdateReadyStateForData()
nsHTMLMediaElement::NextFrameStatus frameStatus;
{
nsAutoMonitor mon(mMonitor);
if (mDecodeStateMachine->HaveNextFrameData()) {
frameStatus = nsHTMLMediaElement::NEXT_FRAME_AVAILABLE;
} else if (mDecodeStateMachine->IsBuffering()) {
if (mDecodeStateMachine->IsBuffering() ||
mDecodeStateMachine->IsSeeking()) {
frameStatus = nsHTMLMediaElement::NEXT_FRAME_UNAVAILABLE_BUFFERING;
} else if (mDecodeStateMachine->HaveNextFrameData()) {
frameStatus = nsHTMLMediaElement::NEXT_FRAME_AVAILABLE;
} else {
frameStatus = nsHTMLMediaElement::NEXT_FRAME_UNAVAILABLE;
}
@ -2085,8 +2101,8 @@ void nsOggDecoder::SeekingStopped()
}
if (mElement) {
mElement->SeekCompleted();
UpdateReadyStateForData();
mElement->SeekCompleted();
}
}
@ -2096,6 +2112,7 @@ void nsOggDecoder::SeekingStarted()
return;
if (mElement) {
UpdateReadyStateForData();
mElement->SeekStarted();
}
}

View File

@ -1513,6 +1513,7 @@ nsWaveDecoder::SeekingStarted()
}
if (mElement) {
UpdateReadyStateForData();
mElement->SeekStarted();
}
}
@ -1525,8 +1526,8 @@ nsWaveDecoder::SeekingStopped()
}
if (mElement) {
mElement->SeekCompleted();
UpdateReadyStateForData();
mElement->SeekCompleted();
}
}
@ -1589,6 +1590,7 @@ nsWaveDecoder::PlaybackPositionChanged()
}
if (mElement && lastTime != mCurrentTime) {
UpdateReadyStateForData();
mElement->DispatchSimpleEvent(NS_LITERAL_STRING("timeupdate"));
}
}