aboutsummaryrefslogblamecommitdiff
path: root/www/waterfox/files/patch-bug1429666
blob: 52a2ad5389ed47f9dfb1f3fb9f1af6e19bfceaee (plain) (tree)



















































































































































































































                                                                                                      
commit d16cbc0c61b1
Author: Karl Tomlinson <karlt+@karlt.net>
Date:   Thu Jan 11 13:30:24 2018 +1300

    bug 1429666 cubeb_resampler_speex: don't call data callback while draining r=padenot a=gchang
    
    MozReview-Commit-ID: 1XEzZjPGai9
    
    --HG--
    extra : source : 1ad55edca07d6706bdec5314724fd2361def43c3
---
 media/libcubeb/README_MOZILLA                 |  8 +++--
 media/libcubeb/gtest/test_resampler.cpp       | 15 ++++----
 media/libcubeb/src/cubeb_resampler.cpp        | 51 +++++++++++++++++----------
 media/libcubeb/src/cubeb_resampler_internal.h |  9 ++---
 4 files changed, 53 insertions(+), 30 deletions(-)

diff --git media/libcubeb/README_MOZILLA media/libcubeb/README_MOZILLA
index 506d2dc5434b..44d36b45c500 100644
--- media/libcubeb/README_MOZILLA
+++ media/libcubeb/README_MOZILLA
@@ -1,7 +1,11 @@
 The source from this directory was copied from the cubeb 
 git repository using the update.sh script.  The only changes
-made were those applied by update.sh and the addition of
-Makefile.in build files for the Mozilla build system.
+made were those applied by update.sh, the addition of
+Makefile.in build files for the Mozilla build system,
+and the following patches, which may be overwritten when
+included upstream.
+https://github.com/kinetiknz/cubeb/pull/398/commits/c8e66dee61a35e6a6d54e3630e1668bdbd6984b4
+https://github.com/kinetiknz/cubeb/pull/398/commits/2ed979bc891cf1a7822799947a357d4d3b625964
 
 The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
 
diff --git media/libcubeb/gtest/test_resampler.cpp media/libcubeb/gtest/test_resampler.cpp
index 3eebce950845..1f5fb8f9e14c 100644
--- media/libcubeb/gtest/test_resampler.cpp
+++ media/libcubeb/gtest/test_resampler.cpp
@@ -497,13 +497,15 @@ TEST(cubeb, resampler_output_only_noop)
   cubeb_resampler_destroy(resampler);
 }
 
-long test_drain_data_cb(cubeb_stream * /*stm*/, void * /*user_ptr*/,
+long test_drain_data_cb(cubeb_stream * /*stm*/, void * user_ptr,
                         const void * input_buffer,
                         void * output_buffer, long frame_count)
 {
   EXPECT_TRUE(output_buffer);
   EXPECT_TRUE(!input_buffer);
-  return frame_count - 10;
+  auto cb_count = static_cast<int *>(user_ptr);
+  (*cb_count)++;
+  return frame_count - 1;
 }
 
 TEST(cubeb, resampler_drain)
@@ -515,10 +517,11 @@ TEST(cubeb, resampler_drain)
   output_params.channels = 1;
   output_params.format = CUBEB_SAMPLE_FLOAT32NE;
   target_rate = 48000;
+  int cb_count = 0;
 
   cubeb_resampler * resampler =
     cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
-                           test_drain_data_cb, nullptr,
+                           test_drain_data_cb, &cb_count,
                            CUBEB_RESAMPLER_QUALITY_VOIP);
 
   const long out_frames = 128;
@@ -530,9 +533,9 @@ TEST(cubeb, resampler_drain)
                                out_buffer, out_frames);
   } while (got == out_frames);
 
-  /* If the above is not an infinite loop, the drain was a success, just mark
-   * this test as such. */
-  ASSERT_TRUE(true);
+  /* The callback should be called once but not again after returning <
+   * frame_count. */
+  ASSERT_EQ(cb_count, 1);
 
   cubeb_resampler_destroy(resampler);
 }
diff --git media/libcubeb/src/cubeb_resampler.cpp media/libcubeb/src/cubeb_resampler.cpp
index 6002bd2161a9..fcccede28e2d 100644
--- media/libcubeb/src/cubeb_resampler.cpp
+++ media/libcubeb/src/cubeb_resampler.cpp
@@ -145,26 +145,32 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
   assert(!input_buffer && (!input_frames_count || *input_frames_count == 0) &&
          output_buffer && output_frames_needed);
 
