From 7e6bd938008f7b5a60a227fb7444674bc5e2627c Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 25 Sep 2008 16:26:45 +1200 Subject: [PATCH] Bug 449159 - Part 2 of Ogg backend seeking implementation - s+sr=roc --- .../html/content/src/nsHTMLMediaElement.cpp | 1 + content/media/video/src/nsOggDecoder.cpp | 36 +++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index bb54ab42b09d..7f267442e78f 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -662,6 +662,7 @@ void nsHTMLMediaElement::PlaybackEnded() { mBegun = PR_FALSE; mEnded = PR_TRUE; + mPaused = PR_TRUE; SetCurrentTime(0); DispatchSimpleEvent(NS_LITERAL_STRING("ended")); } diff --git a/content/media/video/src/nsOggDecoder.cpp b/content/media/video/src/nsOggDecoder.cpp index 7df938306833..02e3a2f1f2d7 100644 --- a/content/media/video/src/nsOggDecoder.cpp +++ b/content/media/video/src/nsOggDecoder.cpp @@ -307,8 +307,8 @@ public: float DisplayFrame(OggPlayCallbackInfo** aFrame, nsAudioStream* aAudioStream); // Decode and display the initial frame after the oggplay buffers - // have been cleared (during a seek for example).The decode monitor - // must be obtained before calling. + // have been cleared (during a seek for example). The decode monitor + // is obtained internally by this method for synchronisation. float DisplayInitialFrame(); protected: @@ -444,9 +444,10 @@ float nsOggDecodeStateMachine::DisplayFrame(OggPlayCallbackInfo** aFrame, nsAudi float nsOggDecodeStateMachine::DisplayInitialFrame() { - // NS_ASSERTION(PR_InMonitor(mDecoder->GetMonitor()), "DisplayInitialFrame() called without acquiring decoder monitor"); + nsAutoMonitor mon(mDecoder->GetMonitor()); float time = 0.0; OggPlayCallbackInfo **frame = NextFrame(); + mon.Exit(); while (!frame) { OggPlayErrorCode r = DecodeFrame(); if (r != E_OGGPLAY_CONTINUE && @@ -454,13 +455,21 @@ float nsOggDecodeStateMachine::DisplayInitialFrame() r != E_OGGPLAY_TIMEOUT) { break; } + mon.Enter(); + if (mState == DECODER_STATE_SHUTDOWN) + return 0.0; mBufferFull = (r == E_OGGPLAY_USER_INTERRUPT); frame = NextFrame(); + mon.Exit(); } - + mon.Enter(); if (frame) { - time = DisplayFrame(frame, nsnull); + if (mState != DECODER_STATE_SHUTDOWN) { + // If shutting down, don't display the frame as this can + // cause events to be posted. + time = DisplayFrame(frame, nsnull); + } ReleaseFrame(frame); mBufferFull = PR_FALSE; } @@ -511,6 +520,9 @@ float nsOggDecodeStateMachine::DisplayTrack(int aTrackNumber, OggPlayCallbackInf } void nsOggDecodeStateMachine::HandleVideoData(int aTrackNum, OggPlayVideoData* aVideoData) { + if (!aVideoData) + return; + CopyVideoFrame(aTrackNum, aVideoData, mFramerate); nsCOMPtr event = @@ -704,9 +716,19 @@ nsresult nsOggDecodeStateMachine::Run() continue; } - mDecoder->mDisplayStateMachine->UpdateFrameTime(DisplayInitialFrame()); + mBufferFull = PR_FALSE; + mon.Exit(); - + float time = DisplayInitialFrame(); + mon.Enter(); + + if (mState == DECODER_STATE_SHUTDOWN) { + continue; + } + + mDecoder->mDisplayStateMachine->UpdateFrameTime(time); + mon.Exit(); + nsCOMPtr stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped); NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);