Bug 592833 - Remove nsBuiltinDecoderReader monitor. r=roc
authorChris Pearce <chris@pearce.org.nz>
Tue, 12 Jul 2011 15:39:28 +1200
changeset 72650 01fc3692c8883999a610472fe774be73149dcb00
parent 72649 61d23b08b595a95808345e6dc458cac85fb086c7
child 72651 45974f65fc7eaa8591d923d2d91f82ddd9819294
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs592833
milestone8.0a1
Bug 592833 - Remove nsBuiltinDecoderReader monitor. r=roc
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
content/media/wave/nsWaveReader.cpp
content/media/webm/nsWebMReader.cpp
content/media/webm/nsWebMReader.h
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -185,18 +185,17 @@ VideoData* VideoData::Create(nsVideoInfo
   data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
   data.mStereoMode = aInfo.mStereoMode;
 
   videoImage->SetData(data); // Copies buffer
   return v.forget();
 }
 
 nsBuiltinDecoderReader::nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder)
-  : mReentrantMonitor("media.decoderreader"),
-    mDecoder(aDecoder)
+  : mDecoder(aDecoder)
 {
   MOZ_COUNT_CTOR(nsBuiltinDecoderReader);
 }
 
 nsBuiltinDecoderReader::~nsBuiltinDecoderReader()
 {
   ResetDecode();
   MOZ_COUNT_DTOR(nsBuiltinDecoderReader);
@@ -270,17 +269,16 @@ nsresult nsBuiltinDecoderReader::DecodeT
   if (HasVideo()) {
     PRBool eof = PR_FALSE;
     PRInt64 startTime = -1;
     while (HasVideo() && !eof) {
       while (mVideoQueue.GetSize() == 0 && !eof) {
         PRBool skip = PR_FALSE;
         eof = !DecodeVideoFrame(skip, 0);
         {
-          ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
           ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
           if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
             return NS_ERROR_FAILURE;
           }
         }
       }
       if (mVideoQueue.GetSize() == 0) {
         break;
@@ -295,17 +293,16 @@ nsresult nsBuiltinDecoderReader::DecodeT
         mVideoQueue.PopFront();
         video = nsnull;
       } else {
         video.forget();
         break;
       }
     }
     {
-      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
       ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
         return NS_ERROR_FAILURE;
       }
     }
     LOG(PR_LOG_DEBUG, ("First video frame after decode is %lld", startTime));
   }
 
@@ -315,17 +312,16 @@ nsresult nsBuiltinDecoderReader::DecodeT
     if (!UsecsToSamples(aTarget, mInfo.mAudioRate, targetSample)) {
       return NS_ERROR_FAILURE;
     }
     PRBool eof = PR_FALSE;
     while (HasAudio() && !eof) {
       while (!eof && mAudioQueue.GetSize() == 0) {
         eof = !DecodeAudioData();
         {
-          ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
           ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
           if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
             return NS_ERROR_FAILURE;
           }
         }
       }
       const SoundData* audio = mAudioQueue.PeekFront();
       if (!audio)
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -393,22 +393,20 @@ template <class T> class MediaQueue : pr
 private:
   ReentrantMonitor mReentrantMonitor;
 
   // PR_TRUE when we've decoded the last frame of data in the
   // bitstream for which we're queueing sample-data.
   PRBool mEndOfStream;
 };
 
-// Encapsulates the decoding and reading of media data. Reading can be done
-// on either the state machine thread (when loading and seeking) or on
-// the reader thread (when it's reading and decoding). The reader encapsulates
-// the reading state and maintains it's own monitor to ensure thread safety
-// and correctness. Never hold the nsBuiltinDecoder's monitor when calling into
-// this class.
+// Encapsulates the decoding and reading of media data. Reading can only be
+// done on the decode thread thread. Never hold the decoder monitor when
+// calling into this class. Unless otherwise specified, methods and fields of
+// this class can only be accessed on the decode thread.
 class nsBuiltinDecoderReader : public nsRunnable {
 public:
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
   typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
 
   nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder);
   ~nsBuiltinDecoderReader();
 
