Bug 1264594 - Update libcubeb to revision 727121. r=kinetik
authorPaul Adenot <paul@paul.cx>
Thu, 14 Apr 2016 12:33:18 +0200
changeset 351758 8efa80a1d294c833136b3ac1db1027a46d72be6f
parent 351757 a9cfac4ce926828806b6fa4247c10d113866b9ac
child 351759 a29c9be8af13c01e80c8bf936289fc167d4ce90c
push id15527
push userbmo:rail@mozilla.com
push dateFri, 15 Apr 2016 01:44:41 +0000
reviewerskinetik
bugs1264594, 727121
milestone48.0a1
Bug 1264594 - Update libcubeb to revision 727121. r=kinetik MozReview-Commit-ID: 26uBiAvDcFy
media/libcubeb/README_MOZILLA
media/libcubeb/src/cubeb_opensl.c
media/libcubeb/src/cubeb_wasapi.cpp
media/libcubeb/tests/test_resampler.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 55afd4e682c25b1fc0509b0c75144ed6b3c7da1d.
+The git commit ID used was 727121c54a583256f2a24eb06889e07755cdc5d6.
--- a/media/libcubeb/src/cubeb_opensl.c
+++ b/media/libcubeb/src/cubeb_opensl.c
@@ -8,23 +8,26 @@
 #include <assert.h>
 #include <dlfcn.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <SLES/OpenSLES.h>
 #include <math.h>
 #include <time.h>
 #if defined(__ANDROID__)
+#include <dlfcn.h>
 #include <sys/system_properties.h>
 #include "android/sles_definitions.h"
 #include <SLES/OpenSLES_Android.h>
 #include <android/log.h>
 #include <android/api-level.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Cubeb_OpenSL" , ## args)
 #define ANDROID_VERSION_GINGERBREAD_MR1 10
+#define ANDROID_VERSION_LOLLIPOP 21
+#define ANDROID_VERSION_MARSHMALLOW 23
 #endif
 #include "cubeb/cubeb.h"
 #include "cubeb-internal.h"
 #include "cubeb_resampler.h"
 #include "cubeb-sles.h"
 
 static struct cubeb_ops const opensl_ops;
 
@@ -177,41 +180,65 @@ convert_stream_type_to_sl_stream(cubeb_s
   default:
     return 0xFFFFFFFF;
   }
 }
 #endif
 
 static void opensl_destroy(cubeb * ctx);
 
