Bug 1264594 - Update libcubeb to revision 727121. r=kinetik
MozReview-Commit-ID: 26uBiAvDcFy
--- 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, ¶ms,
+ 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