Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sles_allinclusive.h"
     18 #include "android_prompts.h"
     19 #include "android/android_AudioToCbRenderer.h"
     20 #include "android/android_StreamPlayer.h"
     21 #include "android/android_LocAVPlayer.h"
     22 #include "android/include/AacBqToPcmCbRenderer.h"
     23 #include "android/channels.h"
     24 
     25 #include <android_runtime/AndroidRuntime.h>
     26 #include <binder/IServiceManager.h>
     27 #include <utils/StrongPointer.h>
     28 #include <audiomanager/AudioManager.h>
     29 #include <audiomanager/IAudioManager.h>
     30 
     31 #include <fcntl.h>
     32 #include <sys/stat.h>
     33 #include <unistd.h>
     34 
     35 #include <system/audio.h>
     36 #include <SLES/OpenSLES_Android.h>
     37 
     38 template class android::KeyedVector<SLuint32,
     39                                     android::sp<android::AudioEffect> > ;
     40 
     41 #define KEY_STREAM_TYPE_PARAMSIZE  sizeof(SLint32)
     42 #define KEY_PERFORMANCE_MODE_PARAMSIZE  sizeof(SLint32)
     43 
     44 #define AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE  500
     45 #define AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE 2000
     46 
     47 #define MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE
     48 #define MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE
     49 
     50 //-----------------------------------------------------------------------------
     51 // Inline functions to communicate with AudioService through the native AudioManager interface
     52 inline void audioManagerPlayerEvent(CAudioPlayer* ap, android::player_state_t event) {
     53     if (ap->mObject.mEngine->mAudioManager != 0) {
     54         ap->mObject.mEngine->mAudioManager->playerEvent(ap->mPIId, event);
     55     }
     56 }
     57 
     58 //-----------------------------------------------------------------------------
     59 // get an audio attributes usage for a stream type, but only consider stream types
     60 // that can successfully be set through SLAndroidConfigurationItf. It is invalid to call
     61 // this function with other stream types.
     62 audio_usage_t usageForStreamType(audio_stream_type_t streamType) {
     63     switch (streamType) {
     64     case AUDIO_STREAM_MUSIC:
     65         return AUDIO_USAGE_MEDIA;
     66     case AUDIO_STREAM_VOICE_CALL:
     67         return AUDIO_USAGE_VOICE_COMMUNICATION;
     68     case AUDIO_STREAM_SYSTEM:
     69         return AUDIO_USAGE_ASSISTANCE_SONIFICATION;
     70     case AUDIO_STREAM_RING:
     71         return AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
     72     case AUDIO_STREAM_ALARM:
     73         return AUDIO_USAGE_ALARM;
     74     case AUDIO_STREAM_NOTIFICATION:
     75         return AUDIO_USAGE_NOTIFICATION;
     76     default:
     77         // shouldn't happen, stream types on AudioPlayer have been sanitized by now.
     78         SL_LOGE("invalid stream type %d when converting to usage", streamType);
     79         return usageForStreamType(ANDROID_DEFAULT_OUTPUT_STREAM_TYPE);
     80     }
     81 }
     82 
     83 //-----------------------------------------------------------------------------
     84 // FIXME this method will be absorbed into android_audioPlayer_setPlayState() once
     85 //       bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object
     86 SLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState,
     87         AndroidObjectState* pObjState) {
     88     SLresult result = SL_RESULT_SUCCESS;
     89     AndroidObjectState objState = *pObjState;
     90 
     91     switch (playState) {
     92      case SL_PLAYSTATE_STOPPED:
     93          SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
     94          ap->stop();
     95          break;
     96      case SL_PLAYSTATE_PAUSED:
     97          SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
     98          switch (objState) {
     99          case ANDROID_UNINITIALIZED:
    100              *pObjState = ANDROID_PREPARING;
    101              ap->prepare();
    102              break;
    103          case ANDROID_PREPARING:
    104              break;
    105          case ANDROID_READY:
    106              ap->pause();
    107              break;
    108          default:
    109              SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
    110              result = SL_RESULT_INTERNAL_ERROR;
    111              break;
    112          }
    113          break;
    114      case SL_PLAYSTATE_PLAYING: {
    115          SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
    116          switch (objState) {
    117          case ANDROID_UNINITIALIZED:
    118              *pObjState = ANDROID_PREPARING;
    119              ap->prepare();
    120              // intended fall through
    121          case ANDROID_PREPARING:
    122              // intended fall through
    123          case ANDROID_READY:
    124              ap->play();
    125              break;
    126          default:
    127              SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
    128              result = SL_RESULT_INTERNAL_ERROR;
    129              break;
    130          }
    131          }
    132          break;
    133      default:
    134          // checked by caller, should not happen
    135          SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
    136          result = SL_RESULT_INTERNAL_ERROR;
    137          break;
    138      }
    139 
    140     return result;
    141 }
    142 
    143 
    144 //-----------------------------------------------------------------------------
    145 // Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data
    146 // from a URI or FD, to write the decoded audio data to a buffer queue
    147 static size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, CAudioPlayer* ap) {
    148     if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
    149         // it is not safe to enter the callback (the player is about to go away)
    150         return 0;
    151     }
    152     size_t sizeConsumed = 0;
    153     SL_LOGD("received %zu bytes from decoder", size);
    154     slBufferQueueCallback callback = NULL;
    155     void * callbackPContext = NULL;
    156 
    157     // push decoded data to the buffer queue
    158     object_lock_exclusive(&ap->mObject);
    159 
    160     if (ap->mBufferQueue.mState.count != 0) {
    161         assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
    162 
    163         BufferHeader *oldFront = ap->mBufferQueue.mFront;
    164         BufferHeader *newFront = &oldFront[1];
    165 
    166         uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
    167         if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) {
    168             // room to consume the whole or rest of the decoded data in one shot
    169             ap->mBufferQueue.mSizeConsumed += size;
    170             // consume data but no callback to the BufferQueue interface here
    171             memcpy(pDest, data, size);
    172             sizeConsumed = size;
    173         } else {
    174             // push as much as possible of the decoded data into the buffer queue
    175             sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
    176 
    177             // the buffer at the head of the buffer queue is full, update the state
    178             ap->mBufferQueue.mSizeConsumed = 0;
    179             if (newFront == &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) {
    180                 newFront = ap->mBufferQueue.mArray;
    181             }
    182             ap->mBufferQueue.mFront = newFront;
    183 
    184             ap->mBufferQueue.mState.count--;
    185             ap->mBufferQueue.mState.playIndex++;
    186             // consume data
    187             memcpy(pDest, data, sizeConsumed);
    188             // data has been copied to the buffer, and the buffer queue state has been updated
    189             // we will notify the client if applicable
    190             callback = ap->mBufferQueue.mCallback;
    191             // save callback data
    192             callbackPContext = ap->mBufferQueue.mContext;
    193         }
    194 
    195     } else {
    196         // no available buffers in the queue to write the decoded data
    197         sizeConsumed = 0;
    198     }
    199 
    200     object_unlock_exclusive(&ap->mObject);
    201     // notify client
    202     if (NULL != callback) {
    203         (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
    204     }
    205 
    206     ap->mCallbackProtector->exitCb();
    207     return sizeConsumed;
    208 }
    209 
    210 
    211 //-----------------------------------------------------------------------------
    212 #define LEFT_CHANNEL_MASK  AUDIO_CHANNEL_OUT_FRONT_LEFT
    213 #define RIGHT_CHANNEL_MASK AUDIO_CHANNEL_OUT_FRONT_RIGHT
    214 
    215 void android_audioPlayer_volumeUpdate(CAudioPlayer* ap)
    216 {
    217     assert(ap != NULL);
    218 
    219     // the source's channel count, where zero means unknown
    220     SLuint8 channelCount = ap->mNumChannels;
    221 
    222     // whether each channel is audible
    223     bool leftAudibilityFactor, rightAudibilityFactor;
    224 
    225     // mute has priority over solo
    226     if (channelCount >= STEREO_CHANNELS) {
    227         if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
    228             // left muted
    229             leftAudibilityFactor = false;
    230         } else {
    231             // left not muted
    232             if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
    233                 // left soloed
    234                 leftAudibilityFactor = true;
    235             } else {
    236                 // left not soloed
    237                 if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
    238                     // right solo silences left
    239                     leftAudibilityFactor = false;
    240                 } else {
    241                     // left and right are not soloed, and left is not muted
    242                     leftAudibilityFactor = true;
    243                 }
    244             }
    245         }
    246 
    247         if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
    248             // right muted
    249             rightAudibilityFactor = false;
    250         } else {
    251             // right not muted
    252             if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
    253                 // right soloed
    254                 rightAudibilityFactor = true;
    255             } else {
    256                 // right not soloed
    257                 if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
    258                     // left solo silences right
    259                     rightAudibilityFactor = false;
    260                 } else {
    261                     // left and right are not soloed, and right is not muted
    262                     rightAudibilityFactor = true;
    263                 }
    264             }
    265         }
    266 
    267     // channel mute and solo are ignored for mono and unknown channel count sources
    268     } else {
    269         leftAudibilityFactor = true;
    270         rightAudibilityFactor = true;
    271     }
    272 
    273     // compute volumes without setting
    274     const bool audibilityFactors[2] = {leftAudibilityFactor, rightAudibilityFactor};
    275     float volumes[2];
    276     android_player_volumeUpdate(volumes, &ap->mVolume, channelCount, ap->mAmplFromDirectLevel,
    277             audibilityFactors);
    278     float leftVol = volumes[0], rightVol = volumes[1];
    279 
    280     // set volume on the underlying media player or audio track
    281     if (ap->mAPlayer != 0) {
    282         ap->mAPlayer->setVolume(leftVol, rightVol);
    283     } else if (ap->mTrackPlayer != 0) {
    284         ap->mTrackPlayer->setPlayerVolume(leftVol, rightVol);
    285     }
    286 
    287     // changes in the AudioPlayer volume must be reflected in the send level:
    288     //  in SLEffectSendItf or in SLAndroidEffectSendItf?
    289     // FIXME replace interface test by an internal API once we have one.
    290     if (NULL != ap->mEffectSend.mItf) {
    291         for (unsigned int i=0 ; i<AUX_MAX ; i++) {
    292             if (ap->mEffectSend.mEnableLevels[i].mEnable) {
    293                 android_fxSend_setSendLevel(ap,
    294                         ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
    295                 // there's a single aux bus on Android, so we can stop looking once the first
    296                 // aux effect is found.
    297                 break;
    298             }
    299         }
    300     } else if (NULL != ap->mAndroidEffectSend.mItf) {
    301         android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
    302     }
    303 }
    304 
    305 // Called by android_audioPlayer_volumeUpdate and android_mediaPlayer_volumeUpdate to compute
    306 // volumes, but setting volumes is handled by the caller.
    307 
    308 void android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf, unsigned
    309 channelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/)
    310 {
    311     assert(pVolumes != NULL);
    312     assert(volumeItf != NULL);
    313     // OK for audibilityFactors to be NULL
    314 
    315     bool leftAudibilityFactor, rightAudibilityFactor;
    316 
    317     // apply player mute factor
    318     // note that AudioTrack has mute() but not MediaPlayer, so it's easier to use volume
    319     // to mute for both rather than calling mute() for AudioTrack
    320 
    321     // player is muted
    322     if (volumeItf->mMute) {
    323         leftAudibilityFactor = false;
    324         rightAudibilityFactor = false;
    325     // player isn't muted, and channel mute/solo audibility factors are available (AudioPlayer)
    326     } else if (audibilityFactors != NULL) {
    327         leftAudibilityFactor = audibilityFactors[0];
    328         rightAudibilityFactor = audibilityFactors[1];
    329     // player isn't muted, and channel mute/solo audibility factors aren't available (MediaPlayer)
    330     } else {
    331         leftAudibilityFactor = true;
    332         rightAudibilityFactor = true;
    333     }
    334 
    335     // compute amplification as the combination of volume level and stereo position
    336     //   amplification (or attenuation) from volume level
    337     float amplFromVolLevel = sles_to_android_amplification(volumeItf->mLevel);
    338     //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
    339     float leftVol  = amplFromVolLevel * amplFromDirectLevel;
    340     float rightVol = leftVol;
    341 
    342     // amplification from stereo position
    343     if (volumeItf->mEnableStereoPosition) {
    344         // Left/right amplification (can be attenuations) factors derived for the StereoPosition
    345         float amplFromStereoPos[STEREO_CHANNELS];
    346         // panning law depends on content channel count: mono to stereo panning vs stereo balance
    347         if (1 == channelCount) {
    348             // mono to stereo panning
    349             double theta = (1000+volumeItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
    350             amplFromStereoPos[0] = cos(theta);
    351             amplFromStereoPos[1] = sin(theta);
    352         // channel count is 0 (unknown), 2 (stereo), or > 2 (multi-channel)
    353         } else {
    354             // stereo balance
    355             if (volumeItf->mStereoPosition > 0) {
    356                 amplFromStereoPos[0] = (1000-volumeItf->mStereoPosition)/1000.0f;
    357                 amplFromStereoPos[1] = 1.0f;
    358             } else {
    359                 amplFromStereoPos[0] = 1.0f;
    360                 amplFromStereoPos[1] = (1000+volumeItf->mStereoPosition)/1000.0f;
    361             }
    362         }
    363         leftVol  *= amplFromStereoPos[0];
    364         rightVol *= amplFromStereoPos[1];
    365     }
    366 
    367     // apply audibility factors
    368     if (!leftAudibilityFactor) {
    369         leftVol = 0.0;
    370     }
    371     if (!rightAudibilityFactor) {
    372         rightVol = 0.0;
    373     }
    374 
    375     // return the computed volumes
    376     pVolumes[0] = leftVol;
    377     pVolumes[1] = rightVol;
    378 }
    379 
    380 //-----------------------------------------------------------------------------
    381 void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
    382     //SL_LOGV("received event EVENT_MARKER from AudioTrack");
    383     slPlayCallback callback = NULL;
    384     void* callbackPContext = NULL;
    385 
    386     interface_lock_shared(&ap->mPlay);
    387     callback = ap->mPlay.mCallback;
    388     callbackPContext = ap->mPlay.mContext;
    389     interface_unlock_shared(&ap->mPlay);
    390 
    391     if (NULL != callback) {
    392         // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
    393         (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
    394     }
    395 }
    396 
    397 //-----------------------------------------------------------------------------
    398 void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
    399     //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
    400     slPlayCallback callback = NULL;
    401     void* callbackPContext = NULL;
    402 
    403     interface_lock_shared(&ap->mPlay);
    404     callback = ap->mPlay.mCallback;
    405     callbackPContext = ap->mPlay.mContext;
    406     interface_unlock_shared(&ap->mPlay);
    407 
    408     if (NULL != callback) {
    409         // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
    410         (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
    411     }
    412 }
    413 
    414 
    415 //-----------------------------------------------------------------------------
    416 void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
    417     slPlayCallback callback = NULL;
    418     void* callbackPContext = NULL;
    419 
    420     interface_lock_shared(&ap->mPlay);
    421     callback = ap->mPlay.mCallback;
    422     callbackPContext = ap->mPlay.mContext;
    423     bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
    424     interface_unlock_shared(&ap->mPlay);
    425 
    426     if ((NULL != callback) && headStalled) {
    427         (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
    428     }
    429 }
    430 
    431 
    432 //-----------------------------------------------------------------------------
    433 /**
    434  * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
    435  *
    436  * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
    437  *       needs to be changed when the player reaches the end of the content to play. This is
    438  *       relative to what the specification describes for buffer queues vs the
    439  *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
    440  *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
    441  *          buffers in the queue, the playing of audio data stops. The player remains in the
    442  *          SL_PLAYSTATE_PLAYING state."
    443  *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
    444  *          of the current content and the player has paused."
    445  */
    446 void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
    447         bool needToLock) {
    448     //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
    449     //        needToLock);
    450     slPlayCallback playCallback = NULL;
    451     void * playContext = NULL;
    452     // SLPlayItf callback or no callback?
    453     if (needToLock) {
    454         interface_lock_exclusive(&ap->mPlay);
    455     }
    456     if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
    457         playCallback = ap->mPlay.mCallback;
    458         playContext = ap->mPlay.mContext;
    459     }
    460     if (setPlayStateToPaused) {
    461         ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
    462     }
    463     if (needToLock) {
    464         interface_unlock_exclusive(&ap->mPlay);
    465     }
    466     // enqueue callback with no lock held
    467     if (NULL != playCallback) {
    468 #ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
    469         (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
    470 #else
    471         SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
    472                 SL_PLAYEVENT_HEADATEND);
    473         if (SL_RESULT_SUCCESS != result) {
    474             ALOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback,
    475                     &ap->mPlay.mItf, playContext);
    476         }
    477 #endif
    478     }
    479 
    480 }
    481 
    482 
    483 //-----------------------------------------------------------------------------
    484 SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
    485     SLresult result = SL_RESULT_SUCCESS;
    486     SL_LOGV("type %d", type);
    487 
    488     audio_stream_type_t newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
    489     switch (type) {
    490     case SL_ANDROID_STREAM_VOICE:
    491         newStreamType = AUDIO_STREAM_VOICE_CALL;
    492         break;
    493     case SL_ANDROID_STREAM_SYSTEM:
    494         newStreamType = AUDIO_STREAM_SYSTEM;
    495         break;
    496     case SL_ANDROID_STREAM_RING:
    497         newStreamType = AUDIO_STREAM_RING;
    498         break;
    499     case SL_ANDROID_STREAM_MEDIA:
    500         newStreamType = AUDIO_STREAM_MUSIC;
    501         break;
    502     case SL_ANDROID_STREAM_ALARM:
    503         newStreamType = AUDIO_STREAM_ALARM;
    504         break;
    505     case SL_ANDROID_STREAM_NOTIFICATION:
    506         newStreamType = AUDIO_STREAM_NOTIFICATION;
    507         break;
    508     default:
    509         SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
    510         result = SL_RESULT_PARAMETER_INVALID;
    511         break;
    512     }
    513 
    514     // stream type needs to be set before the object is realized
    515     // (ap->mTrackPlayer->mAudioTrack is supposed to be NULL until then)
    516     if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
    517         SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
    518         result = SL_RESULT_PRECONDITIONS_VIOLATED;
    519     } else {
    520         ap->mStreamType = newStreamType;
    521     }
    522 
    523     return result;
    524 }
    525 
    526 //-----------------------------------------------------------------------------
    527 SLresult audioPlayer_setPerformanceMode(CAudioPlayer* ap, SLuint32 mode) {
    528     SLresult result = SL_RESULT_SUCCESS;
    529     SL_LOGV("performance mode set to %d", mode);
    530 
    531     SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
    532     switch (mode) {
    533     case SL_ANDROID_PERFORMANCE_LATENCY:
    534         perfMode = ANDROID_PERFORMANCE_MODE_LATENCY;
    535         break;
    536     case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS:
    537         perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
    538         break;
    539     case SL_ANDROID_PERFORMANCE_NONE:
    540         perfMode = ANDROID_PERFORMANCE_MODE_NONE;
    541         break;
    542     case SL_ANDROID_PERFORMANCE_POWER_SAVING:
    543         perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING;
    544         break;
    545     default:
    546         SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN);
    547         result = SL_RESULT_PARAMETER_INVALID;
    548         break;
    549     }
    550 
    551     // performance mode needs to be set before the object is realized
    552     // (ap->mTrackPlayer->mAudioTrack is supposed to be NULL until then)
    553     if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
    554         SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED);
    555         result = SL_RESULT_PRECONDITIONS_VIOLATED;
    556     } else {
    557         ap->mPerformanceMode = perfMode;
    558     }
    559 
    560     return result;
    561 }
    562 
    563 //-----------------------------------------------------------------------------
    564 SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
    565     SLresult result = SL_RESULT_SUCCESS;
    566 
    567     switch (ap->mStreamType) {
    568     case AUDIO_STREAM_VOICE_CALL:
    569         *pType = SL_ANDROID_STREAM_VOICE;
    570         break;
    571     case AUDIO_STREAM_SYSTEM:
    572         *pType = SL_ANDROID_STREAM_SYSTEM;
    573         break;
    574     case AUDIO_STREAM_RING:
    575         *pType = SL_ANDROID_STREAM_RING;
    576         break;
    577     case AUDIO_STREAM_DEFAULT:
    578     case AUDIO_STREAM_MUSIC:
    579         *pType = SL_ANDROID_STREAM_MEDIA;
    580         break;
    581     case AUDIO_STREAM_ALARM:
    582         *pType = SL_ANDROID_STREAM_ALARM;
    583         break;
    584     case AUDIO_STREAM_NOTIFICATION:
    585         *pType = SL_ANDROID_STREAM_NOTIFICATION;
    586         break;
    587     default:
    588         result = SL_RESULT_INTERNAL_ERROR;
    589         *pType = SL_ANDROID_STREAM_MEDIA;
    590         break;
    591     }
    592 
    593     return result;
    594 }
    595 
    596 //-----------------------------------------------------------------------------
    597 SLresult audioPlayer_getPerformanceMode(CAudioPlayer* ap, SLuint32 *pMode) {
    598     SLresult result = SL_RESULT_SUCCESS;
    599 
    600     switch (ap->mPerformanceMode) {
    601     case ANDROID_PERFORMANCE_MODE_LATENCY:
    602         *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
    603         break;
    604     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
    605         *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS;
    606         break;
    607     case ANDROID_PERFORMANCE_MODE_NONE:
    608         *pMode = SL_ANDROID_PERFORMANCE_NONE;
    609         break;
    610     case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
    611         *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING;
    612         break;
    613     default:
    614         result = SL_RESULT_INTERNAL_ERROR;
    615         *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
    616         break;
    617     }
    618 
    619     return result;
    620 }
    621 
    622 //-----------------------------------------------------------------------------
    623 void audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
    624     if ((ap->mTrackPlayer->mAudioTrack != 0) && (ap->mAuxEffect != 0)) {
    625         android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
    626     }
    627 }
    628 
    629 
    630 //-----------------------------------------------------------------------------
    631 /*
    632  * returns true if the given data sink is supported by AudioPlayer that doesn't
    633  *   play to an OutputMix object, false otherwise
    634  *
    635  * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
    636  */
    637 bool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
    638     bool result = true;
    639     const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
    640     const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
    641 
    642     switch (sinkLocatorType) {
    643 
    644     case SL_DATALOCATOR_BUFFERQUEUE:
    645     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    646         if (SL_DATAFORMAT_PCM != sinkFormatType) {
    647             SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM",
    648                     (unsigned)sinkFormatType);
    649             result = false;
    650         }
    651         // it's no use checking the PCM format fields because additional characteristics
    652         // such as the number of channels, or sample size are unknown to the player at this stage
    653         break;
    654 
    655     default:
    656         SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
    657         result = false;
    658         break;
    659     }
    660 
    661     return result;
    662 }
    663 
    664 
    665 //-----------------------------------------------------------------------------
    666 /*
    667  * returns the Android object type if the locator type combinations for the source and sinks
    668  *   are supported by this implementation, INVALID_TYPE otherwise
    669  */
    670 static
    671 AndroidObjectType audioPlayer_getAndroidObjectTypeForSourceSink(const CAudioPlayer *ap) {
    672 
    673     const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource;
    674     const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink;
    675     const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
    676     const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
    677     AndroidObjectType type = INVALID_TYPE;
    678 
    679     //--------------------------------------
    680     // Sink / source matching check:
    681     // the following source / sink combinations are supported
    682     //     SL_DATALOCATOR_BUFFERQUEUE                / SL_DATALOCATOR_OUTPUTMIX
    683     //     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE   / SL_DATALOCATOR_OUTPUTMIX
    684     //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_OUTPUTMIX
    685     //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_OUTPUTMIX
    686     //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_OUTPUTMIX
    687     //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_BUFFERQUEUE
    688     //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_BUFFERQUEUE
    689     //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_BUFFERQUEUE
    690     //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
    691     //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
    692     switch (sinkLocatorType) {
    693 
    694     case SL_DATALOCATOR_OUTPUTMIX: {
    695         switch (sourceLocatorType) {
    696 
    697         //   Buffer Queue to AudioTrack
    698         case SL_DATALOCATOR_BUFFERQUEUE:
    699         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    700             type = AUDIOPLAYER_FROM_PCM_BUFFERQUEUE;
    701             break;
    702 
    703         //   URI or FD to MediaPlayer
    704         case SL_DATALOCATOR_URI:
    705         case SL_DATALOCATOR_ANDROIDFD:
    706             type = AUDIOPLAYER_FROM_URIFD;
    707             break;
    708 
    709         //   Android BufferQueue to MediaPlayer (shared memory streaming)
    710         case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    711             type = AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE;
    712             break;
    713 
    714         default:
    715             SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
    716                     (unsigned)sourceLocatorType);
    717             break;
    718         }
    719         }
    720         break;
    721 
    722     case SL_DATALOCATOR_BUFFERQUEUE:
    723     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    724         switch (sourceLocatorType) {
    725 
    726         //   URI or FD decoded to PCM in a buffer queue
    727         case SL_DATALOCATOR_URI:
    728         case SL_DATALOCATOR_ANDROIDFD:
    729             type = AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE;
    730             break;
    731 
    732         //   AAC ADTS Android buffer queue decoded to PCM in a buffer queue
    733         case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    734             type = AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE;
    735             break;
    736 
    737         default:
    738             SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
    739                     (unsigned)sourceLocatorType);
    740             break;
    741         }
    742         break;
    743 
    744     default:
    745         SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
    746         break;
    747     }
    748 
    749     return type;
    750 }
    751 
    752 
    753 //-----------------------------------------------------------------------------
    754 /*
    755  * Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
    756  * from a URI or FD, for prepare, prefetch, and play events
    757  */
    758 static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
    759 
    760     // FIXME see similar code and comment in player_handleMediaPlayerEventNotifications
    761 
    762     if (NULL == user) {
    763         return;
    764     }
    765 
    766     CAudioPlayer *ap = (CAudioPlayer *)user;
    767     if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
    768         // it is not safe to enter the callback (the track is about to go away)
    769         return;
    770     }
    771     union {
    772         char c[sizeof(int)];
    773         int i;
    774     } u;
    775     u.i = event;
    776     SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
    777             "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
    778     switch (event) {
    779 
    780     case android::GenericPlayer::kEventPrepared: {
    781         SL_LOGV("Received GenericPlayer::kEventPrepared for CAudioPlayer %p", ap);
    782 
    783         // assume no callback
    784         slPrefetchCallback callback = NULL;
    785         void* callbackPContext;
    786         SLuint32 events;
    787 
    788         object_lock_exclusive(&ap->mObject);
    789 
    790         // mark object as prepared; same state is used for successful or unsuccessful prepare
    791         assert(ap->mAndroidObjState == ANDROID_PREPARING);
    792         ap->mAndroidObjState = ANDROID_READY;
    793 
    794         if (PLAYER_SUCCESS == data1) {
    795             // Most of successful prepare completion for ap->mAPlayer
    796             // is handled by GenericPlayer and its subclasses.
    797         } else {
    798             // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
    799             //  indicate a prefetch error, so we signal it by sending simultaneously two events:
    800             //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
    801             //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
    802             SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
    803             if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
    804                 ap->mPrefetchStatus.mLevel = 0;
    805                 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
    806                 if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
    807                         (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
    808                     callback = ap->mPrefetchStatus.mCallback;
    809                     callbackPContext = ap->mPrefetchStatus.mContext;
    810                     events = SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE;
    811                 }
    812             }
    813         }
    814 
    815         object_unlock_exclusive(&ap->mObject);
    816 
    817         // callback with no lock held
    818         if (NULL != callback) {
    819             (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, events);
    820         }
    821 
    822     }
    823     break;
    824 
    825     case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
    826         if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
    827             break;
    828         }
    829         slPrefetchCallback callback = NULL;
    830         void* callbackPContext = NULL;
    831 
    832         // SLPrefetchStatusItf callback or no callback?
    833         interface_lock_exclusive(&ap->mPrefetchStatus);
    834         if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
    835             callback = ap->mPrefetchStatus.mCallback;
    836             callbackPContext = ap->mPrefetchStatus.mContext;
    837         }
    838         ap->mPrefetchStatus.mLevel = (SLpermille)data1;
    839         interface_unlock_exclusive(&ap->mPrefetchStatus);
    840 
    841         // callback with no lock held
    842         if (NULL != callback) {
    843             (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
    844                     SL_PREFETCHEVENT_FILLLEVELCHANGE);
    845         }
    846     }
    847     break;
    848 
    849     case android::GenericPlayer::kEventPrefetchStatusChange: {
    850         if (!IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
    851             break;
    852         }
    853         slPrefetchCallback callback = NULL;
    854         void* callbackPContext = NULL;
    855 
    856         // SLPrefetchStatusItf callback or no callback?
    857         object_lock_exclusive(&ap->mObject);
    858         if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
    859             callback = ap->mPrefetchStatus.mCallback;
    860             callbackPContext = ap->mPrefetchStatus.mContext;
    861         }
    862         if (data1 >= android::kStatusIntermediate) {
    863             ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
    864         } else if (data1 < android::kStatusIntermediate) {
    865             ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
    866         }
    867         object_unlock_exclusive(&ap->mObject);
    868 
    869         // callback with no lock held
    870         if (NULL != callback) {
    871             (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
    872         }
    873         }
    874         break;
    875 
    876     case android::GenericPlayer::kEventEndOfStream: {
    877         audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
    878         if ((ap->mTrackPlayer->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
    879             ap->mTrackPlayer->mAudioTrack->stop();
    880         }
    881         ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STOPPED);
    882         }
    883         break;
    884 
    885     case android::GenericPlayer::kEventChannelCount: {
    886         object_lock_exclusive(&ap->mObject);
    887         if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
    888             ap->mNumChannels = data1;
    889             android_audioPlayer_volumeUpdate(ap);
    890         }
    891         object_unlock_exclusive(&ap->mObject);
    892         }
    893         break;
    894 
    895     case android::GenericPlayer::kEventPlay: {
    896         slPlayCallback callback = NULL;
    897         void* callbackPContext = NULL;
    898 
    899         interface_lock_shared(&ap->mPlay);
    900         callback = ap->mPlay.mCallback;
    901         callbackPContext = ap->mPlay.mContext;
    902         interface_unlock_shared(&ap->mPlay);
    903 
    904         if (NULL != callback) {
    905             SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
    906 #ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
    907             // synchronous callback requires a synchronous GetPosition implementation
    908             (*callback)(&ap->mPlay.mItf, callbackPContext, event);
    909 #else
    910             // asynchronous callback works with any GetPosition implementation
    911             SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
    912                     callbackPContext, event);
    913             if (SL_RESULT_SUCCESS != result) {
    914                 ALOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
    915                         &ap->mPlay.mItf, callbackPContext, event);
    916             }
    917 #endif
    918         }
    919         }
    920         break;
    921 
    922       case android::GenericPlayer::kEventErrorAfterPrepare: {
    923         SL_LOGV("kEventErrorAfterPrepare");
    924 
    925         // assume no callback
    926         slPrefetchCallback callback = NULL;
    927         void* callbackPContext = NULL;
    928 
    929         object_lock_exclusive(&ap->mObject);
    930         if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
    931             ap->mPrefetchStatus.mLevel = 0;
    932             ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
    933             if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
    934                     (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
    935                 callback = ap->mPrefetchStatus.mCallback;
    936                 callbackPContext = ap->mPrefetchStatus.mContext;
    937             }
    938         }
    939         object_unlock_exclusive(&ap->mObject);
    940 
    941         // FIXME there's interesting information in data1, but no API to convey it to client
    942         SL_LOGE("Error after prepare: %d", data1);
    943 
    944         // callback with no lock held
    945         if (NULL != callback) {
    946             (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
    947                     SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
    948         }
    949 
    950       }
    951       break;
    952 
    953     case android::GenericPlayer::kEventHasVideoSize:
    954         //SL_LOGW("Unexpected kEventHasVideoSize");
    955         break;
    956 
    957     default:
    958         break;
    959     }
    960 
    961     ap->mCallbackProtector->exitCb();
    962 }
    963 
    964 // From EffectDownmix.h
    965 static
    966 const uint32_t kSides = AUDIO_CHANNEL_OUT_SIDE_LEFT | AUDIO_CHANNEL_OUT_SIDE_RIGHT;
    967 static
    968 const uint32_t kBacks = AUDIO_CHANNEL_OUT_BACK_LEFT | AUDIO_CHANNEL_OUT_BACK_RIGHT;
    969 static
    970 const uint32_t kUnsupported =
    971         AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER | AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
    972         AUDIO_CHANNEL_OUT_TOP_CENTER |
    973         AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT |
    974         AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER |
    975         AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT |
    976         AUDIO_CHANNEL_OUT_TOP_BACK_LEFT |
    977         AUDIO_CHANNEL_OUT_TOP_BACK_CENTER |
    978         AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT;
    979 
    980 static
    981 SLresult android_audioPlayer_validateChannelMask(uint32_t mask, uint32_t numChans) {
    982     // Check that the number of channels falls within bounds.
    983     if (numChans == 0 || numChans > FCC_8) {
    984         SL_LOGE("Number of channels %u must be between one and %u inclusive", numChans, FCC_8);
    985         return SL_RESULT_CONTENT_UNSUPPORTED;
    986     }
    987     // Are there the right number of channels in the mask?
    988     if (sles_channel_count_from_mask(mask) != numChans) {
    989         SL_LOGE("Channel mask %#x does not match channel count %u", mask, numChans);
    990         return SL_RESULT_CONTENT_UNSUPPORTED;
    991     }
    992 
    993     audio_channel_representation_t representation =
    994             sles_to_audio_channel_mask_representation(mask);
    995 
    996     if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
    997         return SL_RESULT_SUCCESS;
    998     }
    999 
   1000     // If audio is positional we need to run a set of checks to make sure
   1001     // the positions can be handled by our HDMI-compliant downmixer. Compare with
   1002     // android.media.AudioTrack.isMultichannelConfigSupported
   1003     // and Downmix_foldGeneric (in libeffects).
   1004     if (representation == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
   1005         // check against unsupported channels
   1006         if (mask & kUnsupported) {
   1007             SL_LOGE("Mask %#x is invalid: Unsupported channels (top or front left/right of center)",
   1008                     mask);
   1009             return SL_RESULT_CONTENT_UNSUPPORTED;
   1010         }
   1011         // verify that mask has FL/FR if more than one channel specified
   1012         if (numChans > 1 && (mask & AUDIO_CHANNEL_OUT_STEREO) != AUDIO_CHANNEL_OUT_STEREO) {
   1013             SL_LOGE("Mask %#x is invalid: Front channels must be present", mask);
   1014             return SL_RESULT_CONTENT_UNSUPPORTED;
   1015         }
   1016         // verify that SIDE is used as a pair (ok if not using SIDE at all)
   1017         if ((mask & kSides) != 0 && (mask & kSides) != kSides) {
   1018                 SL_LOGE("Mask %#x is invalid: Side channels must be used as a pair", mask);
   1019                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1020         }
   1021         // verify that BACK is used as a pair (ok if not using BACK at all)
   1022         if ((mask & kBacks) != 0 && (mask & kBacks) != kBacks) {
   1023             SL_LOGE("Mask %#x is invalid: Back channels must be used as a pair", mask);
   1024             return SL_RESULT_CONTENT_UNSUPPORTED;
   1025         }
   1026         return SL_RESULT_SUCCESS;
   1027     }
   1028 
   1029     SL_LOGE("Unrecognized channel mask representation %#x", representation);
   1030     return SL_RESULT_CONTENT_UNSUPPORTED;
   1031 }
   1032 
   1033 //-----------------------------------------------------------------------------
   1034 SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
   1035 {
   1036     // verify that the locator types for the source / sink combination is supported
   1037     pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
   1038     if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
   1039         return SL_RESULT_PARAMETER_INVALID;
   1040     }
   1041 
   1042     const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
   1043     const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
   1044 
   1045     // format check:
   1046     const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
   1047     const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
   1048     const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
   1049 
   1050     const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
   1051 
   1052     switch (sourceLocatorType) {
   1053     //------------------
   1054     //   Buffer Queues
   1055     case SL_DATALOCATOR_BUFFERQUEUE:
   1056     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
   1057         {
   1058         // Buffer format
   1059         switch (sourceFormatType) {
   1060         //     currently only PCM buffer queues are supported,
   1061         case SL_ANDROID_DATAFORMAT_PCM_EX: {
   1062             const SLAndroidDataFormat_PCM_EX *df_pcm =
   1063                     (const SLAndroidDataFormat_PCM_EX *) pAudioSrc->pFormat;
   1064             // checkDataFormat() already checked representation
   1065             df_representation = &df_pcm->representation;
   1066             } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
   1067         case SL_DATAFORMAT_PCM: {
   1068             // checkDataFormat() already did generic checks, now do the Android-specific checks
   1069             const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSrc->pFormat;
   1070             SLresult result = android_audioPlayer_validateChannelMask(df_pcm->channelMask,
   1071                                                                       df_pcm->numChannels);
   1072             if (result != SL_RESULT_SUCCESS) {
   1073                 SL_LOGE("Cannot create audio player: unsupported PCM data source with %u channels",
   1074                         (unsigned) df_pcm->numChannels);
   1075                 return result;
   1076             }
   1077 
   1078             // checkDataFormat() already checked sample rate
   1079 
   1080             // checkDataFormat() already checked bits per sample, container size, and representation
   1081 
   1082             // FIXME confirm the following
   1083             // df_pcm->channelMask: the earlier platform-independent check and the
   1084             //     upcoming check by sles_to_android_channelMaskOut are sufficient
   1085 
   1086             if (df_pcm->endianness != pAudioPlayer->mObject.mEngine->mEngine.mNativeEndianness) {
   1087                 SL_LOGE("Cannot create audio player: unsupported byte order %u",
   1088                         df_pcm->endianness);
   1089                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1090             }
   1091 
   1092             // we don't support container size != sample depth
   1093             if (df_pcm->containerSize != df_pcm->bitsPerSample) {
   1094                 SL_LOGE("Cannot create audio player: unsupported container size %u bits for "
   1095                         "sample depth %u bits",
   1096                         df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample);
   1097                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1098             }
   1099 
   1100             } //case SL_DATAFORMAT_PCM
   1101             break;
   1102         case SL_DATAFORMAT_MIME:
   1103         case XA_DATAFORMAT_RAWIMAGE:
   1104             SL_LOGE("Cannot create audio player with buffer queue data source "
   1105                 "without SL_DATAFORMAT_PCM format");
   1106             return SL_RESULT_CONTENT_UNSUPPORTED;
   1107         default:
   1108             // invalid data format is detected earlier
   1109             assert(false);
   1110             return SL_RESULT_INTERNAL_ERROR;
   1111         } // switch (sourceFormatType)
   1112         } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
   1113         break;
   1114     //------------------
   1115     //   URI
   1116     case SL_DATALOCATOR_URI:
   1117         {
   1118         SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
   1119         if (NULL == dl_uri->URI) {
   1120             return SL_RESULT_PARAMETER_INVALID;
   1121         }
   1122         // URI format
   1123         switch (sourceFormatType) {
   1124         case SL_DATAFORMAT_MIME:
   1125             break;
   1126         default:
   1127             SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
   1128                 "SL_DATAFORMAT_MIME format");
   1129             return SL_RESULT_CONTENT_UNSUPPORTED;
   1130         } // switch (sourceFormatType)
   1131         // decoding format check
   1132         if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
   1133                 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
   1134             return SL_RESULT_CONTENT_UNSUPPORTED;
   1135         }
   1136         } // case SL_DATALOCATOR_URI
   1137         break;
   1138     //------------------
   1139     //   File Descriptor
   1140     case SL_DATALOCATOR_ANDROIDFD:
   1141         {
   1142         // fd is already non null
   1143         switch (sourceFormatType) {
   1144         case SL_DATAFORMAT_MIME:
   1145             break;
   1146         default:
   1147             SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
   1148                 "without SL_DATAFORMAT_MIME format");
   1149             return SL_RESULT_CONTENT_UNSUPPORTED;
   1150         } // switch (sourceFormatType)
   1151         if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
   1152                 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
   1153             return SL_RESULT_CONTENT_UNSUPPORTED;
   1154         }
   1155         } // case SL_DATALOCATOR_ANDROIDFD
   1156         break;
   1157     //------------------
   1158     //   Stream
   1159     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
   1160     {
   1161         switch (sourceFormatType) {
   1162         case SL_DATAFORMAT_MIME:
   1163         {
   1164             SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
   1165             if (NULL == df_mime) {
   1166                 SL_LOGE("MIME type null invalid");
   1167                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1168             }
   1169             SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
   1170             switch (df_mime->containerType) {
   1171             case SL_CONTAINERTYPE_MPEG_TS:
   1172                 if (strcasecmp((char*)df_mime->mimeType, (const char *)XA_ANDROID_MIME_MP2TS)) {
   1173                     SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
   1174                             (char*)df_mime->mimeType, XA_ANDROID_MIME_MP2TS);
   1175                     return SL_RESULT_CONTENT_UNSUPPORTED;
   1176                 }
   1177                 if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) {
   1178                     SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_MPEG_TS");
   1179                     return SL_RESULT_PARAMETER_INVALID;
   1180                 }
   1181                 break;
   1182             case SL_CONTAINERTYPE_RAW:
   1183             case SL_CONTAINERTYPE_AAC:
   1184                 if (strcasecmp((char*)df_mime->mimeType, (const char *)SL_ANDROID_MIME_AACADTS) &&
   1185                         strcasecmp((char*)df_mime->mimeType,
   1186                                 ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
   1187                     SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
   1188                             (char*)df_mime->mimeType, df_mime->containerType,
   1189                             SL_ANDROID_MIME_AACADTS);
   1190                     return SL_RESULT_CONTENT_UNSUPPORTED;
   1191                 }
   1192                 if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE) {
   1193                     SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_AAC");
   1194                     return SL_RESULT_PARAMETER_INVALID;
   1195                 }
   1196                 break;
   1197             default:
   1198                 SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
   1199                                         "that is not fed MPEG-2 TS data or AAC ADTS data");
   1200                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1201             }
   1202         }
   1203         break;
   1204         default:
   1205             SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
   1206                     "without SL_DATAFORMAT_MIME format");
   1207             return SL_RESULT_CONTENT_UNSUPPORTED;
   1208         }
   1209     }
   1210     break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
   1211     //------------------
   1212     //   Address
   1213     case SL_DATALOCATOR_ADDRESS:
   1214     case SL_DATALOCATOR_IODEVICE:
   1215     case SL_DATALOCATOR_OUTPUTMIX:
   1216     case XA_DATALOCATOR_NATIVEDISPLAY:
   1217     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
   1218         SL_LOGE("Cannot create audio player with data locator type 0x%x",
   1219                 (unsigned) sourceLocatorType);
   1220         return SL_RESULT_CONTENT_UNSUPPORTED;
   1221     default:
   1222         SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
   1223                 (unsigned) sourceLocatorType);
   1224         return SL_RESULT_PARAMETER_INVALID;
   1225     }// switch (locatorType)
   1226 
   1227     return SL_RESULT_SUCCESS;
   1228 }
   1229 
   1230 
   1231 //-----------------------------------------------------------------------------
   1232 // Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
   1233 // from a buffer queue. This will not be called once the AudioTrack has been destroyed.
   1234 static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
   1235     CAudioPlayer *ap = (CAudioPlayer *)user;
   1236 
   1237     if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
   1238         // it is not safe to enter the callback (the track is about to go away)
   1239         return;
   1240     }
   1241 
   1242     void * callbackPContext = NULL;
   1243     switch (event) {
   1244 
   1245     case android::AudioTrack::EVENT_MORE_DATA: {
   1246         //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
   1247         slPrefetchCallback prefetchCallback = NULL;
   1248         void *prefetchContext = NULL;
   1249         SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
   1250         android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
   1251 
   1252         // retrieve data from the buffer queue
   1253         interface_lock_exclusive(&ap->mBufferQueue);
   1254 
   1255         if (ap->mBufferQueue.mCallbackPending) {
   1256             // call callback with lock not held
   1257             slBufferQueueCallback callback = ap->mBufferQueue.mCallback;
   1258             if (NULL != callback) {
   1259                 callbackPContext = ap->mBufferQueue.mContext;
   1260                 interface_unlock_exclusive(&ap->mBufferQueue);
   1261                 (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
   1262                 interface_lock_exclusive(&ap->mBufferQueue);
   1263                 ap->mBufferQueue.mCallbackPending = false;
   1264             }
   1265         }
   1266 
   1267         if (ap->mBufferQueue.mState.count != 0) {
   1268             //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
   1269             assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
   1270 
   1271             BufferHeader *oldFront = ap->mBufferQueue.mFront;
   1272             BufferHeader *newFront = &oldFront[1];
   1273 
   1274             size_t availSource = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
   1275             size_t availSink = pBuff->size;
   1276             size_t bytesToCopy = availSource < availSink ? availSource : availSink;
   1277             void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
   1278             memcpy(pBuff->raw, pSrc, bytesToCopy);
   1279 
   1280             if (bytesToCopy < availSource) {
   1281                 ap->mBufferQueue.mSizeConsumed += bytesToCopy;
   1282                 // pBuff->size is already equal to bytesToCopy in this case
   1283             } else {
   1284                 // consumed an entire buffer, dequeue
   1285                 pBuff->size = bytesToCopy;
   1286                 ap->mBufferQueue.mSizeConsumed = 0;
   1287                 if (newFront ==
   1288                         &ap->mBufferQueue.mArray
   1289                             [ap->mBufferQueue.mNumBuffers + 1])
   1290                 {
   1291                     newFront = ap->mBufferQueue.mArray;
   1292                 }
   1293                 ap->mBufferQueue.mFront = newFront;
   1294 
   1295                 ap->mBufferQueue.mState.count--;
   1296                 ap->mBufferQueue.mState.playIndex++;
   1297                 ap->mBufferQueue.mCallbackPending = true;
   1298             }
   1299         } else { // empty queue
   1300             // signal no data available
   1301             pBuff->size = 0;
   1302 
   1303             // signal we're at the end of the content, but don't pause (see note in function)
   1304             audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
   1305 
   1306             // signal underflow to prefetch status itf
   1307             if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
   1308                 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
   1309                 ap->mPrefetchStatus.mLevel = 0;
   1310                 // callback or no callback?
   1311                 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
   1312                         (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
   1313                 if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
   1314                     prefetchCallback = ap->mPrefetchStatus.mCallback;
   1315                     prefetchContext  = ap->mPrefetchStatus.mContext;
   1316                 }
   1317             }
   1318 
   1319             // stop the track so it restarts playing faster when new data is enqueued
   1320             ap->mTrackPlayer->stop();
   1321         }
   1322         interface_unlock_exclusive(&ap->mBufferQueue);
   1323 
   1324         // notify client
   1325         if (NULL != prefetchCallback) {
   1326             assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
   1327             // spec requires separate callbacks for each event
   1328             if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
   1329                 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
   1330                         SL_PREFETCHEVENT_STATUSCHANGE);
   1331             }
   1332             if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
   1333                 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
   1334                         SL_PREFETCHEVENT_FILLLEVELCHANGE);
   1335             }
   1336         }
   1337     }
   1338     break;
   1339 
   1340     case android::AudioTrack::EVENT_MARKER:
   1341         //SL_LOGI("received event EVENT_MARKER from AudioTrack");
   1342         audioTrack_handleMarker_lockPlay(ap);
   1343         break;
   1344 
   1345     case android::AudioTrack::EVENT_NEW_POS:
   1346         //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
   1347         audioTrack_handleNewPos_lockPlay(ap);
   1348         break;
   1349 
   1350     case android::AudioTrack::EVENT_UNDERRUN:
   1351         //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
   1352         audioTrack_handleUnderrun_lockPlay(ap);
   1353         break;
   1354 
   1355     case android::AudioTrack::EVENT_NEW_IAUDIOTRACK:
   1356         // ignore for now
   1357         break;
   1358 
   1359     case android::AudioTrack::EVENT_BUFFER_END:
   1360     case android::AudioTrack::EVENT_LOOP_END:
   1361     case android::AudioTrack::EVENT_STREAM_END:
   1362         // These are unexpected so fall through
   1363     default:
   1364         // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
   1365         SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
   1366                 (CAudioPlayer *)user);
   1367         break;
   1368     }
   1369 
   1370     ap->mCallbackProtector->exitCb();
   1371 }
   1372 
   1373 
   1374 //-----------------------------------------------------------------------------
   1375 void android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
   1376 
   1377     // pAudioPlayer->mAndroidObjType has been set in android_audioPlayer_checkSourceSink()
   1378     // and if it was == INVALID_TYPE, then IEngine_CreateAudioPlayer would never call us
   1379     assert(INVALID_TYPE != pAudioPlayer->mAndroidObjType);
   1380 
   1381     // These initializations are in the same order as the field declarations in classes.h
   1382 
   1383     // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
   1384     // mAndroidObjType: see above comment
   1385     pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
   1386     pAudioPlayer->mSessionId = (audio_session_t) android::AudioSystem::newAudioUniqueId(
   1387             AUDIO_UNIQUE_ID_USE_SESSION);
   1388     pAudioPlayer->mPIId = PLAYER_PIID_INVALID;
   1389 
   1390     // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
   1391     // android::AudioSystem::acquireAudioSessionId(pAudioPlayer->mSessionId);
   1392 
   1393     pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
   1394     pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
   1395 
   1396     // mAudioTrack lifecycle is handled through mTrackPlayer
   1397     pAudioPlayer->mTrackPlayer = new android::TrackPlayerBase();
   1398     assert(pAudioPlayer->mTrackPlayer != 0);
   1399     pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
   1400     // mAPLayer
   1401     // mAuxEffect
   1402 
   1403     pAudioPlayer->mAuxSendLevel = 0;
   1404     pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
   1405     pAudioPlayer->mDeferredStart = false;
   1406 
   1407     // This section re-initializes interface-specific fields that
   1408     // can be set or used regardless of whether the interface is
   1409     // exposed on the AudioPlayer or not
   1410 
   1411     switch (pAudioPlayer->mAndroidObjType) {
   1412     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   1413         pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
   1414         pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
   1415         break;
   1416     case AUDIOPLAYER_FROM_URIFD:
   1417         pAudioPlayer->mPlaybackRate.mMinRate = MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE;
   1418         pAudioPlayer->mPlaybackRate.mMaxRate = MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE;
   1419         break;
   1420     default:
   1421         // use the default range
   1422         break;
   1423     }
   1424 
   1425 }
   1426 
   1427 
   1428 //-----------------------------------------------------------------------------
   1429 SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
   1430         const void *pConfigValue, SLuint32 valueSize) {
   1431 
   1432     SLresult result;
   1433 
   1434     assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
   1435     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
   1436 
   1437         // stream type
   1438         if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
   1439             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1440             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1441         } else {
   1442             result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
   1443         }
   1444     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
   1445 
   1446         // performance mode
   1447         if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) {
   1448             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1449             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1450         } else {
   1451             result = audioPlayer_setPerformanceMode(ap, *(SLuint32*)pConfigValue);
   1452         }
   1453 
   1454     } else {
   1455         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
   1456         result = SL_RESULT_PARAMETER_INVALID;
   1457     }
   1458 
   1459     return result;
   1460 }
   1461 
   1462 
   1463 //-----------------------------------------------------------------------------
   1464 SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
   1465         SLuint32* pValueSize, void *pConfigValue) {
   1466 
   1467     SLresult result;
   1468 
   1469     assert(NULL != ap && NULL != configKey && NULL != pValueSize);
   1470     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
   1471 
   1472         // stream type
   1473         if (NULL == pConfigValue) {
   1474             result = SL_RESULT_SUCCESS;
   1475         } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
   1476             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1477             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1478         } else {
   1479             result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
   1480         }
   1481         *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
   1482 
   1483     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
   1484 
   1485         // performance mode
   1486         if (NULL == pConfigValue) {
   1487             result = SL_RESULT_SUCCESS;
   1488         } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) {
   1489             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1490             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1491         } else {
   1492             result = audioPlayer_getPerformanceMode(ap, (SLuint32*)pConfigValue);
   1493         }
   1494         *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE;
   1495 
   1496     } else {
   1497         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
   1498         result = SL_RESULT_PARAMETER_INVALID;
   1499     }
   1500 
   1501     return result;
   1502 }
   1503 
   1504 
   1505 // Called from android_audioPlayer_realize for a PCM buffer queue player before creating the
   1506 // AudioTrack to determine which performance modes are allowed based on effect interfaces present
   1507 static void checkAndSetPerformanceModePre(CAudioPlayer *pAudioPlayer)
   1508 {
   1509     SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL;
   1510     assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
   1511 
   1512     // no need to check the buffer queue size, application side
   1513     // double-buffering (and more) is not a requirement for using fast tracks
   1514 
   1515     // Check a blacklist of interfaces that are incompatible with fast tracks.
   1516     // The alternative, to check a whitelist of compatible interfaces, is
   1517     // more maintainable but is too slow.  As a compromise, in a debug build
   1518     // we use both methods and warn if they produce different results.
   1519     // In release builds, we only use the blacklist method.
   1520     // If a blacklisted interface is added after realization using
   1521     // DynamicInterfaceManagement::AddInterface,
   1522     // then this won't be detected but the interface will be ineffective.
   1523     static const unsigned blacklist[] = {
   1524         MPH_BASSBOOST,
   1525         MPH_EFFECTSEND,
   1526         MPH_ENVIRONMENTALREVERB,
   1527         MPH_EQUALIZER,
   1528         MPH_PLAYBACKRATE,
   1529         MPH_PRESETREVERB,
   1530         MPH_VIRTUALIZER,
   1531         MPH_ANDROIDEFFECT,
   1532         MPH_ANDROIDEFFECTSEND,
   1533         // FIXME The problem with a blacklist is remembering to add new interfaces here
   1534     };
   1535     for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
   1536         if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
   1537             //TODO: query effect for EFFECT_FLAG_HW_ACC_xx flag to refine mode
   1538             allowedModes &=
   1539                     ~(ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS);
   1540             break;
   1541         }
   1542     }
   1543 #if LOG_NDEBUG == 0
   1544     bool blacklistResult = (
   1545             (allowedModes &
   1546                 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
   1547     bool whitelistResult = true;
   1548     static const unsigned whitelist[] = {
   1549         MPH_BUFFERQUEUE,
   1550         MPH_DYNAMICINTERFACEMANAGEMENT,
   1551         MPH_METADATAEXTRACTION,
   1552         MPH_MUTESOLO,
   1553         MPH_OBJECT,
   1554         MPH_PLAY,
   1555         MPH_PREFETCHSTATUS,
   1556         MPH_VOLUME,
   1557         MPH_ANDROIDCONFIGURATION,
   1558         MPH_ANDROIDSIMPLEBUFFERQUEUE,
   1559         MPH_ANDROIDBUFFERQUEUESOURCE,
   1560     };
   1561     for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
   1562         for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
   1563             if (mph == whitelist[i]) {
   1564                 goto compatible;
   1565             }
   1566         }
   1567         if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
   1568             whitelistResult = false;
   1569             break;
   1570         }
   1571 compatible: ;
   1572     }
   1573     if (whitelistResult != blacklistResult) {
   1574         SL_LOGW("whitelistResult != blacklistResult");
   1575     }
   1576 #endif
   1577     if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) {
   1578         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) {
   1579             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
   1580         }
   1581     }
   1582     if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) {
   1583         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) {
   1584             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1585         }
   1586     }
   1587 }
   1588 
   1589 // Called from android_audioPlayer_realize for a PCM buffer queue player after creating the
   1590 // AudioTrack to adjust performance mode based on actual output flags
   1591 static void checkAndSetPerformanceModePost(CAudioPlayer *pAudioPlayer)
   1592 {
   1593     audio_output_flags_t flags = pAudioPlayer->mTrackPlayer->mAudioTrack->getFlags();
   1594     switch (pAudioPlayer->mPerformanceMode) {
   1595     case ANDROID_PERFORMANCE_MODE_LATENCY:
   1596         if ((flags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) ==
   1597                 (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) {
   1598             break;
   1599         }
   1600         pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
   1601         /* FALL THROUGH */
   1602     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
   1603         if ((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
   1604             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1605         }
   1606         break;
   1607     case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
   1608         if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) == 0) {
   1609             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1610         }
   1611         break;
   1612     case ANDROID_PERFORMANCE_MODE_NONE:
   1613     default:
   1614         break;
   1615     }
   1616 }
   1617 //-----------------------------------------------------------------------------
   1618 // FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
   1619 SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
   1620 
   1621     SLresult result = SL_RESULT_SUCCESS;
   1622     SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
   1623     AudioPlayback_Parameters app;
   1624     app.sessionId = pAudioPlayer->mSessionId;
   1625     app.streamType = pAudioPlayer->mStreamType;
   1626 
   1627     switch (pAudioPlayer->mAndroidObjType) {
   1628 
   1629     //-----------------------------------
   1630     // AudioTrack
   1631     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
   1632         // initialize platform-specific CAudioPlayer fields
   1633 
   1634         SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
   1635                 pAudioPlayer->mDynamicSource.mDataSource->pFormat;
   1636 
   1637         uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
   1638 
   1639         audio_channel_mask_t channelMask;
   1640         channelMask = sles_to_audio_output_channel_mask(df_pcm->channelMask);
   1641 
   1642         // To maintain backward compatibility with previous releases, ignore
   1643         // channel masks that are not indexed.
   1644         if (channelMask == AUDIO_CHANNEL_INVALID
   1645                 || audio_channel_mask_get_representation(channelMask)
   1646                         == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
   1647             channelMask = audio_channel_out_mask_from_count(df_pcm->numChannels);
   1648             SL_LOGI("Emulating old channel mask behavior "
   1649                     "(ignoring positional mask %#x, using default mask %#x based on "
   1650                     "channel count of %d)", df_pcm->channelMask, channelMask,
   1651                     df_pcm->numChannels);
   1652         }
   1653         SL_LOGV("AudioPlayer: mapped SLES channel mask %#x to android channel mask %#x",
   1654             df_pcm->channelMask,
   1655             channelMask);
   1656 
   1657         checkAndSetPerformanceModePre(pAudioPlayer);
   1658 
   1659         audio_output_flags_t policy;
   1660         switch (pAudioPlayer->mPerformanceMode) {
   1661         case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
   1662             policy = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
   1663             break;
   1664         case ANDROID_PERFORMANCE_MODE_NONE:
   1665             policy = AUDIO_OUTPUT_FLAG_NONE;
   1666             break;
   1667         case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
   1668             policy = AUDIO_OUTPUT_FLAG_FAST;
   1669             break;
   1670         case ANDROID_PERFORMANCE_MODE_LATENCY:
   1671         default:
   1672             policy = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
   1673             break;
   1674         }
   1675 
   1676         int32_t notificationFrames;
   1677         if ((policy & AUDIO_OUTPUT_FLAG_FAST) != 0) {
   1678             // negative notificationFrames is the number of notifications (sub-buffers) per track
   1679             // buffer for details see the explanation at frameworks/av/include/media/AudioTrack.h
   1680             notificationFrames = -pAudioPlayer->mBufferQueue.mNumBuffers;
   1681         } else {
   1682             notificationFrames = 0;
   1683         }
   1684 
   1685         android::AudioTrack* pat = new android::AudioTrack(
   1686                 pAudioPlayer->mStreamType,                           // streamType
   1687                 sampleRate,                                          // sampleRate
   1688                 sles_to_android_sampleFormat(df_pcm),                // format
   1689                 channelMask,                                         // channel mask
   1690                 0,                                                   // frameCount
   1691                 policy,                                              // flags
   1692                 audioTrack_callBack_pullFromBuffQueue,               // callback
   1693                 (void *) pAudioPlayer,                               // user
   1694                 notificationFrames,                                  // see comment above
   1695                 pAudioPlayer->mSessionId);
   1696         android::status_t status = pat->initCheck();
   1697         if (status != android::NO_ERROR) {
   1698             SL_LOGE("AudioTrack::initCheck status %u", status);
   1699             // FIXME should return a more specific result depending on status
   1700             result = SL_RESULT_CONTENT_UNSUPPORTED;
   1701             return result;
   1702         }
   1703 
   1704         pAudioPlayer->mTrackPlayer->init(pat, android::PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE,
   1705                 usageForStreamType(pAudioPlayer->mStreamType));
   1706 
   1707         // update performance mode according to actual flags granted to AudioTrack
   1708         checkAndSetPerformanceModePost(pAudioPlayer);
   1709 
   1710         // initialize platform-independent CAudioPlayer fields
   1711 
   1712         pAudioPlayer->mNumChannels = df_pcm->numChannels;
   1713         pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
   1714 
   1715         // This use case does not have a separate "prepare" step
   1716         pAudioPlayer->mAndroidObjState = ANDROID_READY;
   1717 
   1718         // If there is a JavaAudioRoutingProxy associated with this player, hook it up...
   1719         JNIEnv* j_env = NULL;
   1720         jclass clsAudioTrack = NULL;
   1721         jmethodID midRoutingProxy_connect = NULL;
   1722         if (pAudioPlayer->mAndroidConfiguration.mRoutingProxy != NULL &&
   1723                 (j_env = android::AndroidRuntime::getJNIEnv()) != NULL &&
   1724                 (clsAudioTrack = j_env->FindClass("android/media/AudioTrack")) != NULL &&
   1725                 (midRoutingProxy_connect =
   1726                     j_env->GetMethodID(clsAudioTrack, "deferred_connect", "(J)V")) != NULL) {
   1727             j_env->ExceptionClear();
   1728             j_env->CallVoidMethod(pAudioPlayer->mAndroidConfiguration.mRoutingProxy,
   1729                                   midRoutingProxy_connect,
   1730                                   (jlong)pAudioPlayer->mTrackPlayer->mAudioTrack.get());
   1731             if (j_env->ExceptionCheck()) {
   1732                 SL_LOGE("Java exception releasing player routing object.");
   1733                 result = SL_RESULT_INTERNAL_ERROR;
   1734                 pAudioPlayer->mTrackPlayer->mAudioTrack.clear();
   1735                 return result;
   1736             }
   1737         }
   1738     }
   1739         break;
   1740 
   1741     //-----------------------------------
   1742     // MediaPlayer
   1743     case AUDIOPLAYER_FROM_URIFD: {
   1744         pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
   1745         pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
   1746                         (void*)pAudioPlayer /*notifUSer*/);
   1747 
   1748         switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
   1749             case SL_DATALOCATOR_URI: {
   1750                 // The legacy implementation ran Stagefright within the application process, and
   1751                 // so allowed local pathnames specified by URI that were openable by
   1752                 // the application but were not openable by mediaserver.
   1753                 // The current implementation runs Stagefright (mostly) within mediaserver,
   1754                 // which runs as a different UID and likely a different current working directory.
   1755                 // For backwards compatibility with any applications which may have relied on the
   1756                 // previous behavior, we convert an openable file URI into an FD.
   1757                 // Note that unlike SL_DATALOCATOR_ANDROIDFD, this FD is owned by us
   1758                 // and so we close it as soon as we've passed it (via Binder dup) to mediaserver.
   1759                 const char *uri = (const char *)pAudioPlayer->mDataSource.mLocator.mURI.URI;
   1760                 if (!isDistantProtocol(uri)) {
   1761                     // don't touch the original uri, we may need it later
   1762                     const char *pathname = uri;
   1763                     // skip over an optional leading file:// prefix
   1764                     if (!strncasecmp(pathname, "file://", 7)) {
   1765                         pathname += 7;
   1766                     }
   1767                     // attempt to open it as a file using the application's credentials
   1768                     int fd = ::open(pathname, O_RDONLY);
   1769                     if (fd >= 0) {
   1770                         // if open is successful, then check to see if it's a regular file
   1771                         struct stat statbuf;
   1772                         if (!::fstat(fd, &statbuf) && S_ISREG(statbuf.st_mode)) {
   1773                             // treat similarly to an FD data locator, but
   1774                             // let setDataSource take responsibility for closing fd
   1775                             pAudioPlayer->mAPlayer->setDataSource(fd, 0, statbuf.st_size, true);
   1776                             break;
   1777                         }
   1778                         // we were able to open it, but it's not a file, so let mediaserver try
   1779                         (void) ::close(fd);
   1780                     }
   1781                 }
   1782                 // if either the URI didn't look like a file, or open failed, or not a file
   1783                 pAudioPlayer->mAPlayer->setDataSource(uri);
   1784                 } break;
   1785             case SL_DATALOCATOR_ANDROIDFD: {
   1786                 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
   1787                 pAudioPlayer->mAPlayer->setDataSource(
   1788                         (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
   1789                         offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
   1790                                 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
   1791                         (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
   1792                 }
   1793                 break;
   1794             default:
   1795                 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
   1796                 break;
   1797         }
   1798 
   1799         if (pAudioPlayer->mObject.mEngine->mAudioManager == 0) {
   1800             SL_LOGE("AudioPlayer realize: no audio service, player will not be registered");
   1801             pAudioPlayer->mPIId = 0;
   1802         } else {
   1803             pAudioPlayer->mPIId = pAudioPlayer->mObject.mEngine->mAudioManager->trackPlayer(
   1804                     android::PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD,
   1805                     usageForStreamType(pAudioPlayer->mStreamType), AUDIO_CONTENT_TYPE_UNKNOWN,
   1806                     pAudioPlayer->mTrackPlayer);
   1807         }
   1808         }
   1809         break;
   1810 
   1811     //-----------------------------------
   1812     // StreamPlayer
   1813     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
   1814         android::StreamPlayer* splr = new android::StreamPlayer(&app, false /*hasVideo*/,
   1815                 &pAudioPlayer->mAndroidBufferQueue, pAudioPlayer->mCallbackProtector);
   1816         pAudioPlayer->mAPlayer = splr;
   1817         splr->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1818         }
   1819         break;
   1820 
   1821     //-----------------------------------
   1822     // AudioToCbRenderer
   1823     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
   1824         android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
   1825         pAudioPlayer->mAPlayer = decoder;
   1826         // configures the callback for the sink buffer queue
   1827         decoder->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
   1828         // configures the callback for the notifications coming from the SF code
   1829         decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1830 
   1831         switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
   1832         case SL_DATALOCATOR_URI:
   1833             decoder->setDataSource(
   1834                     (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
   1835             break;
   1836         case SL_DATALOCATOR_ANDROIDFD: {
   1837             int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
   1838             decoder->setDataSource(
   1839                     (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
   1840                     offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
   1841                             (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
   1842                             (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
   1843             }
   1844             break;
   1845         default:
   1846             SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
   1847             break;
   1848         }
   1849 
   1850         }
   1851         break;
   1852 
   1853     //-----------------------------------
   1854     // AacBqToPcmCbRenderer
   1855     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
   1856         android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app,
   1857                 &pAudioPlayer->mAndroidBufferQueue);
   1858         // configures the callback for the sink buffer queue
   1859         bqtobq->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
   1860         pAudioPlayer->mAPlayer = bqtobq;
   1861         // configures the callback for the notifications coming from the SF code,
   1862         // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
   1863         pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1864         }
   1865         break;
   1866 
   1867     //-----------------------------------
   1868     default:
   1869         SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
   1870         result = SL_RESULT_INTERNAL_ERROR;
   1871         break;
   1872     }
   1873 
   1874     if (result == SL_RESULT_SUCCESS) {
   1875         // proceed with effect initialization
   1876         // initialize EQ
   1877         // FIXME use a table of effect descriptors when adding support for more effects
   1878 
   1879         // No session effects allowed even in latency with effects performance mode because HW
   1880         // accelerated effects are only tolerated as post processing in this mode
   1881         if ((pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_PCM_BUFFERQUEUE) ||
   1882                 ((pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) &&
   1883                  (pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS))) {
   1884             if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
   1885                     sizeof(effect_uuid_t)) == 0) {
   1886                 SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
   1887                 android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
   1888             }
   1889             // initialize BassBoost
   1890             if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
   1891                     sizeof(effect_uuid_t)) == 0) {
   1892                 SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
   1893                 android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
   1894             }
   1895             // initialize Virtualizer
   1896             if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
   1897                        sizeof(effect_uuid_t)) == 0) {
   1898                 SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
   1899                 android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
   1900             }
   1901         }
   1902     }
   1903 
   1904     // initialize EffectSend
   1905     // FIXME initialize EffectSend
   1906 
   1907     return result;
   1908 }
   1909 
   1910 
   1911 //-----------------------------------------------------------------------------
   1912 /**
   1913  * Called with a lock on AudioPlayer, and blocks until safe to destroy
   1914  */
   1915 SLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
   1916     SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
   1917     SLresult result = SL_RESULT_SUCCESS;
   1918 
   1919     bool disableCallbacksBeforePreDestroy;
   1920     switch (pAudioPlayer->mAndroidObjType) {
   1921     // Not yet clear why this order is important, but it reduces detected deadlocks
   1922     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   1923         disableCallbacksBeforePreDestroy = true;
   1924         break;
   1925     // Use the old behavior for all other use cases until proven
   1926     // case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   1927     default:
   1928         disableCallbacksBeforePreDestroy = false;
   1929         break;
   1930     }
   1931 
   1932     if (disableCallbacksBeforePreDestroy) {
   1933         object_unlock_exclusive(&pAudioPlayer->mObject);
   1934         if (pAudioPlayer->mCallbackProtector != 0) {
   1935             pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
   1936         }
   1937         object_lock_exclusive(&pAudioPlayer->mObject);
   1938     }
   1939 
   1940     if (pAudioPlayer->mAPlayer != 0) {
   1941         pAudioPlayer->mAPlayer->preDestroy();
   1942     }
   1943     SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
   1944 
   1945     if (!disableCallbacksBeforePreDestroy) {
   1946         object_unlock_exclusive(&pAudioPlayer->mObject);
   1947         if (pAudioPlayer->mCallbackProtector != 0) {
   1948             pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
   1949         }
   1950         object_lock_exclusive(&pAudioPlayer->mObject);
   1951     }
   1952 
   1953     return result;
   1954 }
   1955 
   1956 
   1957 //-----------------------------------------------------------------------------
   1958 SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
   1959     SLresult result = SL_RESULT_SUCCESS;
   1960     SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
   1961     switch (pAudioPlayer->mAndroidObjType) {
   1962 
   1963     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: // intended fall-throughk, both types of players
   1964                                            //   use the TrackPlayerBase for playback
   1965     case AUDIOPLAYER_FROM_URIFD:
   1966         if (pAudioPlayer->mTrackPlayer != 0) {
   1967             pAudioPlayer->mTrackPlayer->destroy();
   1968         }
   1969 
   1970         // intended fall-through
   1971     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
   1972     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
   1973     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   1974         pAudioPlayer->mAPlayer.clear();
   1975         break;
   1976     //-----------------------------------
   1977     default:
   1978         SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
   1979         result = SL_RESULT_INTERNAL_ERROR;
   1980         break;
   1981     }
   1982 
   1983     // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
   1984     // android::AudioSystem::releaseAudioSessionId(pAudioPlayer->mSessionId);
   1985 
   1986     pAudioPlayer->mTrackPlayer.clear();
   1987 
   1988     pAudioPlayer->mCallbackProtector.clear();
   1989 
   1990     // explicit destructor
   1991     pAudioPlayer->mTrackPlayer.~sp();
   1992     // note that SetPlayState(PLAYING) may still hold a reference
   1993     pAudioPlayer->mCallbackProtector.~sp();
   1994     pAudioPlayer->mAuxEffect.~sp();
   1995     pAudioPlayer->mAPlayer.~sp();
   1996 
   1997     return result;
   1998 }
   1999 
   2000 
   2001 //-----------------------------------------------------------------------------
   2002 SLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
   2003         SLuint32 constraints) {
   2004     SLresult result = SL_RESULT_SUCCESS;
   2005     switch (ap->mAndroidObjType) {
   2006     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
   2007         // these asserts were already checked by the platform-independent layer
   2008         assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
   2009                 (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
   2010         assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
   2011         // get the content sample rate
   2012         uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
   2013         // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
   2014         if (ap->mTrackPlayer->mAudioTrack != 0) {
   2015             ap->mTrackPlayer->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
   2016         }
   2017         }
   2018         break;
   2019     case AUDIOPLAYER_FROM_URIFD: {
   2020         assert((MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
   2021                         (rate <= MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE));
   2022         assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
   2023         // apply the SL ES playback rate on the GenericPlayer
   2024         if (ap->mAPlayer != 0) {
   2025             ap->mAPlayer->setPlaybackRate((int16_t)rate);
   2026         }
   2027         }
   2028         break;
   2029 
   2030     default:
   2031         SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
   2032         result = SL_RESULT_FEATURE_UNSUPPORTED;
   2033         break;
   2034     }
   2035     return result;
   2036 }
   2037 
   2038 
   2039 //-----------------------------------------------------------------------------
   2040 // precondition
   2041 //  called with no lock held
   2042 //  ap != NULL
   2043 //  pItemCount != NULL
   2044 SLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
   2045     if (ap->mAPlayer == 0) {
   2046         return SL_RESULT_PARAMETER_INVALID;
   2047     }
   2048     switch (ap->mAndroidObjType) {
   2049       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2050       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2051         {
   2052             android::AudioSfDecoder* decoder =
   2053                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2054             *pItemCount = decoder->getPcmFormatKeyCount();
   2055         }
   2056         break;
   2057       default:
   2058         *pItemCount = 0;
   2059         break;
   2060     }
   2061     return SL_RESULT_SUCCESS;
   2062 }
   2063 
   2064 
   2065 //-----------------------------------------------------------------------------
   2066 // precondition
   2067 //  called with no lock held
   2068 //  ap != NULL
   2069 //  pKeySize != NULL
   2070 SLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
   2071         SLuint32 index, SLuint32 *pKeySize) {
   2072     if (ap->mAPlayer == 0) {
   2073         return SL_RESULT_PARAMETER_INVALID;
   2074     }
   2075     SLresult res = SL_RESULT_SUCCESS;
   2076     switch (ap->mAndroidObjType) {
   2077       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2078       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2079         {
   2080             android::AudioSfDecoder* decoder =
   2081                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2082             SLuint32 keyNameSize = 0;
   2083             if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
   2084                 res = SL_RESULT_PARAMETER_INVALID;
   2085             } else {
   2086                 // *pKeySize is the size of the region used to store the key name AND
   2087                 //   the information about the key (size, lang, encoding)
   2088                 *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
   2089             }
   2090         }
   2091         break;
   2092       default:
   2093         *pKeySize = 0;
   2094         res = SL_RESULT_PARAMETER_INVALID;
   2095         break;
   2096     }
   2097     return res;
   2098 }
   2099 
   2100 
   2101 //-----------------------------------------------------------------------------
   2102 // precondition
   2103 //  called with no lock held
   2104 //  ap != NULL
   2105 //  pKey != NULL
   2106 SLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
   2107         SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
   2108     if (ap->mAPlayer == 0) {
   2109         return SL_RESULT_PARAMETER_INVALID;
   2110     }
   2111     SLresult res = SL_RESULT_SUCCESS;
   2112     switch (ap->mAndroidObjType) {
   2113       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2114       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2115         {
   2116             android::AudioSfDecoder* decoder =
   2117                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2118             if ((size < sizeof(SLMetadataInfo) ||
   2119                     (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
   2120                             (char*)pKey->data)))) {
   2121                 res = SL_RESULT_PARAMETER_INVALID;
   2122             } else {
   2123                 // successfully retrieved the key value, update the other fields
   2124                 pKey->encoding = SL_CHARACTERENCODING_UTF8;
   2125                 memcpy((char *) pKey->langCountry, "en", 3);
   2126                 pKey->size = strlen((char*)pKey->data) + 1;
   2127             }
   2128         }
   2129         break;
   2130       default:
   2131         res = SL_RESULT_PARAMETER_INVALID;
   2132         break;
   2133     }
   2134     return res;
   2135 }
   2136 
   2137 
   2138 //-----------------------------------------------------------------------------
   2139 // precondition
   2140 //  called with no lock held
   2141 //  ap != NULL
   2142 //  pValueSize != NULL
   2143 SLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
   2144         SLuint32 index, SLuint32 *pValueSize) {
   2145     if (ap->mAPlayer == 0) {
   2146         return SL_RESULT_PARAMETER_INVALID;
   2147     }
   2148     SLresult res = SL_RESULT_SUCCESS;
   2149     switch (ap->mAndroidObjType) {
   2150       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2151       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2152         {
   2153             android::AudioSfDecoder* decoder =
   2154                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2155             SLuint32 valueSize = 0;
   2156             if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
   2157                 res = SL_RESULT_PARAMETER_INVALID;
   2158             } else {
   2159                 // *pValueSize is the size of the region used to store the key value AND
   2160                 //   the information about the value (size, lang, encoding)
   2161                 *pValueSize = valueSize + sizeof(SLMetadataInfo);
   2162             }
   2163         }
   2164         break;
   2165       default:
   2166           *pValueSize = 0;
   2167           res = SL_RESULT_PARAMETER_INVALID;
   2168           break;
   2169     }
   2170     return res;
   2171 }
   2172 
   2173 
   2174 //-----------------------------------------------------------------------------
   2175 // precondition
   2176 //  called with no lock held
   2177 //  ap != NULL
   2178 //  pValue != NULL
   2179 SLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
   2180         SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
   2181     if (ap->mAPlayer == 0) {
   2182         return SL_RESULT_PARAMETER_INVALID;
   2183     }
   2184     SLresult res = SL_RESULT_SUCCESS;
   2185     switch (ap->mAndroidObjType) {
   2186       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2187       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2188         {
   2189             android::AudioSfDecoder* decoder =
   2190                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2191             pValue->encoding = SL_CHARACTERENCODING_BINARY;
   2192             memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
   2193             SLuint32 valueSize = 0;
   2194             if ((size < sizeof(SLMetadataInfo)
   2195                     || (!decoder->getPcmFormatValueSize(index, &valueSize))
   2196                     || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
   2197                             (SLuint32*)pValue->data)))) {
   2198                 res = SL_RESULT_PARAMETER_INVALID;
   2199             } else {
   2200                 pValue->size = valueSize;
   2201             }
   2202         }
   2203         break;
   2204       default:
   2205         res = SL_RESULT_PARAMETER_INVALID;
   2206         break;
   2207     }
   2208     return res;
   2209 }
   2210 
   2211 //-----------------------------------------------------------------------------
   2212 // preconditions
   2213 //  ap != NULL
   2214 //  mutex is locked
   2215 //  play state has changed
   2216 void android_audioPlayer_setPlayState(CAudioPlayer *ap) {
   2217 
   2218     SLuint32 playState = ap->mPlay.mState;
   2219 
   2220     switch (ap->mAndroidObjType) {
   2221     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2222         switch (playState) {
   2223         case SL_PLAYSTATE_STOPPED:
   2224             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
   2225             ap->mTrackPlayer->stop();
   2226             break;
   2227         case SL_PLAYSTATE_PAUSED:
   2228             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
   2229             ap->mTrackPlayer->pause();
   2230             break;
   2231         case SL_PLAYSTATE_PLAYING:
   2232             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
   2233             if (ap->mTrackPlayer->mAudioTrack != 0) {
   2234                 // instead of ap->mTrackPlayer->mAudioTrack->start();
   2235                 if (!ap->mDeferredStart) {
   2236                     // state change
   2237                     ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
   2238                 }
   2239                 ap->mDeferredStart = true;
   2240             }
   2241             break;
   2242         default:
   2243             // checked by caller, should not happen
   2244             break;
   2245         }
   2246         break;
   2247 
   2248     case AUDIOPLAYER_FROM_URIFD:
   2249         switch (playState) {
   2250         case SL_PLAYSTATE_STOPPED:
   2251             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2252             audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
   2253             break;
   2254         case SL_PLAYSTATE_PAUSED:
   2255             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2256             audioManagerPlayerEvent(ap, android::PLAYER_STATE_PAUSED);
   2257             break;
   2258         case SL_PLAYSTATE_PLAYING:
   2259             audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
   2260             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2261             break;
   2262         }
   2263         break;
   2264 
   2265     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
   2266     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
   2267     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2268         // FIXME report and use the return code to the lock mechanism, which is where play state
   2269         //   changes are updated (see object_unlock_exclusive_attributes())
   2270         aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2271         break;
   2272     default:
   2273         SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
   2274         break;
   2275     }
   2276 }
   2277 
   2278 
   2279 //-----------------------------------------------------------------------------
   2280 // call when either player event flags, marker position, or position update period changes
   2281 void android_audioPlayer_usePlayEventMask(CAudioPlayer *ap) {
   2282     IPlay *pPlayItf = &ap->mPlay;
   2283     SLuint32 eventFlags = pPlayItf->mEventFlags;
   2284     /*switch (ap->mAndroidObjType) {
   2285     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
   2286 
   2287     if (ap->mAPlayer != 0) {
   2288         assert(ap->mTrackPlayer->mAudioTrack == 0);
   2289         ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
   2290                 (int32_t) pPlayItf->mPositionUpdatePeriod);
   2291         return;
   2292     }
   2293 
   2294     if (ap->mTrackPlayer->mAudioTrack == 0) {
   2295         return;
   2296     }
   2297 
   2298     if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
   2299         ap->mTrackPlayer->mAudioTrack->setMarkerPosition(
   2300             (uint32_t) (
   2301                 (int64_t) pPlayItf->mMarkerPosition *
   2302                 sles_to_android_sampleRate(ap->mSampleRateMilliHz) /
   2303                 1000
   2304             ));
   2305     } else {
   2306         // clear marker
   2307         ap->mTrackPlayer->mAudioTrack->setMarkerPosition(0);
   2308     }
   2309 
   2310     if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
   2311          ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(
   2312                 (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
   2313                 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
   2314     } else {
   2315         // clear periodic update
   2316         ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(0);
   2317     }
   2318 
   2319     if (eventFlags & SL_PLAYEVENT_HEADATEND) {
   2320         // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
   2321     }
   2322 
   2323     if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
   2324         // FIXME support SL_PLAYEVENT_HEADMOVING
   2325         SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
   2326             "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
   2327     }
   2328     if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
   2329         // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
   2330     }
   2331 
   2332 }
   2333 
   2334 
   2335 //-----------------------------------------------------------------------------
   2336 SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
   2337     CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
   2338     switch (ap->mAndroidObjType) {
   2339 
   2340       case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
   2341       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
   2342         int32_t durationMsec = ANDROID_UNKNOWN_TIME;
   2343         if (ap->mAPlayer != 0) {
   2344             ap->mAPlayer->getDurationMsec(&durationMsec);
   2345         }
   2346         *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
   2347         break;
   2348       }
   2349 
   2350       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
   2351       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2352       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2353       default: {
   2354         *pDurMsec = SL_TIME_UNKNOWN;
   2355       }
   2356     }
   2357     return SL_RESULT_SUCCESS;
   2358 }
   2359 
   2360 
   2361 //-----------------------------------------------------------------------------
   2362 void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
   2363     CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
   2364     switch (ap->mAndroidObjType) {
   2365 
   2366       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2367         if (ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE || ap->mTrackPlayer->mAudioTrack == 0) {
   2368             *pPosMsec = 0;
   2369         } else {
   2370             uint32_t positionInFrames;
   2371             ap->mTrackPlayer->mAudioTrack->getPosition(&positionInFrames);
   2372             *pPosMsec = ((int64_t)positionInFrames * 1000) /
   2373                     sles_to_android_sampleRate(ap->mSampleRateMilliHz);
   2374         }
   2375         break;
   2376 
   2377       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
   2378       case AUDIOPLAYER_FROM_URIFD:
   2379       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2380       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
   2381         int32_t posMsec = ANDROID_UNKNOWN_TIME;
   2382         if (ap->mAPlayer != 0) {
   2383             ap->mAPlayer->getPositionMsec(&posMsec);
   2384         }
   2385         *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
   2386         break;
   2387       }
   2388 
   2389       default:
   2390         *pPosMsec = 0;
   2391     }
   2392 }
   2393 
   2394 
   2395 //-----------------------------------------------------------------------------
   2396 SLresult android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
   2397     SLresult result = SL_RESULT_SUCCESS;
   2398 
   2399     switch (ap->mAndroidObjType) {
   2400 
   2401       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
   2402       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2403       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2404         result = SL_RESULT_FEATURE_UNSUPPORTED;
   2405         break;
   2406 
   2407       case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
   2408       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2409         if (ap->mAPlayer != 0) {
   2410             ap->mAPlayer->seek(posMsec);
   2411         }
   2412         break;
   2413 
   2414       default:
   2415         break;
   2416     }
   2417     return result;
   2418 }
   2419 
   2420 
   2421 //-----------------------------------------------------------------------------
   2422 SLresult android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
   2423     SLresult result = SL_RESULT_SUCCESS;
   2424 
   2425     switch (ap->mAndroidObjType) {
   2426     case AUDIOPLAYER_FROM_URIFD:
   2427     // case AUDIOPLAY_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2428     //      would actually work, but what's the point?
   2429       if (ap->mAPlayer != 0) {
   2430         ap->mAPlayer->loop((bool)loopEnable);
   2431       }
   2432       break;
   2433     default:
   2434       result = SL_RESULT_FEATURE_UNSUPPORTED;
   2435       break;
   2436     }
   2437     return result;
   2438 }
   2439 
   2440 
   2441 //-----------------------------------------------------------------------------
   2442 SLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
   2443         SLpermille threshold) {
   2444     SLresult result = SL_RESULT_SUCCESS;
   2445 
   2446     switch (ap->mAndroidObjType) {
   2447       case AUDIOPLAYER_FROM_URIFD:
   2448         if (ap->mAPlayer != 0) {
   2449             ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
   2450         }
   2451         break;
   2452 
   2453       default: {}
   2454     }
   2455 
   2456     return result;
   2457 }
   2458 
   2459 
   2460 //-----------------------------------------------------------------------------
   2461 void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
   2462     // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
   2463     // queue was stopped when the queue become empty, we restart as soon as a new buffer
   2464     // has been enqueued since we're in playing state
   2465     if (ap->mTrackPlayer->mAudioTrack != 0) {
   2466         ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
   2467         // instead of ap->mTrackPlayer->mAudioTrack->start();
   2468         ap->mDeferredStart = true;
   2469     }
   2470 
   2471     // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
   2472     // has received new data, signal it has sufficient data
   2473     if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
   2474         // we wouldn't have been called unless we were previously in the underflow state
   2475         assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
   2476         assert(0 == ap->mPrefetchStatus.mLevel);
   2477         ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
   2478         ap->mPrefetchStatus.mLevel = 1000;
   2479         // callback or no callback?
   2480         SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
   2481                 (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
   2482         if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
   2483             ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
   2484             ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
   2485             ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
   2486         }
   2487     }
   2488 }
   2489 
   2490 
   2491 //-----------------------------------------------------------------------------
   2492 /*
   2493  * BufferQueue::Clear
   2494  */
   2495 SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
   2496     SLresult result = SL_RESULT_SUCCESS;
   2497 
   2498     switch (ap->mAndroidObjType) {
   2499     //-----------------------------------
   2500     // AudioTrack
   2501     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2502         if (ap->mTrackPlayer->mAudioTrack != 0) {
   2503             ap->mTrackPlayer->mAudioTrack->flush();
   2504         }
   2505         break;
   2506     default:
   2507         result = SL_RESULT_INTERNAL_ERROR;
   2508         break;
   2509     }
   2510 
   2511     return result;
   2512 }
   2513 
   2514 
   2515 //-----------------------------------------------------------------------------
   2516 void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
   2517     switch (ap->mAndroidObjType) {
   2518     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2519       if (ap->mAPlayer != 0) {
   2520         android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
   2521         splr->appClear_l();
   2522       } break;
   2523     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2524       // nothing to do here, fall through
   2525     default:
   2526       break;
   2527     }
   2528 }
   2529 
   2530 void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
   2531     switch (ap->mAndroidObjType) {
   2532     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2533       if (ap->mAPlayer != 0) {
   2534         android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
   2535         splr->queueRefilled();
   2536       } break;
   2537     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2538       // FIXME this may require waking up the decoder if it is currently starved and isn't polling
   2539     default:
   2540       break;
   2541     }
   2542 }
   2543