Bug 837430 - Don't hold the decoder monitor while initializing AudioStreams. r=cpearce
authorMatthew Gregan <kinetik@flim.org>
Fri, 08 Feb 2013 13:46:33 +1300
changeset 121483 f8beba959a1c96466c407496018143bfcf66b0de
parent 121482 80fa2c61df149c573ac85dd82e5c0ae9387fff14
child 121484 0b521694bdbc5a807e9b476b9dc3583561c4428f
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerscpearce
bugs837430
milestone21.0a1
Bug 837430 - Don't hold the decoder monitor while initializing AudioStreams. r=cpearce
content/media/MediaDecoderStateMachine.cpp
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -982,38 +982,51 @@ void MediaDecoderStateMachine::AudioLoop
   uint32_t channels, rate;
   double volume = -1;
   bool setVolume;
   double playbackRate = -1;
   bool setPlaybackRate;
   bool preservesPitch;
   bool setPreservesPitch;
   int32_t minWriteFrames = -1;
+  AudioChannelType audioChannelType;
+
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mAudioCompleted = false;
     audioStartTime = mAudioStartTime;
     channels = mInfo.mAudioChannels;
     rate = mInfo.mAudioRate;
+    audioChannelType = mDecoder->GetAudioChannelType();
     NS_ASSERTION(audioStartTime != -1, "Should have audio start time by now");
 
-    mAudioStream = AudioStream::AllocateStream();
-    mAudioStream->Init(channels, rate, mDecoder->GetAudioChannelType());
-
     volume = mVolume;
-    mAudioStream->SetVolume(volume);
     preservesPitch = mPreservesPitch;
-    mAudioStream->SetPreservesPitch(preservesPitch);
     playbackRate = mPlaybackRate;
+  }
+
+  {
+    // AudioStream initialization can block for extended periods in unusual
+    // circumstances, so we take care to drop the decoder monitor while
+    // initializing.
+    nsAutoPtr<AudioStream> audioStream(AudioStream::AllocateStream());
+    audioStream->Init(channels, rate, audioChannelType);
+    audioStream->SetPreservesPitch(preservesPitch);
     if (playbackRate != 1.0) {
       NS_ASSERTION(playbackRate != 0,
-          "Don't set the playbackRate to 0 on an AudioStream.");
-      mAudioStream->SetPlaybackRate(playbackRate);
+                   "Don't set the playbackRate to 0 on an AudioStream.");
+      audioStream->SetPlaybackRate(playbackRate);
+    }
+
+    {
+      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+      mAudioStream = audioStream;
     }
   }
+
   while (1) {
     // Wait while we're not playing, and we're not shutting down, or we're
     // playing and we've got no audio to play.
     {
       ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       NS_ASSERTION(mState != DECODER_STATE_DECODING_METADATA,
                    "Should have meta data before audio started playing.");
       while (mState != DECODER_STATE_SHUTDOWN &&