Merge "Fast tracks"
diff --git a/src/android/AudioPlayer_to_android.cpp b/src/android/AudioPlayer_to_android.cpp
index ae526fe..0e371bd 100644
--- a/src/android/AudioPlayer_to_android.cpp
+++ b/src/android/AudioPlayer_to_android.cpp
@@ -1345,6 +1345,78 @@
}
+// Called from android_audioPlayer_realize for a PCM buffer queue player
+// to determine if it can use a fast track.
+static bool canUseFastTrack(CAudioPlayer *pAudioPlayer)
+{
+ assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
+ if (pAudioPlayer->mBufferQueue.mNumBuffers < 2) {
+ return false;
+ }
+
+ // Check a blacklist of interfaces that are incompatible with fast tracks.
+ // The alternative, to check a whitelist of compatible interfaces, is
+ // more maintainable but is too slow. As a compromise, in a debug build
+ // we use both methods and warn if they produce different results.
+ // In release builds, we only use the blacklist method.
+ // If a blacklisted interface is added after realization using
+ // DynamicInterfaceManagement::AddInterface,
+ // then this won't be detected but the interface will be ineffective.
+ bool blacklistResult = true;
+ static const unsigned blacklist[] = {
+ MPH_BASSBOOST,
+ MPH_EFFECTSEND,
+ MPH_ENVIRONMENTALREVERB,
+ MPH_EQUALIZER,
+ MPH_MUTESOLO, // FIXME move to whitelist when implemented by server
+ MPH_PLAYBACKRATE,
+ MPH_PRESETREVERB,
+ MPH_VIRTUALIZER,
+ MPH_VOLUME, // FIXME move to whitelist when implemented by server
+ MPH_ANDROIDEFFECT,
+ MPH_ANDROIDEFFECTSEND,
+ // FIXME The problem with a blacklist is remembering to add new interfaces here
+ };
+ for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
+ if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
+ blacklistResult = false;
+ break;
+ }
+ }
+#if LOG_NDEBUG == 0
+ bool whitelistResult = true;
+ static const unsigned whitelist[] = {
+ MPH_BUFFERQUEUE,
+ MPH_DYNAMICINTERFACEMANAGEMENT,
+ MPH_OBJECT,
+ MPH_METADATAEXTRACTION,
+ MPH_PLAY,
+ MPH_PREFETCHSTATUS,
+ MPH_ANDROIDCONFIGURATION,
+ MPH_ANDROIDSIMPLEBUFFERQUEUE,
+ MPH_ANDROIDBUFFERQUEUESOURCE,
+ };
+ for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
+ for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
+ if (mph == whitelist[i]) {
+ goto compatible;
+ }
+ }
+ if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
+ whitelistResult = false;
+ break;
+ }
+compatible: ;
+ }
+ if (whitelistResult != blacklistResult) {
+ ALOGW("whitelistResult != blacklistResult");
+ // and use blacklistResult below
+ }
+#endif
+ return blacklistResult;
+}
+
+
//-----------------------------------------------------------------------------
// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
@@ -1371,19 +1443,28 @@
uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
+ size_t frameCount;
+ audio_policy_output_flags_t policy;
+ if (canUseFastTrack(pAudioPlayer)) {
+ frameCount = 512; // FIXME hard-coded
+ policy = AUDIO_POLICY_OUTPUT_FLAG_FAST;
+ } else {
+ frameCount = 0;
+ policy = AUDIO_POLICY_OUTPUT_FLAG_NONE;
+ }
+
pAudioPlayer->mAudioTrack = new android::AudioTrack(
pAudioPlayer->mStreamType, // streamType
sampleRate, // sampleRate
sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
- //channel mask
- 0, // frameCount (here min)
- AUDIO_POLICY_OUTPUT_FLAG_NONE, // flags
+ // channel mask
+ frameCount, // frameCount
+ policy, // flags
audioTrack_callBack_pullFromBuffQueue, // callback
(void *) pAudioPlayer, // user
- 0 // FIXME find appropriate frame count // notificationFrame
- , pAudioPlayer->mSessionId
- );
+ 0, // FIXME find appropriate frame count // notificationFrame
+ pAudioPlayer->mSessionId);
android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
if (status != android::NO_ERROR) {
SL_LOGE("AudioTrack::initCheck status %u", status);