Bug 1264199: P8. Handle potential resampling errors. r=kinetik
☠☠ backed out by 0c845a225f1a ☠ ☠
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 19 Apr 2016 14:53:18 +1000
changeset 332152 b52399a4a1750d6819cfac993c8c732d5e643a1d
parent 332151 a9bfe66b235c0936cb34f53d24aee08d3814bdfd
child 332153 6fad55fb6f686bb17742d0d777da337d633f3e91
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