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 131357 f8beba959a1c96466c407496018143bfcf66b0de
parent 131356 80fa2c61df149c573ac85dd82e5c0ae9387fff14
child 131358 0b521694bdbc5a807e9b476b9dc3583561c4428f
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs837430
milestone21.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 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 &&