From 3ae2cca96e53add7759c30a760af72c36c01f31d Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Fri, 1 Aug 2014 16:04:37 +1200 Subject: [PATCH] Bug 1047188 - Ensure we only call MediaDataDecoder::Drain() once, and break out of MP4Reader::Decode() when DrainComplete() is called. r=kentuckyfriedtakahe --- content/media/fmp4/MP4Reader.cpp | 29 ++++++++++++++++++++++------- content/media/fmp4/MP4Reader.h | 4 ++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/content/media/fmp4/MP4Reader.cpp b/content/media/fmp4/MP4Reader.cpp index 44abde0e38de..27f837acdc47 100644 --- a/content/media/fmp4/MP4Reader.cpp +++ b/content/media/fmp4/MP4Reader.cpp @@ -463,7 +463,8 @@ MP4Reader::Decode(TrackType aTrack) // if we need output. while (prevNumFramesOutput == data.mNumSamplesOutput && (data.mInputExhausted || - (data.mNumSamplesInput - data.mNumSamplesOutput) < data.mDecodeAhead)) { + (data.mNumSamplesInput - data.mNumSamplesOutput) < data.mDecodeAhead) && + !data.mEOS) { data.mMonitor.AssertCurrentThreadOwns(); data.mMonitor.Unlock(); nsAutoPtr compressed(PopSample(aTrack)); @@ -471,6 +472,9 @@ MP4Reader::Decode(TrackType aTrack) // EOS, or error. Send the decoder a signal to drain. LOG("Draining %s", TrackTypeToStr(aTrack)); data.mMonitor.Lock(); + MOZ_ASSERT(!data.mEOS); + data.mEOS = true; + MOZ_ASSERT(!data.mDrainComplete); data.mDrainComplete = false; data.mMonitor.Unlock(); data.mDecoder->Drain(); @@ -498,15 +502,27 @@ MP4Reader::Decode(TrackType aTrack) data.mMonitor.AssertCurrentThreadOwns(); while (!data.mError && prevNumFramesOutput == data.mNumSamplesOutput && - !data.mInputExhausted && + (!data.mInputExhausted || data.mEOS) && !data.mDrainComplete) { data.mMonitor.Wait(); } + if (data.mError || + (data.mEOS && data.mDrainComplete)) { + break; + } } data.mMonitor.AssertCurrentThreadOwns(); - bool drainComplete = data.mDrainComplete; + bool rv = !(data.mEOS || data.mError); data.mMonitor.Unlock(); - return !drainComplete; + return rv; +} + +nsresult +MP4Reader::ResetDecode() +{ + Flush(kAudio); + Flush(kVideo); + return MediaDecoderReader::ResetDecode(); } void @@ -591,6 +607,8 @@ MP4Reader::Flush(TrackType aTrack) { MonitorAutoLock mon(data.mMonitor); data.mIsFlushing = true; + data.mDrainComplete = false; + data.mEOS = false; } data.mDecoder->Flush(); { @@ -668,9 +686,6 @@ MP4Reader::Seek(int64_t aTime, if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) { return NS_ERROR_FAILURE; } - Flush(kVideo); - Flush(kAudio); - ResetDecode(); mQueuedVideoSample = nullptr; if (mDemuxer->HasValidVideo()) { diff --git a/content/media/fmp4/MP4Reader.h b/content/media/fmp4/MP4Reader.h index 60f75ff60ac8..d8270efa2bee 100644 --- a/content/media/fmp4/MP4Reader.h +++ b/content/media/fmp4/MP4Reader.h @@ -58,6 +58,8 @@ public: virtual bool IsWaitingMediaResources() MOZ_OVERRIDE; + virtual nsresult ResetDecode() MOZ_OVERRIDE; + private: void ExtractCryptoInitData(nsTArray& aInitData); @@ -121,6 +123,7 @@ private: , mError(false) , mIsFlushing(false) , mDrainComplete(false) + , mEOS(false) { } @@ -143,6 +146,7 @@ private: bool mError; bool mIsFlushing; bool mDrainComplete; + bool mEOS; }; DecoderData mAudio; DecoderData mVideo;