From baa4f9165342ccea5f4b0e8fdd994f9c00fc7d4b Mon Sep 17 00:00:00 2001 From: JW Wang Date: Sun, 10 May 2015 12:07:14 +0800 Subject: [PATCH] Bug 1163489 - Remove dependency on MediaDecoder from DecodedStream. r=roc. --- dom/media/DecodedStream.cpp | 62 +++++++++++++++++++++---------------- dom/media/DecodedStream.h | 15 ++++----- dom/media/MediaDecoder.cpp | 5 +-- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp index 2a976c7730e..891361345f9 100644 --- a/dom/media/DecodedStream.cpp +++ b/dom/media/DecodedStream.cpp @@ -6,16 +6,15 @@ #include "DecodedStream.h" #include "MediaStreamGraph.h" -#include "MediaDecoder.h" +#include "mozilla/ReentrantMonitor.h" namespace mozilla { class DecodedStreamGraphListener : public MediaStreamListener { typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent; public: - DecodedStreamGraphListener(MediaStream* aStream, DecodedStreamData* aData) - : mData(aData) - , mMutex("DecodedStreamGraphListener::mMutex") + explicit DecodedStreamGraphListener(MediaStream* aStream) + : mMutex("DecodedStreamGraphListener::mMutex") , mStream(aStream) , mLastOutputTime(aStream->StreamTimeToMicroseconds(aStream->GetCurrentTime())) , mStreamFinishedOnMainThread(false) {} @@ -52,7 +51,6 @@ public: void Forget() { MOZ_ASSERT(NS_IsMainThread()); - mData = nullptr; MutexAutoLock lock(mMutex); mStream = nullptr; } @@ -64,9 +62,6 @@ public: } private: - // Main thread only - DecodedStreamData* mData; - Mutex mMutex; // Members below are protected by mMutex. nsRefPtr mStream; @@ -74,14 +69,12 @@ private: bool mStreamFinishedOnMainThread; }; -DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder, - int64_t aInitialTime, +DecodedStreamData::DecodedStreamData(int64_t aInitialTime, SourceMediaStream* aStream) : mAudioFramesWritten(0) , mInitialTime(aInitialTime) , mNextVideoTime(-1) , mNextAudioTime(-1) - , mDecoder(aDecoder) , mStreamInitialized(false) , mHaveSentFinish(false) , mHaveSentFinishAudio(false) @@ -91,7 +84,7 @@ DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder, , mHaveBlockedForStateMachineNotPlaying(false) , mEOSVideoCompensation(false) { - mListener = new DecodedStreamGraphListener(mStream, this); + mListener = new DecodedStreamGraphListener(mStream); mStream->AddListener(mListener); } @@ -116,8 +109,8 @@ DecodedStreamData::GetClock() const class OutputStreamListener : public MediaStreamListener { typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent; public: - OutputStreamListener(MediaDecoder* aDecoder, MediaStream* aStream) - : mDecoder(aDecoder), mStream(aStream) {} + OutputStreamListener(DecodedStream* aDecodedStream, MediaStream* aStream) + : mDecodedStream(aDecodedStream), mStream(aStream) {} void NotifyEvent(MediaStreamGraph* aGraph, MediaStreamGraphEvent event) override { @@ -131,22 +124,22 @@ public: void Forget() { MOZ_ASSERT(NS_IsMainThread()); - mDecoder = nullptr; + mDecodedStream = nullptr; } private: void DoNotifyFinished() { MOZ_ASSERT(NS_IsMainThread()); - if (!mDecoder) { + if (!mDecodedStream) { return; } // Remove the finished stream so it won't block the decoded stream. - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - auto& streams = mDecoder->OutputStreams(); - // Don't read |mDecoder| in the loop since removing the element will lead - // to ~OutputStreamData() which will call Forget() to reset |mDecoder|. + ReentrantMonitorAutoEnter mon(mDecodedStream->GetReentrantMonitor()); + auto& streams = mDecodedStream->OutputStreams(); + // Don't read |mDecodedStream| in the loop since removing the element will lead + // to ~OutputStreamData() which will call Forget() to reset |mDecodedStream|. for (int32_t i = streams.Length() - 1; i >= 0; --i) { auto& os = streams[i]; MediaStream* p = os.mStream.get(); @@ -162,7 +155,7 @@ private: } // Main thread only - MediaDecoder* mDecoder; + DecodedStream* mDecodedStream; nsRefPtr mStream; }; @@ -177,37 +170,54 @@ OutputStreamData::~OutputStreamData() } void -OutputStreamData::Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream) +OutputStreamData::Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStream) { mStream = aStream; - mListener = new OutputStreamListener(aDecoder, aStream); + mListener = new OutputStreamListener(aDecodedStream, aStream); aStream->AddListener(mListener); } +DecodedStream::DecodedStream(ReentrantMonitor& aMonitor) + : mMonitor(aMonitor) +{ + // +} + DecodedStreamData* DecodedStream::GetData() { + GetReentrantMonitor().AssertCurrentThreadIn(); return mData.get(); } void DecodedStream::DestroyData() { + MOZ_ASSERT(NS_IsMainThread()); + GetReentrantMonitor().AssertCurrentThreadIn(); mData = nullptr; } void -DecodedStream::RecreateData(MediaDecoder* aDecoder, int64_t aInitialTime, - SourceMediaStream* aStream) +DecodedStream::RecreateData(int64_t aInitialTime, SourceMediaStream* aStream) { + MOZ_ASSERT(NS_IsMainThread()); + GetReentrantMonitor().AssertCurrentThreadIn(); MOZ_ASSERT(!mData); - mData.reset(new DecodedStreamData(aDecoder, aInitialTime, aStream)); + mData.reset(new DecodedStreamData(aInitialTime, aStream)); } nsTArray& DecodedStream::OutputStreams() { + GetReentrantMonitor().AssertCurrentThreadIn(); return mOutputStreams; } +ReentrantMonitor& +DecodedStream::GetReentrantMonitor() +{ + return mMonitor; +} + } // namespace mozilla diff --git a/dom/media/DecodedStream.h b/dom/media/DecodedStream.h index 74dd93c89f7..f6ce4503ba8 100644 --- a/dom/media/DecodedStream.h +++ b/dom/media/DecodedStream.h @@ -14,13 +14,14 @@ namespace mozilla { -class MediaDecoder; class MediaInputPort; class SourceMediaStream; class ProcessedMediaStream; +class DecodedStream; class DecodedStreamGraphListener; class OutputStreamData; class OutputStreamListener; +class ReentrantMonitor; namespace layers { class Image; @@ -36,8 +37,7 @@ class Image; */ class DecodedStreamData { public: - DecodedStreamData(MediaDecoder* aDecoder, int64_t aInitialTime, - SourceMediaStream* aStream); + DecodedStreamData(int64_t aInitialTime, SourceMediaStream* aStream); ~DecodedStreamData(); bool IsFinished() const; int64_t GetClock() const; @@ -55,7 +55,6 @@ public: // to the output stream. int64_t mNextVideoTime; // microseconds int64_t mNextAudioTime; // microseconds - MediaDecoder* mDecoder; // The last video image sent to the stream. Useful if we need to replicate // the image. nsRefPtr mLastVideoImage; @@ -89,7 +88,7 @@ public: // to work. OutputStreamData(); ~OutputStreamData(); - void Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream); + void Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStream); nsRefPtr mStream; // mPort connects DecodedStreamData::mStream to our mStream. nsRefPtr mPort; @@ -98,16 +97,18 @@ public: class DecodedStream { public: + explicit DecodedStream(ReentrantMonitor& aMonitor); DecodedStreamData* GetData(); void DestroyData(); - void RecreateData(MediaDecoder* aDecoder, int64_t aInitialTime, - SourceMediaStream* aStream); + void RecreateData(int64_t aInitialTime, SourceMediaStream* aStream); nsTArray& OutputStreams(); + ReentrantMonitor& GetReentrantMonitor(); private: UniquePtr mData; // Data about MediaStreams that are being fed by the decoder. nsTArray mOutputStreams; + ReentrantMonitor& mMonitor; }; } // namespace mozilla diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 041417ba2c6..3d05d8ab528 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -384,7 +384,7 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs, } DestroyDecodedStream(); - mDecodedStream.RecreateData(this, aStartTimeUSecs, aGraph->CreateSourceStream(nullptr)); + mDecodedStream.RecreateData(aStartTimeUSecs, aGraph->CreateSourceStream(nullptr)); // Note that the delay between removing ports in DestroyDecodedStream // and adding new ones won't cause a glitch since all graph operations @@ -419,7 +419,7 @@ void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream, RecreateDecodedStream(mLogicalPosition, aStream->Graph()); } OutputStreamData* os = OutputStreams().AppendElement(); - os->Init(this, aStream); + os->Init(&mDecodedStream, aStream); ConnectDecodedStreamToOutputStream(os); if (aFinishWhenEnded) { // Ensure that aStream finishes the moment mDecodedStream does. @@ -483,6 +483,7 @@ MediaDecoder::MediaDecoder() : mMediaSeekable(true), mSameOriginMedia(false), mReentrantMonitor("media.decoder"), + mDecodedStream(mReentrantMonitor), mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING, "MediaDecoder::mPlayState (Canonical)"), mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,