Bug 1269692 - Update cubeb to revision 17e3048d0afa1152776fb1867cdb61c49fae69e4.
☠☠ backed out by 0c3e8422556e ☠ ☠
authorPaul Adenot <paul@paul.cx>
Tue, 03 May 2016 11:53:19 +0200
changeset 362935 094a64103807bc86dace7c7885328681b9dd2fd7
parent 362934 4a3493053ffb01506babf159fd0b43e177be0f62
child 362936 cf075d9de0633fbc5c7382f6219b0fbbef7e3c59
push id17058
push userbmo:ttromey@mozilla.com
push dateTue, 03 May 2016 14:35:18 +0000
bugs1269692, 1268675, 1268499
milestone49.0a1
Bug 1269692 - Update cubeb to revision 17e3048d0afa1152776fb1867cdb61c49fae69e4. This picks up the fixes for bug 1268675 and bug 1268499, both reviewed by kinetik. MozReview-Commit-ID: GLIDQgIGqch
media/libcubeb/README_MOZILLA
media/libcubeb/src/cubeb_pulse.c
media/libcubeb/src/cubeb_wasapi.cpp
--- a/media/libcubeb/README_MOZILLA
+++ b/media/libcubeb/README_MOZILLA
@@ -1,8 +1,8 @@
 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.
 
 The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
 
-The git commit ID used was 6194d5f4af9722e97084b5292a9f62a7f737a726.
+The git commit ID used was 17e3048d0afa1152776fb1867cdb61c49fae69e4.
--- a/media/libcubeb/src/cubeb_pulse.c
+++ b/media/libcubeb/src/cubeb_pulse.c
@@ -580,17 +580,17 @@ pulse_get_preferred_sample_rate(cubeb * 
 
   return CUBEB_OK;
 }
 
 static int
 pulse_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency_ms)
 {
   // According to PulseAudio developers, this is a safe minimum.
-  *latency_ms = 40;
+  *latency_ms = 25;
 
   return CUBEB_OK;
 }
 
 static void
 pulse_context_destroy(cubeb * ctx)
 {
   pa_operation * o;
@@ -1051,17 +1051,17 @@ pulse_sink_info_cb(pa_context * context,
 
   devinfo->format = CUBEB_DEVICE_FMT_ALL;
   devinfo->default_format = pulse_format_to_cubeb_format(info->sample_spec.format);
   devinfo->max_channels = info->channel_map.channels;
   devinfo->min_rate = 1;
   devinfo->max_rate = PA_RATE_MAX;
   devinfo->default_rate = info->sample_spec.rate;
 
-  devinfo->latency_lo_ms = 40;
+  devinfo->latency_lo_ms = 25;
   devinfo->latency_hi_ms = 400;
 
   pulse_ensure_dev_list_data_list_size (list_data);
   list_data->devinfo[list_data->count++] = devinfo;
 
   WRAP(pa_threaded_mainloop_signal)(list_data->context->mainloop, 0);
 }
 
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -19,16 +19,17 @@
 #include <avrt.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <cmath>
 #include <algorithm>
 #include <memory>
+#include <limits>
 
 #include "cubeb/cubeb.h"
 #include "cubeb-internal.h"
 #include "cubeb_resampler.h"
 #include "cubeb_utils.h"
 
 /* devicetopology.h missing in MinGW. */
 #ifndef __devicetopology_h__
@@ -641,24 +642,25 @@ bool get_input_buffer(cubeb_stream * stm
     hr = stm->capture_client->ReleaseBuffer(packet_size);
     if (FAILED(hr)) {
       LOG("FAILED to release intput buffer");
       return false;
     }
     offset += packet_size * input_channel_count;
   }
 
-  assert(stm->linear_input_buffer.length() == total_available_input);
+  assert(stm->linear_input_buffer.length() >= total_available_input &&
+         offset == total_available_input);
 
   return true;
 }
 
 /* Get an output buffer from the render_client. It has to be released before
  * exiting the callback. */
-bool get_output_buffer(cubeb_stream * stm, float *& buffer, size_t & frame_count)
+bool get_output_buffer(cubeb_stream * stm, size_t max_frames, float *& buffer, size_t & frame_count)
 {
   UINT32 padding_out;
   HRESULT hr;
 
   XASSERT(has_output(stm));
 
   hr = stm->output_client->GetCurrentPadding(&padding_out);
   if (FAILED(hr)) {
@@ -670,17 +672,17 @@ bool get_output_buffer(cubeb_stream * st
   if (stm->draining) {
     if (padding_out == 0) {
       stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
       return false;
     }
     return true;
   }
 
-  frame_count = stm->output_buffer_frame_count - padding_out;
+  frame_count = std::min(max_frames, stm->output_buffer_frame_count - padding_out);
   BYTE * output_buffer;
 
   hr = stm->render_client->GetBuffer(frame_count, &output_buffer);
   if (FAILED(hr)) {
     LOG("cannot get render buffer\n");
     return false;
   }
 
@@ -693,38 +695,44 @@ bool get_output_buffer(cubeb_stream * st
  * This function gets input data from a input device, and pass it along with an
  * output buffer to the resamplers.  */
 bool
 refill_callback_duplex(cubeb_stream * stm)
 {
   HRESULT hr;
   float * output_buffer;
   size_t output_frames;
+  size_t input_frames;
   bool rv;
 
   XASSERT(has_input(stm) && has_output(stm));
 
   rv = get_input_buffer(stm);
   if (!rv) {
     return rv;
   }
 
-  rv = get_output_buffer(stm, output_buffer, output_frames);
+  input_frames = stm->linear_input_buffer.length() / stm->input_stream_params.channels;
+  if (!input_frames) {
+    return true;
+  }
+
+  rv = get_output_buffer(stm, input_frames, output_buffer, output_frames);
   if (!rv) {
+    hr = stm->render_client->ReleaseBuffer(output_frames, 0);
     return rv;
   }
 
   /* This can only happen when debugging, and having breakpoints set in the
    * callback in a way that it makes the stream underrun. */
   if (output_frames == 0) {
     return true;
   }
 
   // When WASAPI has not filled the input buffer yet, send silence.
-  size_t input_frames = stm->linear_input_buffer.length() / stm->input_stream_params.channels;
   double output_duration = double(output_frames) / stm->output_mix_params.rate;
   double input_duration = double(input_frames) / stm->input_mix_params.rate;
   if (input_duration < output_duration) {
     size_t padding = round((output_duration - input_duration) * stm->input_mix_params.rate);
     LOG("padding silence: out=%f in=%f pad=%u\n", output_duration, input_duration, padding);
     stm->linear_input_buffer.push_front_silence(padding * stm->input_stream_params.channels);
   }
 
@@ -774,17 +782,18 @@ refill_callback_output(cubeb_stream * st
 {
   bool rv;
   HRESULT hr;
   float * output_buffer;
   size_t output_frames;
 
   XASSERT(!has_input(stm) && has_output(stm));
 
-  rv = get_output_buffer(stm, output_buffer, output_frames);
+  rv = get_output_buffer(stm, std::numeric_limits<size_t>::max(),
+                         output_buffer, output_frames);
   if (!rv) {
     return rv;
   }
   if (stm->draining || output_frames == 0) {
     return true;
   }