Bug 859805 - Make libcubeb work on Android 2.3. r=kinetik
authorPaul Adenot <paul@paul.cx>
Fri, 12 Apr 2013 14:50:02 +0200
changeset 128589 76166b14908a0e48a30b2647805005f8c9865f65
parent 128588 43acb3f9b06b35aaa23f2d708f180f5c39621ebc
child 128590 1165f67ccfb5b12306136e5ffc36ab5886790156
push id24532
push userryanvm@gmail.com
push dateFri, 12 Apr 2013 19:06:49 +0000
treeherdermozilla-central@2aff2d574a1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs859805
milestone23.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 859805 - Make libcubeb work on Android 2.3. r=kinetik
media/libcubeb/README_MOZILLA
media/libcubeb/src/android/audiotrack_definitions.h
media/libcubeb/src/cubeb_audiotrack.c
--- 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 bfaee9a6c7a15dfe8ae2ffda8dcd156d5a562010.
+The git commit ID used was a2f8aca29015dc0c0e0ac67e3710cd2df5d042c4.
--- a/media/libcubeb/src/android/audiotrack_definitions.h
+++ b/media/libcubeb/src/android/audiotrack_definitions.h
@@ -62,20 +62,20 @@ enum event_type {
 enum {
   AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS  = 0x1,
   AUDIO_CHANNEL_OUT_FRONT_RIGHT_ICS = 0x2,
   AUDIO_CHANNEL_OUT_MONO_ICS     = AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS,
   AUDIO_CHANNEL_OUT_STEREO_ICS   = (AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS | AUDIO_CHANNEL_OUT_FRONT_RIGHT_ICS)
 } AudioTrack_ChannelMapping_ICS;
 
 enum {
-  AUDIO_CHANNEL_OUT_FRONT_LEFT_Froyo = 0x4,
-  AUDIO_CHANNEL_OUT_FRONT_RIGHT_Froyo = 0x8,
-  AUDIO_CHANNEL_OUT_MONO_Froyo = AUDIO_CHANNEL_OUT_FRONT_LEFT_Froyo,
-  AUDIO_CHANNEL_OUT_STEREO_Froyo = (AUDIO_CHANNEL_OUT_FRONT_LEFT_Froyo | AUDIO_CHANNEL_OUT_FRONT_RIGHT_Froyo)
-} AudioTrack_ChannelMapping_Froyo;
+  AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy = 0x4,
+  AUDIO_CHANNEL_OUT_FRONT_RIGHT_Legacy = 0x8,
+  AUDIO_CHANNEL_OUT_MONO_Legacy = AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy,
+  AUDIO_CHANNEL_OUT_STEREO_Legacy = (AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy | AUDIO_CHANNEL_OUT_FRONT_RIGHT_Legacy)
+} AudioTrack_ChannelMapping_Legacy;
 
 typedef enum {
   AUDIO_FORMAT_PCM = 0x00000000,
   AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1,
   AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_16_BIT),
 } AudioTrack_SampleType;
 
--- a/media/libcubeb/src/cubeb_audiotrack.c
+++ b/media/libcubeb/src/cubeb_audiotrack.c
@@ -43,18 +43,22 @@
     }                                                                    \
   } while(0);
 
 static struct cubeb_ops const audiotrack_ops;
 void audiotrack_destroy(cubeb * context);
 void audiotrack_stream_destroy(cubeb_stream * stream);
 
 struct AudioTrack {
-               /* only available on ICS and later. */
+               /* only available on ICS and later. The second int paramter is in fact of type audio_stream_type_t. */
   /* static */ status_t (*get_min_frame_count)(int* frame_count, int stream_type, uint32_t rate);
+              /* if we have a recent ctor, but can't find the above symbol, we
+               * can get the minimum frame count with this signature, and we are
+               * running gingerbread. */
+  /* static */ status_t (*get_min_frame_count_gingerbread)(int* frame_count, int stream_type, uint32_t rate);
                /* if this symbol is not availble, and the next one is, we know
                 * we are on a Froyo (Android 2.2) device. */
                void* (*ctor)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int, int);
                void* (*ctor_froyo)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int);
                void* (*dtor)(void* instance);
                void (*start)(void* instance);
                void (*pause)(void* instance);
                uint32_t (*latency)(void* instance);
@@ -134,16 +138,24 @@ audiotrack_refill(int event, void* user,
 
 /* We are running on froyo if we found the right AudioTrack constructor */
 static int
 audiotrack_version_is_froyo(cubeb * ctx)
 {
   return ctx->klass.ctor_froyo != NULL;
 }
 
+/* We are running on gingerbread if we found the gingerbread signature for
+ * getMinFrameCount */
+static int
+audiotrack_version_is_gingerbread(cubeb * ctx)
+{
+  return ctx->klass.get_min_frame_count_gingerbread != NULL;
+}
+
 int
 audiotrack_get_min_frame_count(cubeb * ctx, cubeb_stream_params * params, int * min_frame_count)
 {
   status_t status;
   /* Recent Android have a getMinFrameCount method. On Froyo, we have to compute it by hand. */
   if (audiotrack_version_is_froyo(ctx)) {
     int samplerate, frame_count, latency, min_buffer_count;
     status = ctx->klass.get_output_frame_count(&frame_count, params->stream_type);
@@ -168,17 +180,21 @@ audiotrack_get_min_frame_count(cubeb * c
      * See https://android.googlesource.com/platform/frameworks/base/+/android-2.2.3_r2.1/media/libmedia/AudioTrack.cpp
      * around line 181 for Android 2.2 */
     min_buffer_count = latency / ((1000 * frame_count) / samplerate);
     min_buffer_count = min_buffer_count < 2 ? min_buffer_count : 2;
     *min_frame_count = (frame_count * params->rate * min_buffer_count) / samplerate;
     return CUBEB_OK;
   }
   /* Recent Android have a getMinFrameCount method. */
-  status = ctx->klass.get_min_frame_count(min_frame_count, params->stream_type, params->rate);
+  if (!audiotrack_version_is_gingerbread(ctx)) {
+    status = ctx->klass.get_min_frame_count(min_frame_count, param->stream_type, params->rate);
+  } else {
+    status = ctx->klass.get_min_frame_count_gingerbread(min_frame_count, param->stream_type, params->rate);
+  }
   if (status != 0) {
     ALOG("error getting the min frame count");
     return CUBEB_ERROR;
   }
   return CUBEB_OK;
 }
 
 int
@@ -210,37 +226,42 @@ audiotrack_init(cubeb ** context, char c
     DLSYM_DLERROR("_ZN7android10AudioTrackC1EijiiijPFviPvS1_ES1_i", ctx->klass.ctor_froyo, ctx->library);
     assert(ctx->klass.ctor_froyo);
   }
   DLSYM_DLERROR("_ZN7android10AudioTrackD1Ev", ctx->klass.dtor, ctx->library);
 
   DLSYM_DLERROR("_ZNK7android10AudioTrack7latencyEv", ctx->klass.latency, ctx->library);
   DLSYM_DLERROR("_ZNK7android10AudioTrack9initCheckEv", ctx->klass.check, ctx->library);
 
-  /* |getMinFrameCount| is not available on Froyo. */
+  /* |getMinFrameCount| is not available on Froyo, and is available on
+   * gingerbread and ICS with a different signature. */
   if (audiotrack_version_is_froyo(ctx)) {
     DLSYM_DLERROR("_ZN7android11AudioSystem19getOutputFrameCountEPii", ctx->klass.get_output_frame_count, ctx->library);
     DLSYM_DLERROR("_ZN7android11AudioSystem16getOutputLatencyEPji", ctx->klass.get_output_latency, ctx->library);
     DLSYM_DLERROR("_ZN7android11AudioSystem21getOutputSamplingRateEPii", ctx->klass.get_output_samplingrate, ctx->library);
   } else {
     DLSYM_DLERROR("_ZN7android10AudioTrack16getMinFrameCountEPi19audio_stream_type_tj", ctx->klass.get_min_frame_count, ctx->library);
+    if (!ctx->klass.get_min_frame_count) {
+      DLSYM_DLERROR("_ZN7android10AudioTrack16getMinFrameCountEPiij", ctx->klass.get_min_frame_count_gingerbread, ctx->library);
+    }
   }
 
   DLSYM_DLERROR("_ZN7android10AudioTrack5startEv", ctx->klass.start, ctx->library);
   DLSYM_DLERROR("_ZN7android10AudioTrack5pauseEv", ctx->klass.pause, ctx->library);
   DLSYM_DLERROR("_ZN7android10AudioTrack11getPositionEPj", ctx->klass.get_position, ctx->library);
   DLSYM_DLERROR("_ZN7android10AudioTrack17setMarkerPositionEj", ctx->klass.set_marker_position, ctx->library);
 
   /* check that we have a combination of symbol that makes sense */
   c = &ctx->klass;
   if(!((c->ctor || c->ctor_froyo) && /* at least on ctor. */
      c->dtor && c->latency && c->check &&
      /* at least one way to get the minimum frame count to request. */
      ((c->get_output_frame_count && c->get_output_latency && c->get_output_samplingrate) ||
-      c->get_min_frame_count) &&
+      c->get_min_frame_count ||
+      c->get_min_frame_count_gingerbread) &&
      c->start && c->pause && c->get_position && c->set_marker_position)) {
     ALOG("Could not find all the symbols we need.");
     audiotrack_destroy(ctx);
     return CUBEB_ERROR;
   }
 
   ctx->ops = &audiotrack_ops;
 
@@ -295,18 +316,19 @@ audiotrack_stream_init(cubeb * ctx, cube
   stm->state_callback = state_callback;
   stm->user_ptr = user_ptr;
   stm->params = stream_params;
 
   stm->instance = calloc(SIZE_AUDIOTRACK_INSTANCE, 1);
   (*(uint32_t*)((intptr_t)stm->instance + SIZE_AUDIOTRACK_INSTANCE - 4)) = 0xbaadbaad;
   assert(stm->instance && "cubeb: EOM");
 
-  if (audiotrack_version_is_froyo(ctx)) {
-    channels = stm->params.channels == 2 ? AUDIO_CHANNEL_OUT_STEREO_Froyo : AUDIO_CHANNEL_OUT_MONO_Froyo;
+  /* gingerbread uses old channel layout enum */
+  if (audiotrack_version_is_froyo(ctx) || audiotrack_version_is_gingerbread(ctx)) {
+    channels = stm->params.channels == 2 ? AUDIO_CHANNEL_OUT_STEREO_Legacy : AUDIO_CHANNEL_OUT_MONO_Legacy;
   } else {
     channels = stm->params.channels == 2 ? AUDIO_CHANNEL_OUT_STEREO_ICS : AUDIO_CHANNEL_OUT_MONO_ICS;
   }
 
   if (audiotrack_version_is_froyo(ctx)) {
     ctx->klass.ctor_froyo(stm->instance,
                           stm->params.stream_type,
                           stm->params.rate,