Bug 806754. Part 2: Fix bogus assertions. r=cpearce
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 30 Jan 2013 17:20:03 +1300
changeset 130203 d4a6570ca6b0a26070a6287875e53cc7c2f12141
parent 130202 62f4bc028c72c1f3609a802e8d83aae12ea0ca88
child 130204 8c1d7f3cc0365ff2d5284b8bc874dd2c7136811c
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
bugs806754, 794426
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 806754. Part 2: Fix bogus assertions. r=cpearce SendStreamAudio gets called by SendStreamData which can be called on the state machine thread since bug 794426 was fixed. At the same time PlayFromAudioQueuec can no longer guarantee that mAudioCaptured is false. It could be true and we're waiting for the audio thread to shut down. We can just remove that assertion; the logic in SendStreamData guarantees that we don't try to pass audio to MediaStreams until the audio thread has actually stopped.
content/media/MediaDecoderStateMachine.cpp
content/media/test/Makefile.in
content/media/test/test_streams_gc.html
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -501,17 +501,18 @@ void MediaDecoderStateMachine::DecodeThr
   
   mReader->OnDecodeThreadFinish();
 }
 
 void MediaDecoderStateMachine::SendStreamAudio(AudioData* aAudio,
                                                DecodedStreamData* aStream,
                                                AudioSegment* aOutput)
 {
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
+  NS_ASSERTION(OnDecodeThread() ||
+               OnStateMachineThread(), "Should be on decode thread or state machine thread");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (aAudio->mTime <= aStream->mLastAudioPacketTime) {
     // ignore packet that we've already processed
     return;
   }
   aStream->mLastAudioPacketTime = aAudio->mTime;
   aStream->mLastAudioPacketEndTime = aAudio->GetEnd();
@@ -1205,25 +1206,24 @@ uint32_t MediaDecoderStateMachine::PlayS
   WriteSilence(mAudioStream, frames);
   // Dispatch events to the DOM for the audio just written.
   mEventManager.QueueWrittenAudioData(nullptr, frames * aChannels,
                                       (aFrameOffset + frames) * aChannels);
   return frames;
 }
 
 uint32_t MediaDecoderStateMachine::PlayFromAudioQueue(uint64_t aFrameOffset,
-                                                          uint32_t aChannels)
+                                                      uint32_t aChannels)
 {
   NS_ASSERTION(OnAudioThread(), "Only call on audio thread.");
   NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused");
   nsAutoPtr<AudioData> audio(mReader->AudioQueue().PopFront());
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     NS_WARN_IF_FALSE(IsPlaying(), "Should be playing");
-    NS_ASSERTION(!mAudioCaptured, "Audio cannot be captured here!");
     // Awaken the decode loop if it's waiting for space to free up in the
     // audio queue.
     mDecoder->GetReentrantMonitor().NotifyAll();
   }
   int64_t offset = -1;
   uint32_t frames = 0;
   if (!PR_GetEnv("MOZ_QUIET")) {
     LOG(PR_LOG_DEBUG, ("%p Decoder playing %d frames of data to stream for AudioData at %lld",
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -128,16 +128,17 @@ MOCHITEST_FILES = \
 		test_bug463162.xhtml \
 		test_decoder_disable.html \
 		test_media_selection.html \
 		test_playback.html \
 		test_seekLies.html \
 		test_media_sniffer.html \
 		contentType.sjs \
 		test_streams_srcObject.html \
+		test_streams_gc.html \
 		$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
 		$(NULL)
 
 # Disabled on Windows for frequent intermittent failures
 ifneq ($(OS_ARCH), WINNT)
 MOCHITEST_FILES += \
 		test_streams_element_capture.html \
 		test_streams_element_capture_reset.html \
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_streams_gc.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test garbage collection of captured stream (bug 806754)</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body onload="doTest()">
+<audio id="a"></audio>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var a = document.getElementById('a');
+a.src = getPlayableAudio(gSmallTests).name;
+
+function forceGC() {
+  SpecialPowers.gc();
+  SpecialPowers.forceGC();
+  SpecialPowers.forceCC();
+}
+
+function doTest() {
+  a.mozCaptureStreamUntilEnded();
+
+  a.addEventListener("seeked", function() {
+    a.play();
+
+    a.addEventListener("play", function() {
+      a.addEventListener("ended", function() {
+        ok(true, "GC completed OK");
+        SimpleTest.finish();
+      }, false);
+    }, false);
+  }, false);
+
+  a.currentTime = a.duration;
+  
+  setTimeout(forceGC, 0);
+}
+</script>
+</pre>
+</body>
+</html>