diff --git a/dom/media/MediaDecoderReader.cpp b/dom/media/MediaDecoderReader.cpp index 26698623d5b5..44ca2d92278d 100644 --- a/dom/media/MediaDecoderReader.cpp +++ b/dom/media/MediaDecoderReader.cpp @@ -283,28 +283,18 @@ MediaDecoderReader::BreakCycles() mTaskQueue = nullptr; } -nsRefPtr +void MediaDecoderReader::Shutdown() { MOZ_ASSERT(OnDecodeThread()); mShutdown = true; ReleaseMediaResources(); - nsRefPtr p; - - // Spin down the task queue if necessary. We wait until BreakCycles to null - // out mTaskQueue, since otherwise any remaining tasks could crash when they - // invoke GetTaskQueue()->IsCurrentThreadIn(). if (mTaskQueue && !mTaskQueueIsBorrowed) { - // If we own our task queue, shutdown ends when the task queue is done. - p = mTaskQueue->BeginShutdown(); - } else { - // If we don't own our task queue, we resolve immediately (though - // asynchronously). - p = new ShutdownPromise(__func__); - p->Resolve(true, __func__); + // We may be running in the task queue ourselves, so we don't block this + // thread on task queue draining, since that would deadlock. + mTaskQueue->BeginShutdown(); } - - return p; + mTaskQueue = nullptr; } AudioDecodeRendezvous::AudioDecodeRendezvous() diff --git a/dom/media/MediaDecoderReader.h b/dom/media/MediaDecoderReader.h index eaee9c0c33a3..508ee8fa8bd7 100644 --- a/dom/media/MediaDecoderReader.h +++ b/dom/media/MediaDecoderReader.h @@ -65,7 +65,7 @@ public: // This is different from ReleaseMediaResources() as it is irreversable, // whereas ReleaseMediaResources() is. Must be called on the decode // thread. - virtual nsRefPtr Shutdown(); + virtual void Shutdown(); virtual void SetCallback(RequestSampleCallback* aDecodedSampleCallback); MediaTaskQueue* EnsureTaskQueue(); diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 9f899eb2215d..798f0860ba38 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -2470,53 +2470,6 @@ private: nsRefPtr mStateMachine; }; -void -MediaDecoderStateMachine::ShutdownReader() -{ - MOZ_ASSERT(OnDecodeThread()); - mReader->Shutdown()->Then(GetStateMachineThread(), __func__, this, - &MediaDecoderStateMachine::FinishShutdown, - &MediaDecoderStateMachine::FinishShutdown); -} - -void -MediaDecoderStateMachine::FinishShutdown(bool aSuccess) -{ - MOZ_ASSERT(OnStateMachineThread()); - MOZ_ASSERT(aSuccess); - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - - // The reader's listeners hold references to the state machine, - // creating a cycle which keeps the state machine and its shared - // thread pools alive. So break it here. - AudioQueue().ClearListeners(); - VideoQueue().ClearListeners(); - - // Now that those threads are stopped, there's no possibility of - // mPendingWakeDecoder being needed again. Revoke it. - mPendingWakeDecoder = nullptr; - - MOZ_ASSERT(mState == DECODER_STATE_SHUTDOWN, - "How did we escape from the shutdown state?"); - // We must daisy-chain these events to destroy the decoder. We must - // destroy the decoder on the main thread, but we can't destroy the - // decoder while this thread holds the decoder monitor. We can't - // dispatch an event to the main thread to destroy the decoder from - // here, as the event may run before the dispatch returns, and we - // hold the decoder monitor here. We also want to guarantee that the - // state machine is destroyed on the main thread, and so the - // event runner running this function (which holds a reference to the - // state machine) needs to finish and be released in order to allow - // that. So we dispatch an event to run after this event runner has - // finished and released its monitor/references. That event then will - // dispatch an event to the main thread to release the decoder and - // state machine. - GetStateMachineThread()->Dispatch( - new nsDispatchDisposeEvent(mDecoder, this), NS_DISPATCH_NORMAL); - - DECODER_LOG("Dispose Event Dispatched"); -} - nsresult MediaDecoderStateMachine::RunStateMachine() { AssertCurrentThreadInMonitor(); @@ -2533,14 +2486,47 @@ nsresult MediaDecoderStateMachine::RunStateMachine() StopAudioThread(); FlushDecoding(); - // Put a task in the decode queue to shutdown the reader. + // Put a task in the decode queue to shutdown the reader and wait for // the queue to spin down. - RefPtr task; - task = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::ShutdownReader); - DebugOnly rv = DecodeTaskQueue()->Dispatch(task); - MOZ_ASSERT(NS_SUCCEEDED(rv)); + { + RefPtr task; + task = NS_NewRunnableMethod(mReader, &MediaDecoderReader::Shutdown); + nsRefPtr queue = DecodeTaskQueue(); + DebugOnly rv = queue->Dispatch(task); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor()); + queue->AwaitShutdownAndIdle(); + } - DECODER_LOG("Shutdown started"); + // The reader's listeners hold references to the state machine, + // creating a cycle which keeps the state machine and its shared + // thread pools alive. So break it here. + AudioQueue().ClearListeners(); + VideoQueue().ClearListeners(); + + // Now that those threads are stopped, there's no possibility of + // mPendingWakeDecoder being needed again. Revoke it. + mPendingWakeDecoder = nullptr; + + MOZ_ASSERT(mState == DECODER_STATE_SHUTDOWN, + "How did we escape from the shutdown state?"); + // We must daisy-chain these events to destroy the decoder. We must + // destroy the decoder on the main thread, but we can't destroy the + // decoder while this thread holds the decoder monitor. We can't + // dispatch an event to the main thread to destroy the decoder from + // here, as the event may run before the dispatch returns, and we + // hold the decoder monitor here. We also want to guarantee that the + // state machine is destroyed on the main thread, and so the + // event runner running this function (which holds a reference to the + // state machine) needs to finish and be released in order to allow + // that. So we dispatch an event to run after this event runner has + // finished and released its monitor/references. That event then will + // dispatch an event to the main thread to release the decoder and + // state machine. + GetStateMachineThread()->Dispatch( + new nsDispatchDisposeEvent(mDecoder, this), NS_DISPATCH_NORMAL); + + DECODER_LOG("SHUTDOWN OK"); return NS_OK; } diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index d99195c703ad..dfcbf5734a44 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -162,8 +162,6 @@ public: // Set/Unset dormant state. void SetDormant(bool aDormant); void Shutdown(); - void ShutdownReader(); - void FinishShutdown(bool aSuccess); // Called from the main thread to get the duration. The decoder monitor // must be obtained before calling this. It is in units of microseconds. diff --git a/dom/media/MediaTaskQueue.cpp b/dom/media/MediaTaskQueue.cpp index 782356121386..7afd582da4ac 100644 --- a/dom/media/MediaTaskQueue.cpp +++ b/dom/media/MediaTaskQueue.cpp @@ -134,17 +134,12 @@ MediaTaskQueue::AwaitShutdownAndIdle() AwaitIdleLocked(); } -nsRefPtr +void MediaTaskQueue::BeginShutdown() { MonitorAutoLock mon(mQueueMonitor); mIsShutdown = true; - nsRefPtr p = mShutdownPromise.Ensure(__func__); - if (!mIsRunning) { - mShutdownPromise.Resolve(true, __func__); - } mon.NotifyAll(); - return p; } nsresult @@ -213,7 +208,6 @@ MediaTaskQueue::Runner::Run() mQueue->mRunningThread = NS_GetCurrentThread(); if (mQueue->mTasks.size() == 0) { mQueue->mIsRunning = false; - mQueue->mShutdownPromise.ResolveIfExists(true, __func__); mon.NotifyAll(); return NS_OK; } @@ -241,7 +235,6 @@ MediaTaskQueue::Runner::Run() if (mQueue->mTasks.size() == 0) { // No more events to run. Exit the task runner. mQueue->mIsRunning = false; - mQueue->mShutdownPromise.ResolveIfExists(true, __func__); mon.NotifyAll(); mQueue->mRunningThread = nullptr; return NS_OK; diff --git a/dom/media/MediaTaskQueue.h b/dom/media/MediaTaskQueue.h index ce3827b52cfe..1027ed56ef1f 100644 --- a/dom/media/MediaTaskQueue.h +++ b/dom/media/MediaTaskQueue.h @@ -12,7 +12,6 @@ #include "mozilla/Monitor.h" #include "SharedThreadPool.h" #include "nsThreadUtils.h" -#include "MediaPromise.h" class nsIRunnable; @@ -20,8 +19,6 @@ namespace mozilla { class SharedThreadPool; -typedef MediaPromise ShutdownPromise; - // Abstracts executing runnables in order in a thread pool. The runnables // dispatched to the MediaTaskQueue will be executed in the order in which // they're received, and are guaranteed to not be executed concurrently. @@ -53,9 +50,7 @@ public: // remain alive at least until all the events are drained, because the Runners // hold a strong reference to the task queue, and one of them is always held // by the threadpool event queue when the task queue is non-empty. - // - // The returned promise is resolved when the queue goes empty. - nsRefPtr BeginShutdown(); + void BeginShutdown(); // Blocks until all task finish executing. void AwaitIdle(); @@ -110,7 +105,6 @@ private: // True if we've started our shutdown process. bool mIsShutdown; - MediaPromiseHolder mShutdownPromise; class MOZ_STACK_CLASS AutoSetFlushing { diff --git a/dom/media/android/AndroidMediaReader.cpp b/dom/media/android/AndroidMediaReader.cpp index cf8c463f1ad2..bd2d32ca8f2f 100644 --- a/dom/media/android/AndroidMediaReader.cpp +++ b/dom/media/android/AndroidMediaReader.cpp @@ -99,8 +99,7 @@ nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo, return NS_OK; } -nsRefPtr -AndroidMediaReader::Shutdown() +void AndroidMediaReader::Shutdown() { ResetDecode(); if (mPlugin) { @@ -108,7 +107,7 @@ AndroidMediaReader::Shutdown() mPlugin = nullptr; } - return MediaDecoderReader::Shutdown(); + MediaDecoderReader::Shutdown(); } // Resets all state related to decoding, emptying all buffers etc. diff --git a/dom/media/android/AndroidMediaReader.h b/dom/media/android/AndroidMediaReader.h index 4738cfa7b6a0..90c4c929abe4 100644 --- a/dom/media/android/AndroidMediaReader.h +++ b/dom/media/android/AndroidMediaReader.h @@ -71,7 +71,7 @@ public: MetadataTags** aTags); virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime); - virtual nsRefPtr Shutdown() MOZ_OVERRIDE; + virtual void Shutdown() MOZ_OVERRIDE; class ImageBufferCallback : public MPAPI::BufferCallback { typedef mozilla::layers::Image Image; diff --git a/dom/media/fmp4/MP4Reader.cpp b/dom/media/fmp4/MP4Reader.cpp index b54a8b80ebac..0482ae5400ac 100644 --- a/dom/media/fmp4/MP4Reader.cpp +++ b/dom/media/fmp4/MP4Reader.cpp @@ -139,7 +139,7 @@ MP4Reader::~MP4Reader() MOZ_COUNT_DTOR(MP4Reader); } -nsRefPtr +void MP4Reader::Shutdown() { MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn()); @@ -172,7 +172,7 @@ MP4Reader::Shutdown() mPlatform = nullptr; } - return MediaDecoderReader::Shutdown(); + MediaDecoderReader::Shutdown(); } void diff --git a/dom/media/fmp4/MP4Reader.h b/dom/media/fmp4/MP4Reader.h index bead54a72c50..0c425a98fad4 100644 --- a/dom/media/fmp4/MP4Reader.h +++ b/dom/media/fmp4/MP4Reader.h @@ -71,7 +71,7 @@ public: virtual nsresult ResetDecode() MOZ_OVERRIDE; - virtual nsRefPtr Shutdown() MOZ_OVERRIDE; + virtual void Shutdown() MOZ_OVERRIDE; private: diff --git a/dom/media/mediasource/MediaSourceDecoder.h b/dom/media/mediasource/MediaSourceDecoder.h index efb61a0caef6..4d1f724e470c 100644 --- a/dom/media/mediasource/MediaSourceDecoder.h +++ b/dom/media/mediasource/MediaSourceDecoder.h @@ -11,7 +11,6 @@ #include "nsCOMPtr.h" #include "nsError.h" #include "MediaDecoder.h" -#include "MediaSourceReader.h" class nsIStreamListener; @@ -19,6 +18,7 @@ namespace mozilla { class MediaResource; class MediaDecoderStateMachine; +class MediaSourceReader; class SourceBufferDecoder; class TrackBuffer; @@ -71,8 +71,6 @@ public: virtual nsresult SetCDMProxy(CDMProxy* aProxy) MOZ_OVERRIDE; #endif - MediaSourceReader* GetReader() { return mReader; } - private: // The owning MediaSource holds a strong reference to this decoder, and // calls Attach/DetachMediaSource on this decoder to set and clear diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 269794a840ea..d6770e640e4b 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -236,35 +236,17 @@ MediaSourceReader::OnNotDecoded(MediaData::Type aType, NotDecodedReason aReason) GetCallback()->OnNotDecoded(aType, WAITING_FOR_DATA); } -nsRefPtr +void MediaSourceReader::Shutdown() { - MOZ_ASSERT(mMediaSourceShutdownPromise.IsEmpty()); - nsRefPtr p = mMediaSourceShutdownPromise.Ensure(__func__); - - ContinueShutdown(true); - return p; -} - -void -MediaSourceReader::ContinueShutdown(bool aSuccess) -{ - MOZ_ASSERT(aSuccess); - if (mTrackBuffers.Length()) { - mTrackBuffers[0]->Shutdown()->Then(GetTaskQueue(), __func__, this, - &MediaSourceReader::ContinueShutdown, - &MediaSourceReader::ContinueShutdown); - mShutdownTrackBuffers.AppendElement(mTrackBuffers[0]); - mTrackBuffers.RemoveElementAt(0); - return; + MediaDecoderReader::Shutdown(); + for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) { + mTrackBuffers[i]->Shutdown(); } - mAudioTrack = nullptr; mAudioReader = nullptr; mVideoTrack = nullptr; mVideoReader = nullptr; - - MediaDecoderReader::Shutdown()->ChainTo(mMediaSourceShutdownPromise.Steal(), __func__); } void @@ -277,12 +259,11 @@ MediaSourceReader::BreakCycles() MOZ_ASSERT(!mAudioReader); MOZ_ASSERT(!mVideoTrack); MOZ_ASSERT(!mVideoReader); - MOZ_ASSERT(!mTrackBuffers.Length()); - for (uint32_t i = 0; i < mShutdownTrackBuffers.Length(); ++i) { - mShutdownTrackBuffers[i]->BreakCycles(); + for (uint32_t i = 0; i < mTrackBuffers.Length(); ++i) { + mTrackBuffers[i]->BreakCycles(); } - mShutdownTrackBuffers.Clear(); + mTrackBuffers.Clear(); } already_AddRefed diff --git a/dom/media/mediasource/MediaSourceReader.h b/dom/media/mediasource/MediaSourceReader.h index eabc1e93c7a8..fdeb09b21d36 100644 --- a/dom/media/mediasource/MediaSourceReader.h +++ b/dom/media/mediasource/MediaSourceReader.h @@ -97,7 +97,7 @@ public: void RemoveTrackBuffer(TrackBuffer* aTrackBuffer); void OnTrackBufferConfigured(TrackBuffer* aTrackBuffer, const MediaInfo& aInfo); - nsRefPtr Shutdown() MOZ_OVERRIDE; + void Shutdown(); virtual void BreakCycles(); @@ -135,7 +135,6 @@ private: nsRefPtr mVideoReader; nsTArray> mTrackBuffers; - nsTArray> mShutdownTrackBuffers; nsTArray> mEssentialTrackBuffers; nsRefPtr mAudioTrack; nsRefPtr mVideoTrack; @@ -177,9 +176,6 @@ private: bool mVideoIsSeeking; bool mHasEssentialTrackBuffers; - - void ContinueShutdown(bool aSuccess); - MediaPromiseHolder mMediaSourceShutdownPromise; #ifdef MOZ_FMP4 nsRefPtr mSharedDecoderManager; #endif diff --git a/dom/media/mediasource/TrackBuffer.cpp b/dom/media/mediasource/TrackBuffer.cpp index 73a4030e1f9d..e19dcea290e6 100644 --- a/dom/media/mediasource/TrackBuffer.cpp +++ b/dom/media/mediasource/TrackBuffer.cpp @@ -96,39 +96,23 @@ private: nsAutoTArray,2> mDecoders; }; -nsRefPtr +void TrackBuffer::Shutdown() { - MOZ_ASSERT(mShutdownPromise.IsEmpty()); - nsRefPtr p = mShutdownPromise.Ensure(__func__); - - RefPtr queue = mTaskQueue; + // Finish any decoder initialization, which may add to mInitializedDecoders. + // Shutdown waits for any pending events, which may require the monitor, + // so we must not hold the monitor during this call. + mParentDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn(); + mTaskQueue->BeginShutdown(); + mTaskQueue->AwaitShutdownAndIdle(); mTaskQueue = nullptr; - queue->BeginShutdown() - ->Then(mParentDecoder->GetReader()->GetTaskQueue(), __func__, this, - &TrackBuffer::ContinueShutdown, &TrackBuffer::ContinueShutdown); - return p; -} - -void -TrackBuffer::ContinueShutdown(bool aSuccess) -{ - MOZ_ASSERT(aSuccess); ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); - if (mDecoders.Length()) { - mDecoders[0]->GetReader()->Shutdown() - ->Then(mParentDecoder->GetReader()->GetTaskQueue(), __func__, this, - &TrackBuffer::ContinueShutdown, &TrackBuffer::ContinueShutdown); - mShutdownDecoders.AppendElement(mDecoders[0]); - mDecoders.RemoveElementAt(0); - return; + for (uint32_t i = 0; i < mDecoders.Length(); ++i) { + mDecoders[i]->GetReader()->Shutdown(); } - mInitializedDecoders.Clear(); mParentDecoder = nullptr; - - mShutdownPromise.Resolve(true, __func__); } bool @@ -449,13 +433,12 @@ TrackBuffer::BreakCycles() { MOZ_ASSERT(NS_IsMainThread()); - for (uint32_t i = 0; i < mShutdownDecoders.Length(); ++i) { - mShutdownDecoders[i]->BreakCycles(); + for (uint32_t i = 0; i < mDecoders.Length(); ++i) { + mDecoders[i]->BreakCycles(); } - mShutdownDecoders.Clear(); + mDecoders.Clear(); // These are cleared in Shutdown() - MOZ_ASSERT(!mDecoders.Length()); MOZ_ASSERT(mInitializedDecoders.IsEmpty()); MOZ_ASSERT(!mParentDecoder); } diff --git a/dom/media/mediasource/TrackBuffer.h b/dom/media/mediasource/TrackBuffer.h index ef2ee18dd942..0e4770f11818 100644 --- a/dom/media/mediasource/TrackBuffer.h +++ b/dom/media/mediasource/TrackBuffer.h @@ -8,7 +8,6 @@ #define MOZILLA_TRACKBUFFER_H_ #include "SourceBufferDecoder.h" -#include "MediaPromise.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/mozalloc.h" @@ -34,7 +33,7 @@ public: TrackBuffer(MediaSourceDecoder* aParentDecoder, const nsACString& aType); - nsRefPtr Shutdown(); + void Shutdown(); // Append data to the current decoder. Also responsible for calling // NotifyDataArrived on the decoder to keep buffered range computation up @@ -132,11 +131,6 @@ private: // mParentDecoder's monitor. nsTArray> mDecoders; - // During shutdown, we move decoders from mDecoders to mShutdownDecoders after - // invoking Shutdown. This is all so that we can avoid destroying the decoders - // off-main-thread. :-( - nsTArray> mShutdownDecoders; - // Contains only the initialized decoders managed by this TrackBuffer. // Access protected by mParentDecoder's monitor. nsTArray> mInitializedDecoders; @@ -159,9 +153,6 @@ private: // Set when the first decoder used by this TrackBuffer is initialized. // Protected by mParentDecoder's monitor. MediaInfo mInfo; - - void ContinueShutdown(bool aSuccess); - MediaPromiseHolder mShutdownPromise; }; } // namespace mozilla diff --git a/dom/media/mediasource/moz.build b/dom/media/mediasource/moz.build index 4365bc991901..1bf57102a455 100644 --- a/dom/media/mediasource/moz.build +++ b/dom/media/mediasource/moz.build @@ -8,7 +8,6 @@ MOCHITEST_MANIFESTS += ['test/mochitest.ini'] EXPORTS += [ 'AsyncEventRunner.h', 'MediaSourceDecoder.h', - 'MediaSourceReader.h', ] EXPORTS.mozilla.dom += [ diff --git a/dom/media/omx/MediaCodecReader.cpp b/dom/media/omx/MediaCodecReader.cpp index c78b7c19fe17..634a62ab198c 100644 --- a/dom/media/omx/MediaCodecReader.cpp +++ b/dom/media/omx/MediaCodecReader.cpp @@ -344,11 +344,11 @@ MediaCodecReader::ReleaseMediaResources() ReleaseCriticalResources(); } -nsRefPtr +void MediaCodecReader::Shutdown() { ReleaseResources(); - return MediaDecoderReader::Shutdown(); + MediaDecoderReader::Shutdown(); } void diff --git a/dom/media/omx/MediaCodecReader.h b/dom/media/omx/MediaCodecReader.h index b82531058e41..3f51e34da08e 100644 --- a/dom/media/omx/MediaCodecReader.h +++ b/dom/media/omx/MediaCodecReader.h @@ -68,7 +68,7 @@ public: // Destroys the decoding state. The reader cannot be made usable again. // This is different from ReleaseMediaResources() as Shutdown() is // irreversible, whereas ReleaseMediaResources() is reversible. - virtual nsRefPtr Shutdown(); + virtual void Shutdown(); // Used to retrieve some special information that can only be retrieved after // all contents have been continuously parsed. (ex. total duration of some diff --git a/dom/media/omx/MediaOmxReader.cpp b/dom/media/omx/MediaOmxReader.cpp index 4d9b69177a70..309d11d4f688 100644 --- a/dom/media/omx/MediaOmxReader.cpp +++ b/dom/media/omx/MediaOmxReader.cpp @@ -175,20 +175,17 @@ void MediaOmxReader::ReleaseDecoder() mOmxDecoder.clear(); } -nsRefPtr -MediaOmxReader::Shutdown() +void MediaOmxReader::Shutdown() { nsCOMPtr cancelEvent = NS_NewRunnableMethod(this, &MediaOmxReader::CancelProcessCachedData); NS_DispatchToMainThread(cancelEvent); - nsRefPtr p = MediaDecoderReader::Shutdown(); + MediaDecoderReader::Shutdown(); nsCOMPtr event = NS_NewRunnableMethod(this, &MediaOmxReader::ReleaseDecoder); NS_DispatchToMainThread(event); - - return p; } bool MediaOmxReader::IsWaitingMediaResources() diff --git a/dom/media/omx/MediaOmxReader.h b/dom/media/omx/MediaOmxReader.h index cbe88c09c726..0a0d67192351 100644 --- a/dom/media/omx/MediaOmxReader.h +++ b/dom/media/omx/MediaOmxReader.h @@ -104,7 +104,7 @@ public: virtual void SetIdle() MOZ_OVERRIDE; - virtual nsRefPtr Shutdown() MOZ_OVERRIDE; + virtual void Shutdown() MOZ_OVERRIDE; bool IsShutdown() { MutexAutoLock lock(mMutex); diff --git a/dom/media/webm/WebMReader.cpp b/dom/media/webm/WebMReader.cpp index e9c3bdac1eab..5b47c331a1e5 100644 --- a/dom/media/webm/WebMReader.cpp +++ b/dom/media/webm/WebMReader.cpp @@ -218,8 +218,7 @@ WebMReader::~WebMReader() MOZ_COUNT_DTOR(WebMReader); } -nsRefPtr -WebMReader::Shutdown() +void WebMReader::Shutdown() { #if defined(MOZ_PDM_VPX) if (mVideoTaskQueue) { @@ -233,7 +232,7 @@ WebMReader::Shutdown() mVideoDecoder = nullptr; } - return MediaDecoderReader::Shutdown(); + MediaDecoderReader::Shutdown(); } nsresult WebMReader::Init(MediaDecoderReader* aCloneDonor) diff --git a/dom/media/webm/WebMReader.h b/dom/media/webm/WebMReader.h index 94b4f5d42d1f..2e19bc8f0b05 100644 --- a/dom/media/webm/WebMReader.h +++ b/dom/media/webm/WebMReader.h @@ -133,7 +133,7 @@ protected: ~WebMReader(); public: - virtual nsRefPtr Shutdown() MOZ_OVERRIDE; + virtual void Shutdown() MOZ_OVERRIDE; virtual nsresult Init(MediaDecoderReader* aCloneDonor); virtual nsresult ResetDecode(); virtual bool DecodeAudioData();