@@ -447,20 +445,22 @@ public:
   // Moves the decode head to aTime microseconds. aStartTime and aEndTime
   // denote the start and end times of the media in usecs, and aCurrentTime
   // is the current playback position in microseconds.
   virtual nsresult Seek(PRInt64 aTime,
                         PRInt64 aStartTime,
                         PRInt64 aEndTime,
                         PRInt64 aCurrentTime) = 0;
 
-  // Queue of audio samples. This queue is threadsafe.
+  // Queue of audio samples. This queue is threadsafe, and is accessed from
+  // the audio, decoder, state machine, and main threads.
   MediaQueue<SoundData> mAudioQueue;
 
-  // Queue of video samples. This queue is threadsafe.
+  // Queue of video samples. This queue is threadsafe, and is accessed from
+  // the decoder, state machine, and main threads.
   MediaQueue<VideoData> mVideoQueue;
 
   // Populates aBuffered with the time ranges which are buffered. aStartTime
   // must be the presentation time of the first sample/frame in the media, e.g.
   // the media time corresponding to playback time/position 0. This function
   // should only be called on the main thread.
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered,
                                PRInt64 aStartTime) = 0;
@@ -487,22 +487,16 @@ protected:
 
   // Wrapper so that DecodeVideoFrame(PRBool&,PRInt64) can be called from
   // DecodeToFirstData().
   PRBool DecodeVideoFrame() {
     PRBool f = PR_FALSE;
     return DecodeVideoFrame(f, 0);
   }
 
-  // The lock which we hold whenever we read or decode. This ensures the thread
-  // safety of the reader and its data fields.
-  ReentrantMonitor mReentrantMonitor;
-
-  // Reference to the owning decoder object. Do not hold the
-  // reader's monitor when accessing this.
+  // Reference to the owning decoder object.
   nsBuiltinDecoder* mDecoder;
 
-  // Stores presentation info required for playback. The reader's monitor
-  // must be held when accessing this.
+  // Stores presentation info required for playback.
   nsVideoInfo mInfo;
 };
 
 #endif
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -135,33 +135,30 @@ nsresult nsOggReader::Init(nsBuiltinDeco
   }
   int ret = ogg_sync_init(&mOggState);
   NS_ENSURE_TRUE(ret == 0, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 nsresult nsOggReader::ResetDecode()
 {
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   nsresult res = NS_OK;
 
   if (NS_FAILED(nsBuiltinDecoderReader::ResetDecode())) {
     res = NS_ERROR_FAILURE;
   }
 
-  {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-    // Discard any previously buffered packets/pages.
-    ogg_sync_reset(&mOggState);
-    if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
-      res = NS_ERROR_FAILURE;
-    }
-    if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
-      res = NS_ERROR_FAILURE;
-    }
+  // Discard any previously buffered packets/pages.
+  ogg_sync_reset(&mOggState);
+  if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
+    res = NS_ERROR_FAILURE;
+  }
+  if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
+    res = NS_ERROR_FAILURE;
   }
 
   return res;
 }
 
 PRBool nsOggReader::ReadHeaders(nsOggCodecState* aState)
 {
   while (!aState->DoneReadingHeaders()) {
@@ -174,17 +171,16 @@ PRBool nsOggReader::ReadHeaders(nsOggCod
     }
   }
   return aState->Init();
 }
 
 nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   // We read packets until all bitstreams have read all their header packets.
   // We record the offset of the first non-header page so that we know
   // what page to seek to when seeking to the media start.
 
   ogg_page page;
   nsAutoTArray<nsOggCodecState*,4> bitstreams;
   PRBool readAllBOS = PR_FALSE;