-  long got = 0;
-  T * out_unprocessed = nullptr;
-  long output_frames_before_processing = 0;
+  if (!draining) {
+    long got = 0;
+    T * out_unprocessed = nullptr;
+    long output_frames_before_processing = 0;
 
-  /* fill directly the input buffer of the output processor to save a copy */
-  output_frames_before_processing =
-    output_processor->input_needed_for_output(output_frames_needed);
+    /* fill directly the input buffer of the output processor to save a copy */
+    output_frames_before_processing =
+      output_processor->input_needed_for_output(output_frames_needed);
 
-  out_unprocessed =
-    output_processor->input_buffer(output_frames_before_processing);
+    out_unprocessed =
+      output_processor->input_buffer(output_frames_before_processing);
 
-  got = data_callback(stream, user_ptr,
-                      nullptr, out_unprocessed,
-                      output_frames_before_processing);
+    got = data_callback(stream, user_ptr,
+                        nullptr, out_unprocessed,
+                        output_frames_before_processing);
 
-  if (got < 0) {
-    return got;
-  }
+    if (got < output_frames_before_processing) {
+      draining = true;
 
-  output_processor->written(got);
+      if (got < 0) {
+        return got;
+      }
+    }
+
+    output_processor->written(got);
+  }
 
   /* Process the output. If not enough frames have been returned from the
   * callback, drain the processors. */
@@ -204,11 +210,16 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
 ::fill_internal_duplex(T * in_buffer, long * input_frames_count,
                        T * out_buffer, long output_frames_needed)
 {
+  if (draining) {
+    // discard input and drain any signal remaining in the resampler.
+    return output_processor->output(out_buffer, output_frames_needed);
+  }
+
   /* The input data, after eventual resampling. This is passed to the callback. */
   T * resampled_input = nullptr;
   /* The output buffer passed down in the callback, that might be resampled. */
   T * out_unprocessed = nullptr;
-  size_t output_frames_before_processing = 0;
+  long output_frames_before_processing = 0;
   /* The number of frames returned from the callback. */
   long got = 0;
 
@@ -243,8 +254,12 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
                       resampled_input, out_unprocessed,
                       output_frames_before_processing);
 
-  if (got < 0) {
-    return got;
+  if (got < output_frames_before_processing) {
+    draining = true;
+
+    if (got < 0) {
+      return got;
+    }
   }
 
   output_processor->written(got);
diff --git media/libcubeb/src/cubeb_resampler_internal.h media/libcubeb/src/cubeb_resampler_internal.h
index ca08ec571422..fb69992ff159 100644
--- media/libcubeb/src/cubeb_resampler_internal.h
+++ media/libcubeb/src/cubeb_resampler_internal.h
@@ -62,11 +62,11 @@ public:
     : channels(channels)
   {}
 protected:
-  size_t frames_to_samples(size_t frames)
+  size_t frames_to_samples(size_t frames) const
   {
     return frames * channels;
   }
-  size_t samples_to_frames(size_t samples)
+  size_t samples_to_frames(size_t samples) const
   {
     assert(!(samples % channels));
     return samples / channels;
@@ -157,6 +157,7 @@ private:
   cubeb_stream * const stream;
   const cubeb_data_callback data_callback;
   void * const user_ptr;
+  bool draining = false;
 };
 
 /** Handles one way of a (possibly) duplex resampler, working on interleaved
@@ -282,7 +283,7 @@ public:
    * exactly `output_frame_count` resampled frames. This can return a number
    * slightly bigger than what is strictly necessary, but it guaranteed that the
    * number of output frames will be exactly equal. */
-  uint32_t input_needed_for_output(uint32_t output_frame_count)
+  uint32_t input_needed_for_output(uint32_t output_frame_count) const
   {
     int32_t unresampled_frames_left = samples_to_frames(resampling_in_buffer.length());
     int32_t resampled_frames_left = samples_to_frames(resampling_out_buffer.length());
@@ -461,7 +462,7 @@ public:
    * @parameter frames_needed the number of frames one want to write into the
    * delay_line
    * @returns the number of frames one will get. */
-  size_t input_needed_for_output(uint32_t frames_needed)
+  size_t input_needed_for_output(uint32_t frames_needed) const
   {
     return frames_needed;
   }