Bug 1264199: P8. Handle potential resampling errors. r=kinetik
☠☠ backed out by 30c5dbcee7dd ☠ ☠
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 19 Apr 2016 14:53:18 +1000
changeset 331855 0f20f2080824affe403a4b5d1bcbb11fda7325f7
parent 331854 90351d2719beeb09ea4239685baf304e5058c19f
child 331856 fbcd1815776a4d1584cb742bfeac64a8373f9167
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1264199
milestone48.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 1264199: P8. Handle potential resampling errors. r=kinetik The speex resampler can never return an error in its current state. But just in case and to handle any future changes to the speex resampler. Also ensure that we can never access a stale speex resampler. MozReview-Commit-ID: CEME0AA9ghK
dom/media/AudioConverter.cpp
--- a/dom/media/AudioConverter.cpp
+++ b/dom/media/AudioConverter.cpp
@@ -100,20 +100,17 @@ void
 }
 
 void
 AudioConverter::ReOrderInterleavedChannels(void* aOut, const void* aIn,
                                            size_t aFrames) const
 {
   MOZ_DIAGNOSTIC_ASSERT(mIn.Channels() == mOut.Channels());
 
-  if (mOut.Layout() == mIn.Layout()) {
-    return;
-  }
-  if (mOut.Channels() == 1) {
+  if (mOut.Channels() == 1 || mOut.Layout() == mIn.Layout()) {
     // If channel count is 1, planar and non-planar formats are the same and
     // there's nothing to reorder.
     if (aOut != aIn) {
       memmove(aOut, aIn, FramesOutToBytes(aFrames));
     }
     return;
   }
 
@@ -248,29 +245,38 @@ size_t
 AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames)
 {
   if (!mResampler) {
     return 0;
   }
   uint32_t outframes = ResampleRecipientFrames(aFrames);
   uint32_t inframes = aFrames;
 
+  int error;
   if (mOut.Format() == AudioConfig::FORMAT_FLT) {
     const float* in = reinterpret_cast<const float*>(aIn);
     float* out = reinterpret_cast<float*>(aOut);
-    speex_resampler_process_interleaved_float(mResampler, in, &inframes,
-                                              out, &outframes);
+    error =
+      speex_resampler_process_interleaved_float(mResampler, in, &inframes,
+                                                out, &outframes);
   } else if (mOut.Format() == AudioConfig::FORMAT_S16) {
     const int16_t* in = reinterpret_cast<const int16_t*>(aIn);
     int16_t* out = reinterpret_cast<int16_t*>(aOut);
-    speex_resampler_process_interleaved_int(mResampler, in, &inframes,
-                                            out, &outframes);
+    error =
+      speex_resampler_process_interleaved_int(mResampler, in, &inframes,
+                                              out, &outframes);
   } else {
     MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
   }
+  MOZ_ASSERT(error == RESAMPLER_ERR_SUCCESS);
+  if (error != RESAMPLER_ERR_SUCCESS) {
+    speex_resampler_destroy(mResampler);
+    mResampler = nullptr;
+    return 0;
+  }
   MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped");
   return outframes;
 }
 
 void
 AudioConverter::RecreateResampler()
 {
   if (mResampler) {
@@ -293,18 +299,17 @@ AudioConverter::RecreateResampler()
 
 size_t
 AudioConverter::DrainResampler(void* aOut)
 {
   if (!mResampler) {
     return 0;
   }
   int frames = speex_resampler_get_input_latency(mResampler);
-  AlignedByteBuffer buffer(FramesOutToSamples(frames) *
-                           AudioConfig::SampleSize(mOut.Format()));
+  AlignedByteBuffer buffer(FramesOutToBytes(frames));
   if (!buffer) {
     // OOM
     return 0;
   }
   frames = ResampleAudio(aOut, buffer.Data(), frames);
   // Tore down the resampler as it's easier than handling follow-up.
   RecreateResampler();
   return frames;
@@ -353,16 +358,19 @@ AudioConverter::UpmixAudio(void* aOut, c
 }
 
 size_t
 AudioConverter::ResampleRecipientFrames(size_t aFrames) const
 {
   if (!aFrames && mIn.Rate() != mOut.Rate()) {
     // The resampler will be drained, account for frames currently buffered
     // in the resampler.
+    if (!mResampler) {
+      return 0;
+    }
     return speex_resampler_get_output_latency(mResampler);
   } else {
     return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
   }
 }
 
 size_t
 AudioConverter::FramesOutToSamples(size_t aFrames) const