Bug 1028458 - Don't try to use a resampler when resampling segments to graph rate if we haven't instanciated one yet. r=karlt, a=2.0+
authorPaul Adenot <paul@paul.cx>
Thu, 26 Jun 2014 14:01:01 +0200
changeset 208516 17bc466733ddb8e212bfed26c6fca45af24d9e5d
parent 208515 2016c180a540a97dd44965168c80fa305857cbcb
child 208517 8fb4f7972218d779541e0c81dd6b6aff109fbc58
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt, 2
bugs1028458
milestone32.0a2
Bug 1028458 - Don't try to use a resampler when resampling segments to graph rate if we haven't instanciated one yet. r=karlt, a=2.0+
content/media/AudioSegment.cpp
content/media/AudioSegment.h
content/media/MediaStreamGraph.cpp
content/media/test/crashtests/1028458.html
content/media/test/crashtests/crashtests.list
--- a/content/media/AudioSegment.cpp
+++ b/content/media/AudioSegment.cpp
@@ -109,43 +109,41 @@ DownmixAndInterleave(const nsTArray<cons
   if (channelData.Length() > aOutputChannels) {
     AudioChannelsDownMix(channelData, outputChannelBuffers.Elements(),
                          aOutputChannels, aDuration);
   }
   InterleaveAndConvertBuffer(outputChannelData.Elements(), AUDIO_FORMAT_FLOAT32,
                              aDuration, aVolume, aOutputChannels, aOutput);
 }
 
-void AudioSegment::ResampleChunks(SpeexResamplerState* aResampler)
+void AudioSegment::ResampleChunks(SpeexResamplerState* aResampler, uint32_t aInRate, uint32_t aOutRate)
 {
-  uint32_t inRate, outRate;
-
   if (mChunks.IsEmpty()) {
     return;
   }
 
-  speex_resampler_get_rate(aResampler, &inRate, &outRate);
+  MOZ_ASSERT(aResampler || IsNull(), "We can only be here without a resampler if this segment is null.");
 
   AudioSampleFormat format = AUDIO_FORMAT_SILENCE;
   for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
     if (ci->mBufferFormat != AUDIO_FORMAT_SILENCE) {
       format = ci->mBufferFormat;
     }
   }
 
   switch (format) {
     // If the format is silence at this point, all the chunks are silent. The
     // actual function we use does not matter, it's just a matter of changing
     // the chunks duration.
     case AUDIO_FORMAT_SILENCE:
     case AUDIO_FORMAT_FLOAT32:
-      Resample<float>(aResampler, inRate, outRate);
+      Resample<float>(aResampler, aInRate, aOutRate);
     break;
     case AUDIO_FORMAT_S16:
-      Resample<int16_t>(aResampler, inRate, outRate);
+      Resample<int16_t>(aResampler, aInRate, aOutRate);
     break;
     default:
       MOZ_ASSERT(false);
     break;
   }
 }
 
 void
--- a/content/media/AudioSegment.h
+++ b/content/media/AudioSegment.h
@@ -218,17 +218,19 @@ public:
       c.mBuffer = new mozilla::SharedChannelArrayBuffer<T>(&output);
       for (uint32_t i = 0; i < channels; i++) {
         c.mChannelData[i] = bufferPtrs[i];
       }
       mDuration += c.mDuration;
     }
   }
 
-  void ResampleChunks(SpeexResamplerState* aResampler);
+  void ResampleChunks(SpeexResamplerState* aResampler,
+                      uint32_t aInRate,
+                      uint32_t aOutRate);
 
   void AppendFrames(already_AddRefed<ThreadSharedObject> aBuffer,
                     const nsTArray<const float*>& aChannelData,
                     int32_t aDuration)
   {
     AudioChunk* chunk = AppendChunk(aDuration);
     chunk->mBuffer = aBuffer;
     for (uint32_t channel = 0; channel < aChannelData.Length(); ++channel) {
@@ -280,16 +282,25 @@ public:
     for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
       if (ci->ChannelCount()) {
         return ci->ChannelCount();
       }
     }
     return 0;
   }
 
+  bool IsNull() {
+    for (ChunkIterator ci(*this); !ci.IsEnded(); ci.Next()) {
+      if (!ci->IsNull()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   static Type StaticType() { return AUDIO; }
 
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 };
 
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -2306,17 +2306,17 @@ SourceMediaStream::ResampleAudioToGraphS
         return;
       }
       aTrackData->mResampler.own(state);
 #ifdef DEBUG
       aTrackData->mResamplerChannelCount = channels;
 #endif
     }
   }
-  segment->ResampleChunks(aTrackData->mResampler);
+  segment->ResampleChunks(aTrackData->mResampler, aTrackData->mInputRate, GraphImpl()->AudioSampleRate());
 }
 
 bool
 SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegment *aRawSegment)
 {
   MutexAutoLock lock(mMutex);
   // ::EndAllTrackAndFinished() can end these before the sources notice
   bool appended = false;
new file mode 100644
--- /dev/null
+++ b/content/media/test/crashtests/1028458.html
@@ -0,0 +1,21 @@
+<html class="reftest-wait">
+<audio id="testAudio" controls></audio>
+<script type="text/javascript">
+navigator.mozGetUserMedia({audio: true}, function(stream) {
+    stream.getAudioTracks()[0].enabled = false;
+    var testAudio = document.getElementById('testAudio');
+    // Wait some time for good measure
+    var eventReceived = 0;
+    testAudio.addEventListener("timeupdate", function() {
+      if (++eventReceived == 3) {
+        document.querySelector("html").className = "";
+      }
+    })
+    testAudio.mozSrcObject = stream;
+    testAudio.play();
+    }, function(err) {
+    console.log(err);
+    });
+</script>
+
+</html>
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -59,14 +59,15 @@ load 910171-1.html
 load 920987.html
 load 925619-1.html
 load 925619-2.html
 load 926619.html
 load 933151.html
 load 933156.html
 load 952756.html
 load 986901.html
+test-pref(media.navigator.permission.disabled,true) load 1028458.html
 load buffer-source-ended-1.html
 load offline-buffer-source-ended-1.html
 HTTP load media-element-source-seek-1.html
 skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
 include ../../mediasource/test/crashtests/crashtests.list