Bug 1104964 - Make sure that MediaDecoderReader::Shutdown is always called. r=cpearce
authorBobby Holley <bobbyholley@gmail.com>
Mon, 01 Dec 2014 21:51:02 -0800
changeset 218214 dd847aca8a71c668b4f01538424a5f746caad3d5
parent 218213 11a0c78d319d2fdc3bfd9fea41895f572aa58c7b
child 218215 f8c1c3b79b8299cabe9fd7f948446677864d99c4
push id27922
push usercbook@mozilla.com
push dateTue, 02 Dec 2014 10:55:24 +0000
treeherdermozilla-central@22ad8a162cf3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1104964
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1104964 - Make sure that MediaDecoderReader::Shutdown is always called. r=cpearce
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
dom/media/android/AndroidMediaReader.cpp
dom/media/fmp4/MP4Reader.cpp
dom/media/omx/MediaCodecReader.cpp
dom/media/omx/MediaOmxReader.cpp
dom/media/webm/WebMReader.cpp
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -60,22 +60,24 @@ public:
 
 MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
   : mAudioCompactor(mAudioQueue)
   , mDecoder(aDecoder)
   , mIgnoreAudioOutputFormat(false)
   , mStartTime(-1)
   , mAudioDiscontinuity(false)
   , mVideoDiscontinuity(false)
+  , mShutdown(false)
 {
   MOZ_COUNT_CTOR(MediaDecoderReader);
 }
 
 MediaDecoderReader::~MediaDecoderReader()
 {
+  MOZ_ASSERT(mShutdown);
   ResetDecode();
   MOZ_COUNT_DTOR(MediaDecoderReader);
 }
 
 size_t MediaDecoderReader::SizeOfVideoQueueInBytes() const
 {
   VideoQueueMemoryFunctor functor;
   mVideoQueue.LockedForEach(functor);
@@ -260,16 +262,17 @@ MediaDecoderReader::BreakCycles()
   }
   mTaskQueue = nullptr;
 }
 
 void
 MediaDecoderReader::Shutdown()
 {
   MOZ_ASSERT(mDecoder->OnDecodeThread());
+  mShutdown = true;
   ReleaseMediaResources();
 }
 
 AudioDecodeRendezvous::AudioDecodeRendezvous()
   : mMonitor("AudioDecodeRendezvous")
   , mHaveResult(false)
 {
 }
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -261,16 +261,17 @@ private:
   nsRefPtr<RequestSampleCallback> mSampleDecodedCallback;
 
   nsRefPtr<MediaTaskQueue> mTaskQueue;
 
   // Flags whether a the next audio/video sample comes after a "gap" or
   // "discontinuity" in the stream. For example after a seek.
   bool mAudioDiscontinuity;
   bool mVideoDiscontinuity;
+  bool mShutdown;
 };
 
 // Interface that callers to MediaDecoderReader::Request{Audio,Video}Data()
 // must implement to receive the requested samples asynchronously.
 // This object is refcounted, and cycles must be broken by calling
 // BreakCycles() during shutdown.
 class RequestSampleCallback {
 public:
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -101,16 +101,18 @@ nsresult AndroidMediaReader::ReadMetadat
 
 void AndroidMediaReader::Shutdown()
 {
   ResetDecode();
   if (mPlugin) {
     GetAndroidMediaPluginHost()->DestroyDecoder(mPlugin);
     mPlugin = nullptr;
   }
+
+  MediaDecoderReader::Shutdown();
 }
 
 // Resets all state related to decoding, emptying all buffers etc.
 nsresult AndroidMediaReader::ResetDecode()
 {
   if (mLastVideoFrame) {
     mLastVideoFrame = nullptr;
   }
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -164,16 +164,18 @@ MP4Reader::Shutdown()
   }
   // Dispose of the queued sample before shutting down the demuxer
   mQueuedVideoSample = nullptr;
 
   if (mPlatform) {
     mPlatform->Shutdown();
     mPlatform = nullptr;
   }
+
+  MediaDecoderReader::Shutdown();
 }
 
 void
 MP4Reader::InitLayersBackendType()
 {
   if (!IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
     // Not playing video, we don't care about the layers backend type.
     return;
--- a/dom/media/omx/MediaCodecReader.cpp
+++ b/dom/media/omx/MediaCodecReader.cpp
@@ -343,16 +343,17 @@ MediaCodecReader::ReleaseMediaResources(
   }
   ReleaseCriticalResources();
 }
 
 void
 MediaCodecReader::Shutdown()
 {
   ReleaseResources();
+  MediaDecoderReader::Shutdown();
 }
 
 void
 MediaCodecReader::DispatchAudioTask()
 {
   if (mAudioTrack.mTaskQueue && mAudioTrack.mTaskQueue->IsEmpty()) {
     RefPtr<nsIRunnable> task =
       NS_NewRunnableMethod(this,
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -176,17 +176,18 @@ void MediaOmxReader::ReleaseDecoder()
 }
 
 void MediaOmxReader::Shutdown()
 {
   nsCOMPtr<nsIRunnable> cancelEvent =
     NS_NewRunnableMethod(this, &MediaOmxReader::CancelProcessCachedData);
   NS_DispatchToMainThread(cancelEvent);
 
-  ReleaseMediaResources();
+  MediaDecoderReader::Shutdown();
+
   nsCOMPtr<nsIRunnable> event =
     NS_NewRunnableMethod(this, &MediaOmxReader::ReleaseDecoder);
   NS_DispatchToMainThread(event);
 }
 
 bool MediaOmxReader::IsWaitingMediaResources()
 {
   return mIsWaitingResources;
--- a/dom/media/webm/WebMReader.cpp
+++ b/dom/media/webm/WebMReader.cpp
@@ -226,16 +226,18 @@ void WebMReader::Shutdown()
     mTaskQueue->Shutdown();
   }
 #endif
 
   if (mVideoDecoder) {
     mVideoDecoder->Shutdown();
     mVideoDecoder = nullptr;
   }
+
+  MediaDecoderReader::Shutdown();
 }
 
 nsresult WebMReader::Init(MediaDecoderReader* aCloneDonor)
 {
   vorbis_info_init(&mVorbisInfo);
   vorbis_comment_init(&mVorbisComment);
   memset(&mVorbisDsp, 0, sizeof(vorbis_dsp_state));
   memset(&mVorbisBlock, 0, sizeof(vorbis_block));