@@ -313,27 +309,25 @@ nsresult nsOggReader::ReadMetadata(nsVid
       if (HasVideo()) {
         tracks.AppendElement(mTheoraState->mSerial);
       }
       if (HasAudio()) {
         tracks.AppendElement(mVorbisState->mSerial);
       }
       PRInt64 duration = 0;
       if (NS_SUCCEEDED(mSkeletonState->GetDuration(tracks, duration))) {
-        ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-        ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+        ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
         mDecoder->GetStateMachine()->SetDuration(duration);
         LOG(PR_LOG_DEBUG, ("Got duration from Skeleton index %lld", duration));
       }
     }
   }
 
   {
-    ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-    ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
     nsMediaStream* stream = mDecoder->GetCurrentStream();
     if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
         mDecoder->GetStateMachine()->GetState() != nsDecoderStateMachine::DECODER_STATE_SHUTDOWN &&
         stream->GetLength() >= 0 &&
         mDecoder->GetStateMachine()->GetSeekable())
     {
       // We didn't get a duration from the index or a Content-Duration header.
@@ -397,17 +391,16 @@ nsresult nsOggReader::DecodeVorbis(ogg_p
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 PRBool nsOggReader::DecodeAudioData()
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   NS_ASSERTION(mVorbisState!=0, "Need Vorbis state to decode audio");
 
   // Read the next data packet. Skip any non-data packets we encounter.
   ogg_packet* packet = 0;
   do {
     if (packet) {
       nsOggCodecState::ReleasePacket(packet);
@@ -474,19 +467,16 @@ nsresult nsOggReader::DecodeTheora(ogg_p
     VideoData::YCbCrBuffer b;
     for (PRUint32 i=0; i < 3; ++i) {
       b.mPlanes[i].mData = buffer[i].data;
       b.mPlanes[i].mHeight = buffer[i].height;
       b.mPlanes[i].mWidth = buffer[i].width;
       b.mPlanes[i].mStride = buffer[i].stride;
     }
 
-    // Need the monitor to be held to be able to use mInfo. This
-    // is held by our caller.
-    mReentrantMonitor.AssertCurrentThreadIn();
     VideoData *v = VideoData::Create(mInfo,
                                      mDecoder->GetImageContainer(),
                                      mPageOffset,
                                      time,
                                      endTime,
                                      b,
                                      isKeyframe,
                                      aPacket->granulepos,
@@ -500,17 +490,16 @@ nsresult nsOggReader::DecodeTheora(ogg_p
     mVideoQueue.Push(v);
   }
   return NS_OK;
 }
 
 PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                      PRInt64 aTimeThreshold)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   PRUint32 parsed = 0, decoded = 0;
   nsMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
 
   // Read the next data packet. Skip any non-data packets we encounter.
@@ -551,17 +540,16 @@ PRBool nsOggReader::DecodeVideoFrame(PRB
   }
 
   return PR_TRUE;
 }
 
 PRInt64 nsOggReader::ReadOggPage(ogg_page* aPage)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  mReentrantMonitor.AssertCurrentThreadIn();
 
   int ret = 0;
   while((ret = ogg_sync_pageseek(&mOggState, aPage)) <= 0) {
     if (ret < 0) {
       // Lost page sync, have to skip up to next page.
       mPageOffset += -ret;
       continue;
     }
@@ -590,17 +578,16 @@ PRInt64 nsOggReader::ReadOggPage(ogg_pag
   mPageOffset += aPage->header_len + aPage->body_len;
   
   return offset;
 }
 
 ogg_packet* nsOggReader::NextOggPacket(nsOggCodecState* aCodecState)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (!aCodecState || !aCodecState->mActive) {
     return nsnull;
   }
 
   ogg_packet* packet;
   while ((packet = aCodecState->PacketOut()) == nsnull) {
     // The codec state does not have any buffered pages, so try to read another
@@ -633,18 +620,17 @@ GetChecksum(ogg_page* page)
                (p[1] << 8) + 
                (p[2] << 16) +
                (p[3] << 24);
   return c;
 }
 
 PRInt64 nsOggReader::RangeStartTime(PRInt64 aOffset)
 {
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-               "Should be on state machine or decode thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   NS_ENSURE_TRUE(stream != nsnull, nsnull);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
   NS_ENSURE_SUCCESS(res, nsnull);
   PRInt64 startTime = 0;
   nsBuiltinDecoderReader::FindStartTime(startTime);
   return startTime;
 }
@@ -656,17 +642,16 @@ struct nsAutoOggSyncState {
   ~nsAutoOggSyncState() {
     ogg_sync_clear(&mState);
   }
   ogg_sync_state mState;
 };
 
 PRInt64 nsOggReader::RangeEndTime(PRInt64 aEndOffset)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   NS_ENSURE_TRUE(stream != nsnull, -1);
   PRInt64 position = stream->Tell();
   PRInt64 endTime = RangeEndTime(0, aEndOffset, PR_FALSE);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, position);
@@ -789,17 +774,16 @@ PRInt64 nsOggReader::RangeEndTime(PRInt6
   }
 
   return endTime;
 }
 
 nsresult nsOggReader::GetSeekRanges(nsTArray<SeekRange>& aRanges)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  mReentrantMonitor.AssertCurrentThreadIn();
   nsTArray<nsByteRange> cached;
   nsresult res = mDecoder->GetCurrentStream()->GetCachedRanges(cached);
   NS_ENSURE_SUCCESS(res, res);
 
   for (PRUint32 index = 0; index < cached.Length(); index++) {
     nsByteRange& range = cached[index];
     PRInt64 startTime = -1;
     PRInt64 endTime = -1;
@@ -966,18 +950,17 @@ nsresult nsOggReader::SeekInBufferedRang
 
   // We have an active Theora bitstream. Decode the next Theora frame, and
   // extract its keyframe's time.
   PRBool eof;
   do {
     PRBool skip = PR_FALSE;
     eof = !DecodeVideoFrame(skip, 0);
     {
-      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
         return NS_ERROR_FAILURE;
       }
     }
   } while (!eof &&
            mVideoQueue.GetSize() == 0);
 
   VideoData* video = mVideoQueue.PeekFront();
@@ -1041,17 +1024,16 @@ nsresult nsOggReader::SeekInUnbuffered(P
   return SeekBisection(seekTarget, k, SEEK_FUZZ_USECS);
 }
 
 nsresult nsOggReader::Seek(PRInt64 aTarget,
                            PRInt64 aStartTime,
                            PRInt64 aEndTime,
                            PRInt64 aCurrentTime)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
   nsresult res;
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   NS_ENSURE_TRUE(stream != nsnull, NS_ERROR_FAILURE);
 
   if (aTarget == aStartTime) {
     // We've seeked to the media start. Just seek to the offset of the first
@@ -1060,18 +1042,17 @@ nsresult nsOggReader::Seek(PRInt64 aTarg
     NS_ENSURE_SUCCESS(res,res);
 
     mPageOffset = 0;
     res = ResetDecode();
     NS_ENSURE_SUCCESS(res,res);
 
     NS_ASSERTION(aStartTime != -1, "mStartTime should be known");
     {
-      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       mDecoder->UpdatePlaybackPosition(aStartTime);
     }
   } else if (CanDecodeToTarget(aTarget, aCurrentTime)) {
     LOG(PR_LOG_DEBUG, ("%p Seek target (%lld) is close to current time (%lld), "
         "will just decode to it", mDecoder, aCurrentTime, aTarget));
   } else {
     IndexedSeekResult sres = SeekToKeyframeUsingIndex(aTarget);
     NS_ENSURE_TRUE(sres != SEEK_FATAL_ERROR, NS_ERROR_FAILURE);
--- a/content/media/ogg/nsOggReader.h
+++ b/content/media/ogg/nsOggReader.h
@@ -66,37 +66,31 @@ public:
   virtual PRBool DecodeAudioData();
 
   // If the Theora granulepos has not been captured, it may read several packets
   // until one with a granulepos has been captured, to ensure that all packets
   // read have valid time info.  
   virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
                                   PRInt64 aTimeThreshold);
 
-  virtual PRBool HasAudio()
-  {
-    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+  virtual PRBool HasAudio() {
     return mVorbisState != 0 && mVorbisState->mActive;
   }
 
-  virtual PRBool HasVideo()
-  {
-    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+  virtual PRBool HasVideo() {
     return mTheoraState != 0 && mTheoraState->mActive;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
 private:
 
-  PRBool HasSkeleton()
-  {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+  PRBool HasSkeleton() {
     return mSkeletonState != 0 && mSkeletonState->mActive;
   }
 
   // Returns PR_TRUE if we should decode up to the seek target rather than
   // seeking to the target using a bisection search or index-assisted seek.
   // We should do this if the seek target (aTarget, in usecs), lies not too far
   // ahead of the current playback position (aCurrentTime, in usecs).
   PRBool CanDecodeToTarget(PRInt64 aTarget,
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -148,44 +148,40 @@ nsWaveReader::~nsWaveReader()
 nsresult nsWaveReader::Init(nsBuiltinDecoderReader* aCloneDonor)
 {
   return NS_OK;
 }
 
 nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   PRBool loaded = LoadRIFFChunk() && LoadFormatChunk() && FindDataOffset();
   if (!loaded) {
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mHasAudio = PR_TRUE;
   mInfo.mHasVideo = PR_FALSE;
   mInfo.mAudioRate = mSampleRate;
   mInfo.mAudioChannels = mChannels;
 
   *aInfo = mInfo;
 
-  ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-  ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   mDecoder->GetStateMachine()->SetDuration(
     static_cast<PRInt64>(BytesToTime(GetDataLength()) * USECS_PER_S));
 
   return NS_OK;
 }
 
 PRBool nsWaveReader::DecodeAudioData()
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-               "Should be on state machine thread or decode thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   PRInt64 pos = GetPosition() - mWavePCMOffset;
   PRInt64 len = GetDataLength();
   PRInt64 remaining = len - pos;
   NS_ASSERTION(remaining >= 0, "Current wave position is greater than wave file length");
 
   static const PRInt64 BLOCK_SIZE = 4096;
   PRInt64 readSize = NS_MIN(BLOCK_SIZE, remaining);
@@ -241,26 +237,23 @@ PRBool nsWaveReader::DecodeAudioData()
                                  mChannels));
 
   return PR_TRUE;
 }
 
 PRBool nsWaveReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                       PRInt64 aTimeThreshold)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-               "Should be on state machine or decode thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   return PR_FALSE;
 }
 
 nsresult nsWaveReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
   if (NS_FAILED(ResetDecode())) {
     return NS_ERROR_FAILURE;
   }
   double d = BytesToTime(GetDataLength());
   NS_ASSERTION(d < PR_INT64_MAX / USECS_PER_S, "Duration overflow"); 
   PRInt64 duration = static_cast<PRInt64>(d * USECS_PER_S);
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -204,34 +204,32 @@ void nsWebMReader::Cleanup()
   if (mContext) {
     nestegg_destroy(mContext);
     mContext = nsnull;
   }
 }
 
 nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
 {
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on state machine thread.");
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   nestegg_io io;
   io.read = webm_read;
   io.seek = webm_seek;
   io.tell = webm_tell;
   io.userdata = static_cast<nsBuiltinDecoder*>(mDecoder);
   int r = nestegg_init(&mContext, io, NULL);
   if (r == -1) {
     return NS_ERROR_FAILURE;
   }
 
   uint64_t duration = 0;
   r = nestegg_duration(mContext, &duration);
   if (r == 0) {
-    ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
-    ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mDecoder->GetStateMachine()->SetDuration(duration / NS_PER_USEC);
   }
 
   unsigned int ntracks = 0;
   r = nestegg_track_count(mContext, &ntracks);
   if (r == -1) {
     Cleanup();
     return NS_ERROR_FAILURE;
@@ -406,17 +404,17 @@ ogg_packet nsWebMReader::InitOggPacket(u
   packet.e_o_s = aEOS;
   packet.granulepos = aGranulepos;
   packet.packetno = mPacketCount++;
   return packet;
 }
  
 PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
 {
-  mReentrantMonitor.AssertCurrentThreadIn();
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   int r = 0;
   unsigned int count = 0;
   r = nestegg_packet_count(aPacket, &count);
   if (r == -1) {
     return PR_FALSE;
   }
 
@@ -584,34 +582,31 @@ nsReturnRef<NesteggPacketHolder> nsWebMR
     } while (PR_TRUE);
   }
 
   return holder.out();
 }
 
 PRBool nsWebMReader::DecodeAudioData()
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-    "Should be on state machine thread or decode thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
+
   nsAutoRef<NesteggPacketHolder> holder(NextPacket(AUDIO));
   if (!holder) {
     mAudioQueue.Finish();
     return PR_FALSE;
   }
 
   return DecodeAudioPacket(holder->mPacket, holder->mOffset);
 }
 
 PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                       PRInt64 aTimeThreshold)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-               "Should be on state machine or decode thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   PRUint32 parsed = 0, decoded = 0;
   nsMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
 
   nsAutoRef<NesteggPacketHolder> holder(NextPacket(VIDEO));
   if (!holder) {
@@ -647,17 +642,16 @@ PRBool nsWebMReader::DecodeVideoFrame(PR
     nsAutoRef<NesteggPacketHolder> next_holder(NextPacket(VIDEO));
     if (next_holder) {
       r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
       if (r == -1) {
         return PR_FALSE;
       }
       mVideoPackets.PushFront(next_holder.disown());
     } else {
-      ReentrantMonitorAutoExit exitMon(mReentrantMonitor);
       ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       nsBuiltinDecoderStateMachine* s =
         static_cast<nsBuiltinDecoderStateMachine*>(mDecoder->GetStateMachine());
       PRInt64 endTime = s->GetEndMediaTime();
       if (endTime == -1) {
         return PR_FALSE;
       }
       next_tstamp = endTime * NS_PER_USEC;
@@ -761,19 +755,18 @@ PRBool nsWebMReader::CanDecodeToTarget(P
 {
   return aTarget >= aCurrentTime &&
          aTarget - aCurrentTime < SEEK_DECODE_MARGIN;
 }
 
 nsresult nsWebMReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime,
                             PRInt64 aCurrentTime)
 {
-  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-  NS_ASSERTION(mDecoder->OnDecodeThread(),
-               "Should be on state machine thread.");
+  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
+
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
   if (CanDecodeToTarget(aTarget, aCurrentTime)) {
     LOG(PR_LOG_DEBUG, ("%p Seek target (%lld) is close to current time (%lld), "
                        "will just decode to it", mDecoder, aCurrentTime, aTarget));
   } else {
     if (NS_FAILED(ResetDecode())) {
       return NS_ERROR_FAILURE;
     }
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -138,23 +138,23 @@ public:
   // If the Theora granulepos has not been captured, it may read several packets
   // until one with a granulepos has been captured, to ensure that all packets
   // read have valid time info.  
   virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
                                   PRInt64 aTimeThreshold);
 
   virtual PRBool HasAudio()
   {
-    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+    NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
     return mHasAudio;
   }
 
   virtual PRBool HasVideo()
   {
-    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+    NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
     return mHasVideo;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset);