]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/opensles_android.c
Qt is GPLv2+
[vlc] / modules / audio_output / opensles_android.c
index cf6e9c5898576c4c5151f497ceedf5c687d10b49..434d78d8b47911dbddcb3db0e3d92a3029320ed2 100644 (file)
@@ -41,6 +41,8 @@
 #include <SLES/OpenSLES.h>
 #include <SLES/OpenSLES_Android.h>
 
+int aout_get_native_sample_rate(void);
+
 #define OPENSLES_BUFFERS 255 /* maximum number of buffers */
 #define OPENSLES_BUFLEN  10   /* ms */
 /*
@@ -168,8 +170,8 @@ static int TimeGet(audio_output_t* aout, mtime_t* restrict drift)
     *drift = (CLOCK_FREQ * OPENSLES_BUFLEN * st.count / 1000)
         + sys->samples * CLOCK_FREQ / sys->rate;
 
-    msg_Dbg(aout, "latency %"PRId64" ms, %d/%d buffers", *drift / 1000,
-        (int)st.count, OPENSLES_BUFFERS);
+    /* msg_Dbg(aout, "latency %"PRId64" ms, %d/%d buffers", *drift / 1000,
+        (int)st.count, OPENSLES_BUFFERS); */
 
     return 0;
 }
@@ -352,16 +354,6 @@ static void PlayedCallback (SLAndroidSimpleBufferQueueItf caller, void *pContext
 /*****************************************************************************
  *
  *****************************************************************************/
-static void Clean(aout_sys_t *sys)
-{
-    if (sys->playerObject)
-        Destroy(sys->playerObject);
-    if (sys->outputMixObject)
-        Destroy(sys->outputMixObject);
-    if (sys->engineObject)
-        Destroy(sys->engineObject);
-}
-
 static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
 {
     SLresult       result;
@@ -395,9 +387,28 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
     //create audio player
     const SLInterfaceID ids2[] = { sys->SL_IID_ANDROIDSIMPLEBUFFERQUEUE, sys->SL_IID_VOLUME };
     static const SLboolean req2[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
-    result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc,
+
+    if (aout_get_native_sample_rate() >= fmt->i_rate) {
+        result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc,
                                     &audioSnk, sizeof(ids2) / sizeof(*ids2),
                                     ids2, req2);
+    } else {
+        // Don't try to play back a sample rate higher than the native one,
+        // since OpenSL ES will try to use the fast path, which AudioFlinger
+        // will reject (fast path can't do resampling), and will end up with
+        // too small buffers for the resampling. See http://b.android.com/59453
+        // for details. This bug is still present in 4.4. If it is fixed later
+        // this workaround could be made conditional.
+        result = SL_RESULT_UNKNOWN_ERROR;
+    }
+    if (unlikely(result != SL_RESULT_SUCCESS)) {
+        /* Try again with a more sensible samplerate */
+        fmt->i_rate = 44100;
+        format_pcm.samplesPerSec = ((SLuint32) 44100 * 1000) ;
+        result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc,
+                &audioSnk, sizeof(ids2) / sizeof(*ids2),
+                ids2, req2);
+    }
     CHECK_OPENSL_ERROR("Failed to create audio player");
 
     result = Realize(sys->playerObject, SL_BOOLEAN_FALSE);
@@ -446,7 +457,11 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
     return VLC_SUCCESS;
 
 error:
-    Clean(sys);
+    if (sys->playerObject) {
+        Destroy(sys->playerObject);
+        sys->playerObject = NULL;
+    }
+
     return VLC_EGENERIC;
 }
 
@@ -460,6 +475,9 @@ static void Stop(audio_output_t *aout)
 
     free(sys->buf);
     block_ChainRelease(sys->p_buffer_chain);
+
+    Destroy(sys->playerObject);
+    sys->playerObject = NULL;
 }
 
 /*****************************************************************************
@@ -470,7 +488,8 @@ static void Close(vlc_object_t *obj)
     audio_output_t *aout = (audio_output_t *)obj;
     aout_sys_t *sys = aout->sys;
 
-    Clean(sys);
+    Destroy(sys->outputMixObject);
+    Destroy(sys->engineObject);
     dlclose(sys->p_so_handle);
     vlc_mutex_destroy(&sys->lock);
     free(sys);
@@ -553,7 +572,10 @@ static int Open (vlc_object_t *obj)
     return VLC_SUCCESS;
 
 error:
-    Clean(sys);
+    if (sys->outputMixObject)
+        Destroy(sys->outputMixObject);
+    if (sys->engineObject)
+        Destroy(sys->engineObject);
     if (sys->p_so_handle)
         dlclose(sys->p_so_handle);
     free(sys);