Bug 856361. Part 9: Make SpeechStreamListener handle null AudioChunks. r=smaug, a=webaudio
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 01 Aug 2013 16:02:49 +1200
changeset 153849 541920cf140e4d74c24af079eadbe2643f02ad28
parent 153848 5077bc561ce4690fff03fc4a33157e03e684e429
child 153850 532d1f0a2f2a973540a21e647ba6614cba67ab08
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, webaudio
bugs856361
milestone25.0a2
Bug 856361. Part 9: Make SpeechStreamListener handle null AudioChunks. r=smaug, a=webaudio
content/media/webspeech/recognition/SpeechStreamListener.cpp
content/media/webspeech/recognition/SpeechStreamListener.h
--- a/content/media/webspeech/recognition/SpeechStreamListener.cpp
+++ b/content/media/webspeech/recognition/SpeechStreamListener.cpp
@@ -35,45 +35,56 @@ SpeechStreamListener::NotifyQueuedTrackC
                                                uint32_t aTrackEvents,
                                                const MediaSegment& aQueuedMedia)
 {
   AudioSegment* audio = const_cast<AudioSegment*>(
     static_cast<const AudioSegment*>(&aQueuedMedia));
 
   AudioSegment::ChunkIterator iterator(*audio);
   while (!iterator.IsEnded()) {
-    AudioSampleFormat format = iterator->mBufferFormat;
-
-    MOZ_ASSERT(format == AUDIO_FORMAT_S16 || format == AUDIO_FORMAT_FLOAT32);
+    // Skip over-large chunks so we don't crash!
+    if (iterator->GetDuration() > INT_MAX) {
+      continue;
+    }
+    int duration = int(iterator->GetDuration());
 
-    if (format == AUDIO_FORMAT_S16) {
-      ConvertAndDispatchAudioChunk<int16_t>(*iterator);
-    } else if (format == AUDIO_FORMAT_FLOAT32) {
-      ConvertAndDispatchAudioChunk<float>(*iterator);
+    if (iterator->IsNull()) {
+      nsTArray<int16_t> nullData;
+      PodZero(nullData.AppendElements(duration), duration);
+      ConvertAndDispatchAudioChunk(duration, iterator->mVolume, nullData.Elements());
+    } else {
+      AudioSampleFormat format = iterator->mBufferFormat;
+
+      MOZ_ASSERT(format == AUDIO_FORMAT_S16 || format == AUDIO_FORMAT_FLOAT32);
+
+      if (format == AUDIO_FORMAT_S16) {
+        ConvertAndDispatchAudioChunk(duration, iterator->mVolume,
+                                     static_cast<const int16_t*>(iterator->mChannelData[0]));
+      } else if (format == AUDIO_FORMAT_FLOAT32) {
+        ConvertAndDispatchAudioChunk(duration, iterator->mVolume,
+                                     static_cast<const float*>(iterator->mChannelData[0]));
+      }
     }
 
     iterator.Next();
   }
 }
 
 template<typename SampleFormatType> void
-SpeechStreamListener::ConvertAndDispatchAudioChunk(AudioChunk& aChunk)
+SpeechStreamListener::ConvertAndDispatchAudioChunk(int aDuration, float aVolume,
+                                                   SampleFormatType* aData)
 {
-  nsRefPtr<SharedBuffer> samples(SharedBuffer::Create(aChunk.mDuration *
+  nsRefPtr<SharedBuffer> samples(SharedBuffer::Create(aDuration *
                                                       1 * // channel
                                                       sizeof(int16_t)));
 
-  const SampleFormatType* from =
-    static_cast<const SampleFormatType*>(aChunk.mChannelData[0]);
+  int16_t* to = static_cast<int16_t*>(samples->Data());
+  ConvertAudioSamplesWithScale(aData, to, aDuration, aVolume);
 
-  int16_t* to = static_cast<int16_t*>(samples->Data());
-  ConvertAudioSamplesWithScale(from, to, aChunk.mDuration, aChunk.mVolume);
-
-  mRecognition->FeedAudioData(samples.forget(), aChunk.mDuration, this);
-  return;
+  mRecognition->FeedAudioData(samples.forget(), aDuration, this);
 }
 
 void
 SpeechStreamListener::NotifyFinished(MediaStreamGraph* aGraph)
 {
   // TODO dispatch SpeechEnd event so services can be informed
 }
 
--- a/content/media/webspeech/recognition/SpeechStreamListener.h
+++ b/content/media/webspeech/recognition/SpeechStreamListener.h
@@ -27,14 +27,15 @@ public:
                                 TrackRate aTrackRate,
                                 TrackTicks aTrackOffset,
                                 uint32_t aTrackEvents,
                                 const MediaSegment& aQueuedMedia) MOZ_OVERRIDE;
 
   void NotifyFinished(MediaStreamGraph* aGraph) MOZ_OVERRIDE;
 
 private:
-  template<typename SampleFormatType> void ConvertAndDispatchAudioChunk(AudioChunk& aChunk);
+  template<typename SampleFormatType>
+  void ConvertAndDispatchAudioChunk(int aDuration, float aVolume, SampleFormatType* aData);
   nsRefPtr<SpeechRecognition> mRecognition;
 };
 
 } // namespace dom
 } // namespace mozilla