-#if defined(__ANDROID__) && (__ANDROID_API__ <= ANDROID_VERSION_GINGERBREAD_MR1)
+#if defined(__ANDROID__)
+
+#if (__ANDROID_API__ >= ANDROID_VERSION_LOLLIPOP)
+typedef int (system_property_get)(const char*, char*);
+
+static int
+__system_property_get(const char* name, char* value)
+{
+  void* libc = dlopen("libc.so", RTLD_LAZY);
+  if (!libc) {
+    LOG("Failed to open libc.so");
+    return -1;
+  }
+  system_property_get* func = (system_property_get*)
+                              dlsym(libc, "__system_property_get");
+  int ret = -1;
+  if (func) {
+    ret = func(name, value);
+  }
+  dlclose(libc);
+  return ret;
+}
+#endif
 
 static int
 get_android_version(void)
 {
   char version_string[PROP_VALUE_MAX];
 
   memset(version_string, 0, PROP_VALUE_MAX);
 
   int len = __system_property_get("ro.build.version.sdk", version_string);
   if (len <= 0) {
     LOG("Failed to get Android version!\n");
     return len;
   }
 
-  return (int)strtol(version_string, NULL, 10);
+  int version = (int)strtol(version_string, NULL, 10);
+  LOG("%d", version);
+  return version;
 }
 #endif
 
 /*static*/ int
 opensl_init(cubeb ** context, char const * context_name)
 {
   cubeb * ctx;
 
-#if defined(__ANDROID__) && (__ANDROID_API__ <= ANDROID_VERSION_GINGERBREAD_MR1)
+#if defined(__ANDROID__)
   int android_version = get_android_version();
   if (android_version > 0 && android_version <= ANDROID_VERSION_GINGERBREAD_MR1) {
     // Don't even attempt to run on Gingerbread and lower
     return CUBEB_ERROR;
   }
 #endif
 
   *context = NULL;
@@ -551,20 +578,36 @@ opensl_stream_init(cubeb * ctx, cubeb_st
                                ctx->SL_IID_VOLUME,
                                ctx->SL_IID_ANDROIDCONFIGURATION};
   const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
 #else
   const SLInterfaceID ids[] = {ctx->SL_IID_BUFFERQUEUE, ctx->SL_IID_VOLUME};
   const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
 #endif
   assert(NELEMS(ids) == NELEMS(req));
-  SLresult res = (*ctx->eng)->CreateAudioPlayer(ctx->eng, &stm->playerObj,
-                                                &source, &sink, NELEMS(ids), ids, req);
 
   uint32_t preferred_sampling_rate = stm->inputrate;
+#if defined(__ANDROID__)
+  if (get_android_version() >= ANDROID_VERSION_MARSHMALLOW) {
+    // Reset preferred samping rate to trigger fallback to native sampling rate.
+    preferred_sampling_rate = 0;
+    if (opensl_get_min_latency(ctx, *output_stream_params, &latency) != CUBEB_OK) {
+      // Default to AudioFlinger's advertised fast track latency of 10ms.
+      latency = 10;
+    }
+    stm->latency = latency;
+  }
+#endif
+
+  SLresult res = SL_RESULT_CONTENT_UNSUPPORTED;
+  if (preferred_sampling_rate) {
+    res = (*ctx->eng)->CreateAudioPlayer(ctx->eng, &stm->playerObj, &source,
+                                         &sink, NELEMS(ids), ids, req);
+  }
+
   // Sample rate not supported? Try again with primary sample rate!
   if (res == SL_RESULT_CONTENT_UNSUPPORTED) {
     if (opensl_get_preferred_sample_rate(ctx, &preferred_sampling_rate)) {
       opensl_stream_destroy(stm);
       return CUBEB_ERROR;
     }
 
     format.samplesPerSec = preferred_sampling_rate * 1000;
@@ -573,25 +616,28 @@ opensl_stream_init(cubeb * ctx, cubeb_st
   }
 
   if (res != SL_RESULT_SUCCESS) {
     opensl_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   stm->outputrate = preferred_sampling_rate;
-  stm->bytespersec = preferred_sampling_rate * stm->framesize;
+  stm->bytespersec = stm->outputrate * stm->framesize;
   stm->queuebuf_len = (stm->bytespersec * latency) / (1000 * NBUFS);
   // round up to the next multiple of stm->framesize, if needed.
   if (stm->queuebuf_len % stm->framesize) {
     stm->queuebuf_len += stm->framesize - (stm->queuebuf_len % stm->framesize);
   }
 
-  stm->resampler = cubeb_resampler_create(stm, NULL, output_stream_params,
-                                          preferred_sampling_rate,
+  cubeb_stream_params params = *output_stream_params;
+  params.rate = preferred_sampling_rate;
+
+  stm->resampler = cubeb_resampler_create(stm, NULL, &params,
+                                          output_stream_params->rate,
                                           data_callback,
                                           user_ptr,
                                           CUBEB_RESAMPLER_QUALITY_DEFAULT);
 
   if (!stm->resampler) {
     opensl_stream_destroy(stm);
     return CUBEB_ERROR;
   }
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -1609,19 +1609,21 @@ wasapi_stream_init(cubeb * context, cube
 
   stm->context = context;
   stm->data_callback = data_callback;
   stm->state_callback = state_callback;
   stm->user_ptr = user_ptr;
   stm->draining = false;
   if (input_stream_params) {
     stm->input_stream_params = *input_stream_params;
+    stm->input_device = input_device;
   }
   if (output_stream_params) {
     stm->output_stream_params = *output_stream_params;
+    stm->output_device = output_device;
   }
   stm->latency = latency;
   stm->volume = 1.0;
 
   stm->stream_reset_lock = new owned_critical_section();
 
   stm->reconfigure_event = CreateEvent(NULL, 0, 0, NULL);
   if (!stm->reconfigure_event) {
@@ -1718,69 +1720,75 @@ void wasapi_stream_destroy(cubeb_stream 
     close_wasapi_stream(stm);
   }
 
   delete stm->stream_reset_lock;
 
   free(stm);
 }
 
-int stream_start_one_side(cubeb_stream * stm, IAudioClient * client)
+enum StreamDirection {
+  OUTPUT,
+  INPUT
+};
+
+int stream_start_one_side(cubeb_stream * stm, StreamDirection dir)
 {
-  XASSERT(stm->output_client == client || stm->input_client == client);
+  XASSERT((dir == OUTPUT && stm->output_client) ||
+          (dir == INPUT && stm->input_client));
 
-  HRESULT hr = client->Start();
+  HRESULT hr = dir == OUTPUT ? stm->output_client->Start() : stm->input_client->Start();
   if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
     LOG("audioclient invalidated for %s device, reconfiguring\n",
-        stm->output_client == client ? "output" : "input", hr);
+        dir == OUTPUT ? "output" : "input", hr);
 
     BOOL ok = ResetEvent(stm->reconfigure_event);
     if (!ok) {
       LOG("resetting reconfig event failed for %s stream: %x\n",
-          stm->output_client == client ? "output" : "input", GetLastError());
+          dir == OUTPUT ? "output" : "input", GetLastError());
     }
 
     close_wasapi_stream(stm);
     int r = setup_wasapi_stream(stm);
     if (r != CUBEB_OK) {
       LOG("reconfigure failed\n");
       return r;
     }
 
-    HRESULT hr = client->Start();
+    HRESULT hr = OUTPUT ? stm->output_client->Start() : stm->input_client->Start();
     if (FAILED(hr)) {
       LOG("could not start the %s stream after reconfig: %x (%s)\n",
-        stm->output_client == client ? "output" : "input", hr);
+          dir == OUTPUT ? "output" : "input", hr);
       return CUBEB_ERROR;
     }
   } else if (FAILED(hr)) {
     LOG("could not start the %s stream: %x.\n",
-        stm->output_client == client ? "output" : "input", hr);
+        dir == OUTPUT ? "output" : "input", hr);
     return CUBEB_ERROR;
   }
 
   return CUBEB_OK;
 }
 
 int wasapi_stream_start(cubeb_stream * stm)
 {
   int rv;
   auto_lock lock(stm->stream_reset_lock);
 
   XASSERT(stm && !stm->thread && !stm->shutdown_event);
 
-  if (has_output(stm)) {
-    rv = stream_start_one_side(stm, stm->output_client);
+  if (stm->output_client) {
+    rv = stream_start_one_side(stm, OUTPUT);
     if (rv != CUBEB_OK) {
       return rv;
     }
   }
 
   if (stm->input_client) {
-    rv = stream_start_one_side(stm, stm->input_client);
+    rv = stream_start_one_side(stm, INPUT);
     if (rv != CUBEB_OK) {
       return rv;
     }
   }
 
   stm->shutdown_event = CreateEvent(NULL, 0, 0, NULL);
   if (!stm->shutdown_event) {
     LOG("Can't create the shutdown event, error: %x\n", GetLastError());
--- a/media/libcubeb/tests/test_resampler.cpp
+++ b/media/libcubeb/tests/test_resampler.cpp
@@ -88,17 +88,16 @@ void dump(const char * name, T * frames,
 
   if (!file) {
     fprintf(stderr, "error opening %s\n", name);
     return;
   }
 
   if (count != fwrite(frames, sizeof(T), count, file)) {
     fprintf(stderr, "error writing to %s\n", name);
-    return;
   }
   fclose(file);
 }
 #else
 template<typename T>
 void dump(const char * name, T * frames, size_t count)
 { }
 #endif