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              FALLTHROUGH_INTENDED;
    121          case ANDROID_PREPARING:
    122              FALLTHROUGH_INTENDED;
    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             FALLTHROUGH_INTENDED;
   1068         case SL_DATAFORMAT_PCM: {
   1069             // checkDataFormat() already did generic checks, now do the Android-specific checks
   1070             const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSrc->pFormat;
   1071             SLresult result = android_audioPlayer_validateChannelMask(df_pcm->channelMask,
   1072                                                                       df_pcm->numChannels);
   1073             if (result != SL_RESULT_SUCCESS) {
   1074                 SL_LOGE("Cannot create audio player: unsupported PCM data source with %u channels",
   1075                         (unsigned) df_pcm->numChannels);
   1076                 return result;
   1077             }
   1078 
   1079             // checkDataFormat() already checked sample rate
   1080 
   1081             // checkDataFormat() already checked bits per sample, container size, and representation
   1082 
   1083             // FIXME confirm the following
   1084             // df_pcm->channelMask: the earlier platform-independent check and the
   1085             //     upcoming check by sles_to_android_channelMaskOut are sufficient
   1086 
   1087             if (df_pcm->endianness != pAudioPlayer->mObject.mEngine->mEngine.mNativeEndianness) {
   1088                 SL_LOGE("Cannot create audio player: unsupported byte order %u",
   1089                         df_pcm->endianness);
   1090                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1091             }
   1092 
   1093             // we don't support container size != sample depth
   1094             if (df_pcm->containerSize != df_pcm->bitsPerSample) {
   1095                 SL_LOGE("Cannot create audio player: unsupported container size %u bits for "
   1096                         "sample depth %u bits",
   1097                         df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample);
   1098                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1099             }
   1100 
   1101             } //case SL_DATAFORMAT_PCM
   1102             break;
   1103         case SL_DATAFORMAT_MIME:
   1104         case XA_DATAFORMAT_RAWIMAGE:
   1105             SL_LOGE("Cannot create audio player with buffer queue data source "
   1106                 "without SL_DATAFORMAT_PCM format");
   1107             return SL_RESULT_CONTENT_UNSUPPORTED;
   1108         default:
   1109             // invalid data format is detected earlier
   1110             assert(false);
   1111             return SL_RESULT_INTERNAL_ERROR;
   1112         } // switch (sourceFormatType)
   1113         } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
   1114         break;
   1115     //------------------
   1116     //   URI
   1117     case SL_DATALOCATOR_URI:
   1118         {
   1119         SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
   1120         if (NULL == dl_uri->URI) {
   1121             return SL_RESULT_PARAMETER_INVALID;
   1122         }
   1123         // URI format
   1124         switch (sourceFormatType) {
   1125         case SL_DATAFORMAT_MIME:
   1126             break;
   1127         default:
   1128             SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
   1129                 "SL_DATAFORMAT_MIME format");
   1130             return SL_RESULT_CONTENT_UNSUPPORTED;
   1131         } // switch (sourceFormatType)
   1132         // decoding format check
   1133         if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
   1134                 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
   1135             return SL_RESULT_CONTENT_UNSUPPORTED;
   1136         }
   1137         } // case SL_DATALOCATOR_URI
   1138         break;
   1139     //------------------
   1140     //   File Descriptor
   1141     case SL_DATALOCATOR_ANDROIDFD:
   1142         {
   1143         // fd is already non null
   1144         switch (sourceFormatType) {
   1145         case SL_DATAFORMAT_MIME:
   1146             break;
   1147         default:
   1148             SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
   1149                 "without SL_DATAFORMAT_MIME format");
   1150             return SL_RESULT_CONTENT_UNSUPPORTED;
   1151         } // switch (sourceFormatType)
   1152         if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
   1153                 !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
   1154             return SL_RESULT_CONTENT_UNSUPPORTED;
   1155         }
   1156         } // case SL_DATALOCATOR_ANDROIDFD
   1157         break;
   1158     //------------------
   1159     //   Stream
   1160     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
   1161     {
   1162         switch (sourceFormatType) {
   1163         case SL_DATAFORMAT_MIME:
   1164         {
   1165             SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
   1166             if (NULL == df_mime) {
   1167                 SL_LOGE("MIME type null invalid");
   1168                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1169             }
   1170             SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
   1171             switch (df_mime->containerType) {
   1172             case SL_CONTAINERTYPE_MPEG_TS:
   1173                 if (strcasecmp((char*)df_mime->mimeType, (const char *)XA_ANDROID_MIME_MP2TS)) {
   1174                     SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
   1175                             (char*)df_mime->mimeType, XA_ANDROID_MIME_MP2TS);
   1176                     return SL_RESULT_CONTENT_UNSUPPORTED;
   1177                 }
   1178                 if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) {
   1179                     SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_MPEG_TS");
   1180                     return SL_RESULT_PARAMETER_INVALID;
   1181                 }
   1182                 break;
   1183             case SL_CONTAINERTYPE_RAW:
   1184             case SL_CONTAINERTYPE_AAC:
   1185                 if (strcasecmp((char*)df_mime->mimeType, (const char *)SL_ANDROID_MIME_AACADTS) &&
   1186                         strcasecmp((char*)df_mime->mimeType,
   1187                                 ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
   1188                     SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
   1189                             (char*)df_mime->mimeType, df_mime->containerType,
   1190                             SL_ANDROID_MIME_AACADTS);
   1191                     return SL_RESULT_CONTENT_UNSUPPORTED;
   1192                 }
   1193                 if (pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE) {
   1194                     SL_LOGE("Invalid sink for container SL_CONTAINERTYPE_AAC");
   1195                     return SL_RESULT_PARAMETER_INVALID;
   1196                 }
   1197                 break;
   1198             default:
   1199                 SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
   1200                                         "that is not fed MPEG-2 TS data or AAC ADTS data");
   1201                 return SL_RESULT_CONTENT_UNSUPPORTED;
   1202             }
   1203         }
   1204         break;
   1205         default:
   1206             SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
   1207                     "without SL_DATAFORMAT_MIME format");
   1208             return SL_RESULT_CONTENT_UNSUPPORTED;
   1209         }
   1210     }
   1211     break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
   1212     //------------------
   1213     //   Address
   1214     case SL_DATALOCATOR_ADDRESS:
   1215     case SL_DATALOCATOR_IODEVICE:
   1216     case SL_DATALOCATOR_OUTPUTMIX:
   1217     case XA_DATALOCATOR_NATIVEDISPLAY:
   1218     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
   1219         SL_LOGE("Cannot create audio player with data locator type 0x%x",
   1220                 (unsigned) sourceLocatorType);
   1221         return SL_RESULT_CONTENT_UNSUPPORTED;
   1222     default:
   1223         SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
   1224                 (unsigned) sourceLocatorType);
   1225         return SL_RESULT_PARAMETER_INVALID;
   1226     }// switch (locatorType)
   1227 
   1228     return SL_RESULT_SUCCESS;
   1229 }
   1230 
   1231 
   1232 //-----------------------------------------------------------------------------
   1233 // Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
   1234 // from a buffer queue. This will not be called once the AudioTrack has been destroyed.
   1235 static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
   1236     CAudioPlayer *ap = (CAudioPlayer *)user;
   1237 
   1238     if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
   1239         // it is not safe to enter the callback (the track is about to go away)
   1240         return;
   1241     }
   1242 
   1243     void * callbackPContext = NULL;
   1244     switch (event) {
   1245 
   1246     case android::AudioTrack::EVENT_MORE_DATA: {
   1247         //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
   1248         slPrefetchCallback prefetchCallback = NULL;
   1249         void *prefetchContext = NULL;
   1250         SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
   1251         android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
   1252 
   1253         // retrieve data from the buffer queue
   1254         interface_lock_exclusive(&ap->mBufferQueue);
   1255 
   1256         if (ap->mBufferQueue.mCallbackPending) {
   1257             // call callback with lock not held
   1258             slBufferQueueCallback callback = ap->mBufferQueue.mCallback;
   1259             if (NULL != callback) {
   1260                 callbackPContext = ap->mBufferQueue.mContext;
   1261                 interface_unlock_exclusive(&ap->mBufferQueue);
   1262                 (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
   1263                 interface_lock_exclusive(&ap->mBufferQueue);
   1264                 ap->mBufferQueue.mCallbackPending = false;
   1265             }
   1266         }
   1267 
   1268         if (ap->mBufferQueue.mState.count != 0) {
   1269             //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
   1270             assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
   1271 
   1272             BufferHeader *oldFront = ap->mBufferQueue.mFront;
   1273             BufferHeader *newFront = &oldFront[1];
   1274 
   1275             size_t availSource = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
   1276             size_t availSink = pBuff->size;
   1277             size_t bytesToCopy = availSource < availSink ? availSource : availSink;
   1278             void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
   1279             memcpy(pBuff->raw, pSrc, bytesToCopy);
   1280 
   1281             if (bytesToCopy < availSource) {
   1282                 ap->mBufferQueue.mSizeConsumed += bytesToCopy;
   1283                 // pBuff->size is already equal to bytesToCopy in this case
   1284             } else {
   1285                 // consumed an entire buffer, dequeue
   1286                 pBuff->size = bytesToCopy;
   1287                 ap->mBufferQueue.mSizeConsumed = 0;
   1288                 if (newFront ==
   1289                         &ap->mBufferQueue.mArray
   1290                             [ap->mBufferQueue.mNumBuffers + 1])
   1291                 {
   1292                     newFront = ap->mBufferQueue.mArray;
   1293                 }
   1294                 ap->mBufferQueue.mFront = newFront;
   1295 
   1296                 ap->mBufferQueue.mState.count--;
   1297                 ap->mBufferQueue.mState.playIndex++;
   1298                 ap->mBufferQueue.mCallbackPending = true;
   1299             }
   1300         } else { // empty queue
   1301             // signal no data available
   1302             pBuff->size = 0;
   1303 
   1304             // signal we're at the end of the content, but don't pause (see note in function)
   1305             audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
   1306 
   1307             // signal underflow to prefetch status itf
   1308             if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
   1309                 ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
   1310                 ap->mPrefetchStatus.mLevel = 0;
   1311                 // callback or no callback?
   1312                 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
   1313                         (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
   1314                 if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
   1315                     prefetchCallback = ap->mPrefetchStatus.mCallback;
   1316                     prefetchContext  = ap->mPrefetchStatus.mContext;
   1317                 }
   1318             }
   1319 
   1320             // stop the track so it restarts playing faster when new data is enqueued
   1321             ap->mTrackPlayer->stop();
   1322         }
   1323         interface_unlock_exclusive(&ap->mBufferQueue);
   1324 
   1325         // notify client
   1326         if (NULL != prefetchCallback) {
   1327             assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
   1328             // spec requires separate callbacks for each event
   1329             if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
   1330                 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
   1331                         SL_PREFETCHEVENT_STATUSCHANGE);
   1332             }
   1333             if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
   1334                 (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
   1335                         SL_PREFETCHEVENT_FILLLEVELCHANGE);
   1336             }
   1337         }
   1338     }
   1339     break;
   1340 
   1341     case android::AudioTrack::EVENT_MARKER:
   1342         //SL_LOGI("received event EVENT_MARKER from AudioTrack");
   1343         audioTrack_handleMarker_lockPlay(ap);
   1344         break;
   1345 
   1346     case android::AudioTrack::EVENT_NEW_POS:
   1347         //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
   1348         audioTrack_handleNewPos_lockPlay(ap);
   1349         break;
   1350 
   1351     case android::AudioTrack::EVENT_UNDERRUN:
   1352         //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
   1353         audioTrack_handleUnderrun_lockPlay(ap);
   1354         break;
   1355 
   1356     case android::AudioTrack::EVENT_NEW_IAUDIOTRACK:
   1357         // ignore for now
   1358         break;
   1359 
   1360     case android::AudioTrack::EVENT_BUFFER_END:
   1361     case android::AudioTrack::EVENT_LOOP_END:
   1362     case android::AudioTrack::EVENT_STREAM_END:
   1363         // These are unexpected so fall through
   1364         FALLTHROUGH_INTENDED;
   1365     default:
   1366         // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
   1367         SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
   1368                 (CAudioPlayer *)user);
   1369         break;
   1370     }
   1371 
   1372     ap->mCallbackProtector->exitCb();
   1373 }
   1374 
   1375 
   1376 //-----------------------------------------------------------------------------
   1377 void android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
   1378 
   1379     // pAudioPlayer->mAndroidObjType has been set in android_audioPlayer_checkSourceSink()
   1380     // and if it was == INVALID_TYPE, then IEngine_CreateAudioPlayer would never call us
   1381     assert(INVALID_TYPE != pAudioPlayer->mAndroidObjType);
   1382 
   1383     // These initializations are in the same order as the field declarations in classes.h
   1384 
   1385     // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
   1386     // mAndroidObjType: see above comment
   1387     pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
   1388     pAudioPlayer->mSessionId = (audio_session_t) android::AudioSystem::newAudioUniqueId(
   1389             AUDIO_UNIQUE_ID_USE_SESSION);
   1390     pAudioPlayer->mPIId = PLAYER_PIID_INVALID;
   1391 
   1392     // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
   1393     // android::AudioSystem::acquireAudioSessionId(pAudioPlayer->mSessionId);
   1394 
   1395     pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
   1396     pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
   1397 
   1398     // mAudioTrack lifecycle is handled through mTrackPlayer
   1399     pAudioPlayer->mTrackPlayer = new android::TrackPlayerBase();
   1400     assert(pAudioPlayer->mTrackPlayer != 0);
   1401     pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
   1402     // mAPLayer
   1403     // mAuxEffect
   1404 
   1405     pAudioPlayer->mAuxSendLevel = 0;
   1406     pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
   1407     pAudioPlayer->mDeferredStart = false;
   1408 
   1409     // This section re-initializes interface-specific fields that
   1410     // can be set or used regardless of whether the interface is
   1411     // exposed on the AudioPlayer or not
   1412 
   1413     switch (pAudioPlayer->mAndroidObjType) {
   1414     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   1415         pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
   1416         pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
   1417         break;
   1418     case AUDIOPLAYER_FROM_URIFD:
   1419         pAudioPlayer->mPlaybackRate.mMinRate = MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE;
   1420         pAudioPlayer->mPlaybackRate.mMaxRate = MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE;
   1421         break;
   1422     default:
   1423         // use the default range
   1424         break;
   1425     }
   1426 
   1427 }
   1428 
   1429 
   1430 //-----------------------------------------------------------------------------
   1431 SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
   1432         const void *pConfigValue, SLuint32 valueSize) {
   1433 
   1434     SLresult result;
   1435 
   1436     assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
   1437     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
   1438 
   1439         // stream type
   1440         if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
   1441             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1442             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1443         } else {
   1444             result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
   1445         }
   1446     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
   1447 
   1448         // performance mode
   1449         if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) {
   1450             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1451             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1452         } else {
   1453             result = audioPlayer_setPerformanceMode(ap, *(SLuint32*)pConfigValue);
   1454         }
   1455 
   1456     } else {
   1457         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
   1458         result = SL_RESULT_PARAMETER_INVALID;
   1459     }
   1460 
   1461     return result;
   1462 }
   1463 
   1464 
   1465 //-----------------------------------------------------------------------------
   1466 SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
   1467         SLuint32* pValueSize, void *pConfigValue) {
   1468 
   1469     SLresult result;
   1470 
   1471     assert(NULL != ap && NULL != configKey && NULL != pValueSize);
   1472     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
   1473 
   1474         // stream type
   1475         if (NULL == pConfigValue) {
   1476             result = SL_RESULT_SUCCESS;
   1477         } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
   1478             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1479             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1480         } else {
   1481             result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
   1482         }
   1483         *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
   1484 
   1485     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
   1486 
   1487         // performance mode
   1488         if (NULL == pConfigValue) {
   1489             result = SL_RESULT_SUCCESS;
   1490         } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) {
   1491             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
   1492             result = SL_RESULT_BUFFER_INSUFFICIENT;
   1493         } else {
   1494             result = audioPlayer_getPerformanceMode(ap, (SLuint32*)pConfigValue);
   1495         }
   1496         *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE;
   1497 
   1498     } else {
   1499         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
   1500         result = SL_RESULT_PARAMETER_INVALID;
   1501     }
   1502 
   1503     return result;
   1504 }
   1505 
   1506 
   1507 // Called from android_audioPlayer_realize for a PCM buffer queue player before creating the
   1508 // AudioTrack to determine which performance modes are allowed based on effect interfaces present
   1509 static void checkAndSetPerformanceModePre(CAudioPlayer *pAudioPlayer)
   1510 {
   1511     SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL;
   1512     assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
   1513 
   1514     // no need to check the buffer queue size, application side
   1515     // double-buffering (and more) is not a requirement for using fast tracks
   1516 
   1517     // Check a blacklist of interfaces that are incompatible with fast tracks.
   1518     // The alternative, to check a whitelist of compatible interfaces, is
   1519     // more maintainable but is too slow.  As a compromise, in a debug build
   1520     // we use both methods and warn if they produce different results.
   1521     // In release builds, we only use the blacklist method.
   1522     // If a blacklisted interface is added after realization using
   1523     // DynamicInterfaceManagement::AddInterface,
   1524     // then this won't be detected but the interface will be ineffective.
   1525     static const unsigned blacklist[] = {
   1526         MPH_BASSBOOST,
   1527         MPH_EFFECTSEND,
   1528         MPH_ENVIRONMENTALREVERB,
   1529         MPH_EQUALIZER,
   1530         MPH_PLAYBACKRATE,
   1531         MPH_PRESETREVERB,
   1532         MPH_VIRTUALIZER,
   1533         MPH_ANDROIDEFFECT,
   1534         MPH_ANDROIDEFFECTSEND,
   1535         // FIXME The problem with a blacklist is remembering to add new interfaces here
   1536     };
   1537     for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
   1538         if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
   1539             //TODO: query effect for EFFECT_FLAG_HW_ACC_xx flag to refine mode
   1540             allowedModes &=
   1541                     ~(ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS);
   1542             break;
   1543         }
   1544     }
   1545 #if LOG_NDEBUG == 0
   1546     bool blacklistResult = (
   1547             (allowedModes &
   1548                 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
   1549     bool whitelistResult = true;
   1550     static const unsigned whitelist[] = {
   1551         MPH_BUFFERQUEUE,
   1552         MPH_DYNAMICINTERFACEMANAGEMENT,
   1553         MPH_METADATAEXTRACTION,
   1554         MPH_MUTESOLO,
   1555         MPH_OBJECT,
   1556         MPH_PLAY,
   1557         MPH_PREFETCHSTATUS,
   1558         MPH_VOLUME,
   1559         MPH_ANDROIDCONFIGURATION,
   1560         MPH_ANDROIDSIMPLEBUFFERQUEUE,
   1561         MPH_ANDROIDBUFFERQUEUESOURCE,
   1562     };
   1563     for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
   1564         for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
   1565             if (mph == whitelist[i]) {
   1566                 goto compatible;
   1567             }
   1568         }
   1569         if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
   1570             whitelistResult = false;
   1571             break;
   1572         }
   1573 compatible: ;
   1574     }
   1575     if (whitelistResult != blacklistResult) {
   1576         SL_LOGW("whitelistResult != blacklistResult");
   1577     }
   1578 #endif
   1579     if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) {
   1580         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) {
   1581             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
   1582         }
   1583     }
   1584     if (pAudioPlayer->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) {
   1585         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) {
   1586             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1587         }
   1588     }
   1589 }
   1590 
   1591 // Called from android_audioPlayer_realize for a PCM buffer queue player after creating the
   1592 // AudioTrack to adjust performance mode based on actual output flags
   1593 static void checkAndSetPerformanceModePost(CAudioPlayer *pAudioPlayer)
   1594 {
   1595     audio_output_flags_t flags = pAudioPlayer->mTrackPlayer->mAudioTrack->getFlags();
   1596     switch (pAudioPlayer->mPerformanceMode) {
   1597     case ANDROID_PERFORMANCE_MODE_LATENCY:
   1598         if ((flags & (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) ==
   1599                 (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)) {
   1600             break;
   1601         }
   1602         pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
   1603         FALLTHROUGH_INTENDED;
   1604     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
   1605         if ((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
   1606             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1607         }
   1608         break;
   1609     case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
   1610         if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) == 0) {
   1611             pAudioPlayer->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
   1612         }
   1613         break;
   1614     case ANDROID_PERFORMANCE_MODE_NONE:
   1615     default:
   1616         break;
   1617     }
   1618 }
   1619 //-----------------------------------------------------------------------------
   1620 // FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
   1621 SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
   1622 
   1623     SLresult result = SL_RESULT_SUCCESS;
   1624     SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
   1625     AudioPlayback_Parameters app;
   1626     app.sessionId = pAudioPlayer->mSessionId;
   1627     app.streamType = pAudioPlayer->mStreamType;
   1628 
   1629     switch (pAudioPlayer->mAndroidObjType) {
   1630 
   1631     //-----------------------------------
   1632     // AudioTrack
   1633     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
   1634         // initialize platform-specific CAudioPlayer fields
   1635 
   1636         SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
   1637                 pAudioPlayer->mDynamicSource.mDataSource->pFormat;
   1638 
   1639         uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
   1640 
   1641         audio_channel_mask_t channelMask;
   1642         channelMask = sles_to_audio_output_channel_mask(df_pcm->channelMask);
   1643 
   1644         // To maintain backward compatibility with previous releases, ignore
   1645         // channel masks that are not indexed.
   1646         if (channelMask == AUDIO_CHANNEL_INVALID
   1647                 || audio_channel_mask_get_representation(channelMask)
   1648                         == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
   1649             channelMask = audio_channel_out_mask_from_count(df_pcm->numChannels);
   1650             SL_LOGI("Emulating old channel mask behavior "
   1651                     "(ignoring positional mask %#x, using default mask %#x based on "
   1652                     "channel count of %d)", df_pcm->channelMask, channelMask,
   1653                     df_pcm->numChannels);
   1654         }
   1655         SL_LOGV("AudioPlayer: mapped SLES channel mask %#x to android channel mask %#x",
   1656             df_pcm->channelMask,
   1657             channelMask);
   1658 
   1659         checkAndSetPerformanceModePre(pAudioPlayer);
   1660 
   1661         audio_output_flags_t policy;
   1662         switch (pAudioPlayer->mPerformanceMode) {
   1663         case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
   1664             policy = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
   1665             break;
   1666         case ANDROID_PERFORMANCE_MODE_NONE:
   1667             policy = AUDIO_OUTPUT_FLAG_NONE;
   1668             break;
   1669         case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
   1670             policy = AUDIO_OUTPUT_FLAG_FAST;
   1671             break;
   1672         case ANDROID_PERFORMANCE_MODE_LATENCY:
   1673         default:
   1674             policy = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
   1675             break;
   1676         }
   1677 
   1678         int32_t notificationFrames;
   1679         if ((policy & AUDIO_OUTPUT_FLAG_FAST) != 0) {
   1680             // negative notificationFrames is the number of notifications (sub-buffers) per track
   1681             // buffer for details see the explanation at frameworks/av/include/media/AudioTrack.h
   1682             notificationFrames = -pAudioPlayer->mBufferQueue.mNumBuffers;
   1683         } else {
   1684             notificationFrames = 0;
   1685         }
   1686 
   1687         android::AudioTrack* pat = new android::AudioTrack(
   1688                 pAudioPlayer->mStreamType,                           // streamType
   1689                 sampleRate,                                          // sampleRate
   1690                 sles_to_android_sampleFormat(df_pcm),                // format
   1691                 channelMask,                                         // channel mask
   1692                 0,                                                   // frameCount
   1693                 policy,                                              // flags
   1694                 audioTrack_callBack_pullFromBuffQueue,               // callback
   1695                 (void *) pAudioPlayer,                               // user
   1696                 notificationFrames,                                  // see comment above
   1697                 pAudioPlayer->mSessionId);
   1698         android::status_t status = pat->initCheck();
   1699         if (status != android::NO_ERROR) {
   1700             // AudioTracks are meant to be refcounted, so their dtor is protected.
   1701             static_cast<void>(android::sp<android::AudioTrack>(pat));
   1702 
   1703             SL_LOGE("AudioTrack::initCheck status %u", status);
   1704             // FIXME should return a more specific result depending on status
   1705             result = SL_RESULT_CONTENT_UNSUPPORTED;
   1706             return result;
   1707         }
   1708 
   1709         pAudioPlayer->mTrackPlayer->init(pat, android::PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE,
   1710                 usageForStreamType(pAudioPlayer->mStreamType));
   1711 
   1712         // update performance mode according to actual flags granted to AudioTrack
   1713         checkAndSetPerformanceModePost(pAudioPlayer);
   1714 
   1715         // initialize platform-independent CAudioPlayer fields
   1716 
   1717         pAudioPlayer->mNumChannels = df_pcm->numChannels;
   1718         pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
   1719 
   1720         // This use case does not have a separate "prepare" step
   1721         pAudioPlayer->mAndroidObjState = ANDROID_READY;
   1722 
   1723         // If there is a JavaAudioRoutingProxy associated with this player, hook it up...
   1724         JNIEnv* j_env = NULL;
   1725         jclass clsAudioTrack = NULL;
   1726         jmethodID midRoutingProxy_connect = NULL;
   1727         if (pAudioPlayer->mAndroidConfiguration.mRoutingProxy != NULL &&
   1728                 (j_env = android::AndroidRuntime::getJNIEnv()) != NULL &&
   1729                 (clsAudioTrack = j_env->FindClass("android/media/AudioTrack")) != NULL &&
   1730                 (midRoutingProxy_connect =
   1731                     j_env->GetMethodID(clsAudioTrack, "deferred_connect", "(J)V")) != NULL) {
   1732             j_env->ExceptionClear();
   1733             j_env->CallVoidMethod(pAudioPlayer->mAndroidConfiguration.mRoutingProxy,
   1734                                   midRoutingProxy_connect,
   1735                                   (jlong)pAudioPlayer->mTrackPlayer->mAudioTrack.get());
   1736             if (j_env->ExceptionCheck()) {
   1737                 SL_LOGE("Java exception releasing player routing object.");
   1738                 result = SL_RESULT_INTERNAL_ERROR;
   1739                 pAudioPlayer->mTrackPlayer->mAudioTrack.clear();
   1740                 return result;
   1741             }
   1742         }
   1743     }
   1744         break;
   1745 
   1746     //-----------------------------------
   1747     // MediaPlayer
   1748     case AUDIOPLAYER_FROM_URIFD: {
   1749         pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
   1750         pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
   1751                         (void*)pAudioPlayer /*notifUSer*/);
   1752 
   1753         switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
   1754             case SL_DATALOCATOR_URI: {
   1755                 // The legacy implementation ran Stagefright within the application process, and
   1756                 // so allowed local pathnames specified by URI that were openable by
   1757                 // the application but were not openable by mediaserver.
   1758                 // The current implementation runs Stagefright (mostly) within mediaserver,
   1759                 // which runs as a different UID and likely a different current working directory.
   1760                 // For backwards compatibility with any applications which may have relied on the
   1761                 // previous behavior, we convert an openable file URI into an FD.
   1762                 // Note that unlike SL_DATALOCATOR_ANDROIDFD, this FD is owned by us
   1763                 // and so we close it as soon as we've passed it (via Binder dup) to mediaserver.
   1764                 const char *uri = (const char *)pAudioPlayer->mDataSource.mLocator.mURI.URI;
   1765                 if (!isDistantProtocol(uri)) {
   1766                     // don't touch the original uri, we may need it later
   1767                     const char *pathname = uri;
   1768                     // skip over an optional leading file:// prefix
   1769                     if (!strncasecmp(pathname, "file://", 7)) {
   1770                         pathname += 7;
   1771                     }
   1772                     // attempt to open it as a file using the application's credentials
   1773                     int fd = ::open(pathname, O_RDONLY);
   1774                     if (fd >= 0) {
   1775                         // if open is successful, then check to see if it's a regular file
   1776                         struct stat statbuf;
   1777                         if (!::fstat(fd, &statbuf) && S_ISREG(statbuf.st_mode)) {
   1778                             // treat similarly to an FD data locator, but
   1779                             // let setDataSource take responsibility for closing fd
   1780                             pAudioPlayer->mAPlayer->setDataSource(fd, 0, statbuf.st_size, true);
   1781                             break;
   1782                         }
   1783                         // we were able to open it, but it's not a file, so let mediaserver try
   1784                         (void) ::close(fd);
   1785                     }
   1786                 }
   1787                 // if either the URI didn't look like a file, or open failed, or not a file
   1788                 pAudioPlayer->mAPlayer->setDataSource(uri);
   1789                 } break;
   1790             case SL_DATALOCATOR_ANDROIDFD: {
   1791                 int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
   1792                 pAudioPlayer->mAPlayer->setDataSource(
   1793                         (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
   1794                         offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
   1795                                 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
   1796                         (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
   1797                 }
   1798                 break;
   1799             default:
   1800                 SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
   1801                 break;
   1802         }
   1803 
   1804         if (pAudioPlayer->mObject.mEngine->mAudioManager == 0) {
   1805             SL_LOGE("AudioPlayer realize: no audio service, player will not be registered");
   1806             pAudioPlayer->mPIId = 0;
   1807         } else {
   1808             pAudioPlayer->mPIId = pAudioPlayer->mObject.mEngine->mAudioManager->trackPlayer(
   1809                     android::PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD,
   1810                     usageForStreamType(pAudioPlayer->mStreamType), AUDIO_CONTENT_TYPE_UNKNOWN,
   1811                     pAudioPlayer->mTrackPlayer);
   1812         }
   1813         }
   1814         break;
   1815 
   1816     //-----------------------------------
   1817     // StreamPlayer
   1818     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
   1819         android::StreamPlayer* splr = new android::StreamPlayer(&app, false /*hasVideo*/,
   1820                 &pAudioPlayer->mAndroidBufferQueue, pAudioPlayer->mCallbackProtector);
   1821         pAudioPlayer->mAPlayer = splr;
   1822         splr->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1823         }
   1824         break;
   1825 
   1826     //-----------------------------------
   1827     // AudioToCbRenderer
   1828     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
   1829         android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
   1830         pAudioPlayer->mAPlayer = decoder;
   1831         // configures the callback for the sink buffer queue
   1832         decoder->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
   1833         // configures the callback for the notifications coming from the SF code
   1834         decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1835 
   1836         switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
   1837         case SL_DATALOCATOR_URI:
   1838             decoder->setDataSource(
   1839                     (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
   1840             break;
   1841         case SL_DATALOCATOR_ANDROIDFD: {
   1842             int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
   1843             decoder->setDataSource(
   1844                     (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
   1845                     offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
   1846                             (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
   1847                             (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
   1848             }
   1849             break;
   1850         default:
   1851             SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
   1852             break;
   1853         }
   1854 
   1855         }
   1856         break;
   1857 
   1858     //-----------------------------------
   1859     // AacBqToPcmCbRenderer
   1860     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
   1861         android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app,
   1862                 &pAudioPlayer->mAndroidBufferQueue);
   1863         // configures the callback for the sink buffer queue
   1864         bqtobq->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
   1865         pAudioPlayer->mAPlayer = bqtobq;
   1866         // configures the callback for the notifications coming from the SF code,
   1867         // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
   1868         pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
   1869         }
   1870         break;
   1871 
   1872     //-----------------------------------
   1873     default:
   1874         SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
   1875         result = SL_RESULT_INTERNAL_ERROR;
   1876         break;
   1877     }
   1878 
   1879     if (result == SL_RESULT_SUCCESS) {
   1880         // proceed with effect initialization
   1881         // initialize EQ
   1882         // FIXME use a table of effect descriptors when adding support for more effects
   1883 
   1884         // No session effects allowed even in latency with effects performance mode because HW
   1885         // accelerated effects are only tolerated as post processing in this mode
   1886         if ((pAudioPlayer->mAndroidObjType != AUDIOPLAYER_FROM_PCM_BUFFERQUEUE) ||
   1887                 ((pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) &&
   1888                  (pAudioPlayer->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS))) {
   1889             if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
   1890                     sizeof(effect_uuid_t)) == 0) {
   1891                 SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
   1892                 android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
   1893             }
   1894             // initialize BassBoost
   1895             if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
   1896                     sizeof(effect_uuid_t)) == 0) {
   1897                 SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
   1898                 android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
   1899             }
   1900             // initialize Virtualizer
   1901             if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
   1902                        sizeof(effect_uuid_t)) == 0) {
   1903                 SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
   1904                 android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
   1905             }
   1906         }
   1907     }
   1908 
   1909     // initialize EffectSend
   1910     // FIXME initialize EffectSend
   1911 
   1912     return result;
   1913 }
   1914 
   1915 
   1916 //-----------------------------------------------------------------------------
   1917 /**
   1918  * Called with a lock on AudioPlayer, and blocks until safe to destroy
   1919  */
   1920 SLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
   1921     SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
   1922     SLresult result = SL_RESULT_SUCCESS;
   1923 
   1924     bool disableCallbacksBeforePreDestroy;
   1925     switch (pAudioPlayer->mAndroidObjType) {
   1926     // Not yet clear why this order is important, but it reduces detected deadlocks
   1927     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   1928         disableCallbacksBeforePreDestroy = true;
   1929         break;
   1930     // Use the old behavior for all other use cases until proven
   1931     // case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   1932     default:
   1933         disableCallbacksBeforePreDestroy = false;
   1934         break;
   1935     }
   1936 
   1937     if (disableCallbacksBeforePreDestroy) {
   1938         object_unlock_exclusive(&pAudioPlayer->mObject);
   1939         if (pAudioPlayer->mCallbackProtector != 0) {
   1940             pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
   1941         }
   1942         object_lock_exclusive(&pAudioPlayer->mObject);
   1943     }
   1944 
   1945     if (pAudioPlayer->mAPlayer != 0) {
   1946         pAudioPlayer->mAPlayer->preDestroy();
   1947     }
   1948     SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
   1949 
   1950     if (!disableCallbacksBeforePreDestroy) {
   1951         object_unlock_exclusive(&pAudioPlayer->mObject);
   1952         if (pAudioPlayer->mCallbackProtector != 0) {
   1953             pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
   1954         }
   1955         object_lock_exclusive(&pAudioPlayer->mObject);
   1956     }
   1957 
   1958     return result;
   1959 }
   1960 
   1961 
   1962 //-----------------------------------------------------------------------------
   1963 SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
   1964     SLresult result = SL_RESULT_SUCCESS;
   1965     SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
   1966     switch (pAudioPlayer->mAndroidObjType) {
   1967 
   1968     case AUDIOPLAYER_FROM_URIFD:
   1969         if (pAudioPlayer->mObject.mEngine->mAudioManager != 0) {
   1970             pAudioPlayer->mObject.mEngine->mAudioManager->releasePlayer(pAudioPlayer->mPIId);
   1971         }
   1972         // intended fall-throughk, both types of players
   1973         // use the TrackPlayerBase for playback
   1974         FALLTHROUGH_INTENDED;
   1975     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   1976         if (pAudioPlayer->mTrackPlayer != 0) {
   1977             pAudioPlayer->mTrackPlayer->destroy();
   1978         }
   1979         FALLTHROUGH_INTENDED;
   1980     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   1981         FALLTHROUGH_INTENDED;
   1982     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   1983         FALLTHROUGH_INTENDED;
   1984     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   1985         pAudioPlayer->mAPlayer.clear();
   1986         break;
   1987     //-----------------------------------
   1988     default:
   1989         SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
   1990         result = SL_RESULT_INTERNAL_ERROR;
   1991         break;
   1992     }
   1993 
   1994     // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
   1995     // android::AudioSystem::releaseAudioSessionId(pAudioPlayer->mSessionId);
   1996 
   1997     pAudioPlayer->mTrackPlayer.clear();
   1998 
   1999     pAudioPlayer->mCallbackProtector.clear();
   2000 
   2001     // explicit destructor
   2002     pAudioPlayer->mTrackPlayer.~sp();
   2003     // note that SetPlayState(PLAYING) may still hold a reference
   2004     pAudioPlayer->mCallbackProtector.~sp();
   2005     pAudioPlayer->mAuxEffect.~sp();
   2006     pAudioPlayer->mAPlayer.~sp();
   2007 
   2008     return result;
   2009 }
   2010 
   2011 
   2012 //-----------------------------------------------------------------------------
   2013 SLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
   2014         SLuint32 constraints) {
   2015     SLresult result = SL_RESULT_SUCCESS;
   2016     switch (ap->mAndroidObjType) {
   2017     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
   2018         // these asserts were already checked by the platform-independent layer
   2019         assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
   2020                 (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
   2021         assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
   2022         // get the content sample rate
   2023         uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
   2024         // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
   2025         if (ap->mTrackPlayer->mAudioTrack != 0) {
   2026             ap->mTrackPlayer->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
   2027         }
   2028         }
   2029         break;
   2030     case AUDIOPLAYER_FROM_URIFD: {
   2031         assert((MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
   2032                         (rate <= MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE));
   2033         assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
   2034         // apply the SL ES playback rate on the GenericPlayer
   2035         if (ap->mAPlayer != 0) {
   2036             ap->mAPlayer->setPlaybackRate((int16_t)rate);
   2037         }
   2038         }
   2039         break;
   2040 
   2041     default:
   2042         SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
   2043         result = SL_RESULT_FEATURE_UNSUPPORTED;
   2044         break;
   2045     }
   2046     return result;
   2047 }
   2048 
   2049 
   2050 //-----------------------------------------------------------------------------
   2051 // precondition
   2052 //  called with no lock held
   2053 //  ap != NULL
   2054 //  pItemCount != NULL
   2055 SLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
   2056     if (ap->mAPlayer == 0) {
   2057         return SL_RESULT_PARAMETER_INVALID;
   2058     }
   2059     switch (ap->mAndroidObjType) {
   2060       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2061       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2062         {
   2063             android::AudioSfDecoder* decoder =
   2064                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2065             *pItemCount = decoder->getPcmFormatKeyCount();
   2066         }
   2067         break;
   2068       default:
   2069         *pItemCount = 0;
   2070         break;
   2071     }
   2072     return SL_RESULT_SUCCESS;
   2073 }
   2074 
   2075 
   2076 //-----------------------------------------------------------------------------
   2077 // precondition
   2078 //  called with no lock held
   2079 //  ap != NULL
   2080 //  pKeySize != NULL
   2081 SLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
   2082         SLuint32 index, SLuint32 *pKeySize) {
   2083     if (ap->mAPlayer == 0) {
   2084         return SL_RESULT_PARAMETER_INVALID;
   2085     }
   2086     SLresult res = SL_RESULT_SUCCESS;
   2087     switch (ap->mAndroidObjType) {
   2088       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2089       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2090         {
   2091             android::AudioSfDecoder* decoder =
   2092                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2093             SLuint32 keyNameSize = 0;
   2094             if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
   2095                 res = SL_RESULT_PARAMETER_INVALID;
   2096             } else {
   2097                 // *pKeySize is the size of the region used to store the key name AND
   2098                 //   the information about the key (size, lang, encoding)
   2099                 *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
   2100             }
   2101         }
   2102         break;
   2103       default:
   2104         *pKeySize = 0;
   2105         res = SL_RESULT_PARAMETER_INVALID;
   2106         break;
   2107     }
   2108     return res;
   2109 }
   2110 
   2111 
   2112 //-----------------------------------------------------------------------------
   2113 // precondition
   2114 //  called with no lock held
   2115 //  ap != NULL
   2116 //  pKey != NULL
   2117 SLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
   2118         SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
   2119     if (ap->mAPlayer == 0) {
   2120         return SL_RESULT_PARAMETER_INVALID;
   2121     }
   2122     SLresult res = SL_RESULT_SUCCESS;
   2123     switch (ap->mAndroidObjType) {
   2124       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2125       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2126         {
   2127             android::AudioSfDecoder* decoder =
   2128                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2129             if ((size < sizeof(SLMetadataInfo) ||
   2130                     (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
   2131                             (char*)pKey->data)))) {
   2132                 res = SL_RESULT_PARAMETER_INVALID;
   2133             } else {
   2134                 // successfully retrieved the key value, update the other fields
   2135                 pKey->encoding = SL_CHARACTERENCODING_UTF8;
   2136                 memcpy((char *) pKey->langCountry, "en", 3);
   2137                 pKey->size = strlen((char*)pKey->data) + 1;
   2138             }
   2139         }
   2140         break;
   2141       default:
   2142         res = SL_RESULT_PARAMETER_INVALID;
   2143         break;
   2144     }
   2145     return res;
   2146 }
   2147 
   2148 
   2149 //-----------------------------------------------------------------------------
   2150 // precondition
   2151 //  called with no lock held
   2152 //  ap != NULL
   2153 //  pValueSize != NULL
   2154 SLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
   2155         SLuint32 index, SLuint32 *pValueSize) {
   2156     if (ap->mAPlayer == 0) {
   2157         return SL_RESULT_PARAMETER_INVALID;
   2158     }
   2159     SLresult res = SL_RESULT_SUCCESS;
   2160     switch (ap->mAndroidObjType) {
   2161       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2162       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2163         {
   2164             android::AudioSfDecoder* decoder =
   2165                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2166             SLuint32 valueSize = 0;
   2167             if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
   2168                 res = SL_RESULT_PARAMETER_INVALID;
   2169             } else {
   2170                 // *pValueSize is the size of the region used to store the key value AND
   2171                 //   the information about the value (size, lang, encoding)
   2172                 *pValueSize = valueSize + sizeof(SLMetadataInfo);
   2173             }
   2174         }
   2175         break;
   2176       default:
   2177           *pValueSize = 0;
   2178           res = SL_RESULT_PARAMETER_INVALID;
   2179           break;
   2180     }
   2181     return res;
   2182 }
   2183 
   2184 
   2185 //-----------------------------------------------------------------------------
   2186 // precondition
   2187 //  called with no lock held
   2188 //  ap != NULL
   2189 //  pValue != NULL
   2190 SLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
   2191         SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
   2192     if (ap->mAPlayer == 0) {
   2193         return SL_RESULT_PARAMETER_INVALID;
   2194     }
   2195     SLresult res = SL_RESULT_SUCCESS;
   2196     switch (ap->mAndroidObjType) {
   2197       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2198       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2199         {
   2200             android::AudioSfDecoder* decoder =
   2201                     static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
   2202             pValue->encoding = SL_CHARACTERENCODING_BINARY;
   2203             memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
   2204             SLuint32 valueSize = 0;
   2205             if ((size < sizeof(SLMetadataInfo)
   2206                     || (!decoder->getPcmFormatValueSize(index, &valueSize))
   2207                     || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
   2208                             (SLuint32*)pValue->data)))) {
   2209                 res = SL_RESULT_PARAMETER_INVALID;
   2210             } else {
   2211                 pValue->size = valueSize;
   2212             }
   2213         }
   2214         break;
   2215       default:
   2216         res = SL_RESULT_PARAMETER_INVALID;
   2217         break;
   2218     }
   2219     return res;
   2220 }
   2221 
   2222 //-----------------------------------------------------------------------------
   2223 // preconditions
   2224 //  ap != NULL
   2225 //  mutex is locked
   2226 //  play state has changed
   2227 void android_audioPlayer_setPlayState(CAudioPlayer *ap) {
   2228 
   2229     SLuint32 playState = ap->mPlay.mState;
   2230 
   2231     switch (ap->mAndroidObjType) {
   2232     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2233         switch (playState) {
   2234         case SL_PLAYSTATE_STOPPED:
   2235             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
   2236             ap->mTrackPlayer->stop();
   2237             break;
   2238         case SL_PLAYSTATE_PAUSED:
   2239             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
   2240             ap->mTrackPlayer->pause();
   2241             break;
   2242         case SL_PLAYSTATE_PLAYING:
   2243             SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
   2244             if (ap->mTrackPlayer->mAudioTrack != 0) {
   2245                 // instead of ap->mTrackPlayer->mAudioTrack->start();
   2246                 if (!ap->mDeferredStart) {
   2247                     // state change
   2248                     ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
   2249                 }
   2250                 ap->mDeferredStart = true;
   2251             }
   2252             break;
   2253         default:
   2254             // checked by caller, should not happen
   2255             break;
   2256         }
   2257         break;
   2258 
   2259     case AUDIOPLAYER_FROM_URIFD:
   2260         switch (playState) {
   2261         case SL_PLAYSTATE_STOPPED:
   2262             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2263             audioManagerPlayerEvent(ap, android::PLAYER_STATE_STOPPED);
   2264             break;
   2265         case SL_PLAYSTATE_PAUSED:
   2266             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2267             audioManagerPlayerEvent(ap, android::PLAYER_STATE_PAUSED);
   2268             break;
   2269         case SL_PLAYSTATE_PLAYING:
   2270             audioManagerPlayerEvent(ap, android::PLAYER_STATE_STARTED);
   2271             aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2272             break;
   2273         }
   2274         break;
   2275 
   2276     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2277         FALLTHROUGH_INTENDED;
   2278     case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2279         FALLTHROUGH_INTENDED;
   2280     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2281         // FIXME report and use the return code to the lock mechanism, which is where play state
   2282         //   changes are updated (see object_unlock_exclusive_attributes())
   2283         aplayer_setPlayState(ap->mAPlayer, playState, &ap->mAndroidObjState);
   2284         break;
   2285     default:
   2286         SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
   2287         break;
   2288     }
   2289 }
   2290 
   2291 
   2292 //-----------------------------------------------------------------------------
   2293 // call when either player event flags, marker position, or position update period changes
   2294 void android_audioPlayer_usePlayEventMask(CAudioPlayer *ap) {
   2295     IPlay *pPlayItf = &ap->mPlay;
   2296     SLuint32 eventFlags = pPlayItf->mEventFlags;
   2297     /*switch (ap->mAndroidObjType) {
   2298     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
   2299 
   2300     if (ap->mAPlayer != 0) {
   2301         assert(ap->mTrackPlayer->mAudioTrack == 0);
   2302         ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
   2303                 (int32_t) pPlayItf->mPositionUpdatePeriod);
   2304         return;
   2305     }
   2306 
   2307     if (ap->mTrackPlayer->mAudioTrack == 0) {
   2308         return;
   2309     }
   2310 
   2311     if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
   2312         ap->mTrackPlayer->mAudioTrack->setMarkerPosition(
   2313             (uint32_t) (
   2314                 (int64_t) pPlayItf->mMarkerPosition *
   2315                 sles_to_android_sampleRate(ap->mSampleRateMilliHz) /
   2316                 1000
   2317             ));
   2318     } else {
   2319         // clear marker
   2320         ap->mTrackPlayer->mAudioTrack->setMarkerPosition(0);
   2321     }
   2322 
   2323     if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
   2324          ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(
   2325                 (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
   2326                 * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
   2327     } else {
   2328         // clear periodic update
   2329         ap->mTrackPlayer->mAudioTrack->setPositionUpdatePeriod(0);
   2330     }
   2331 
   2332     if (eventFlags & SL_PLAYEVENT_HEADATEND) {
   2333         // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
   2334     }
   2335 
   2336     if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
   2337         // FIXME support SL_PLAYEVENT_HEADMOVING
   2338         SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
   2339             "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
   2340     }
   2341     if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
   2342         // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
   2343     }
   2344 
   2345 }
   2346 
   2347 
   2348 //-----------------------------------------------------------------------------
   2349 SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
   2350     CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
   2351     switch (ap->mAndroidObjType) {
   2352 
   2353       case AUDIOPLAYER_FROM_URIFD:
   2354         FALLTHROUGH_INTENDED;
   2355       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
   2356         int32_t durationMsec = ANDROID_UNKNOWN_TIME;
   2357         if (ap->mAPlayer != 0) {
   2358             ap->mAPlayer->getDurationMsec(&durationMsec);
   2359         }
   2360         *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
   2361         break;
   2362       }
   2363 
   2364       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
   2365       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2366       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2367       default: {
   2368         *pDurMsec = SL_TIME_UNKNOWN;
   2369       }
   2370     }
   2371     return SL_RESULT_SUCCESS;
   2372 }
   2373 
   2374 
   2375 //-----------------------------------------------------------------------------
   2376 void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
   2377     CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
   2378     switch (ap->mAndroidObjType) {
   2379 
   2380       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2381         if (ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE || ap->mTrackPlayer->mAudioTrack == 0) {
   2382             *pPosMsec = 0;
   2383         } else {
   2384             uint32_t positionInFrames;
   2385             ap->mTrackPlayer->mAudioTrack->getPosition(&positionInFrames);
   2386             *pPosMsec = ((int64_t)positionInFrames * 1000) /
   2387                     sles_to_android_sampleRate(ap->mSampleRateMilliHz);
   2388         }
   2389         break;
   2390 
   2391       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
   2392       case AUDIOPLAYER_FROM_URIFD:
   2393       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2394       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
   2395         int32_t posMsec = ANDROID_UNKNOWN_TIME;
   2396         if (ap->mAPlayer != 0) {
   2397             ap->mAPlayer->getPositionMsec(&posMsec);
   2398         }
   2399         *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
   2400         break;
   2401       }
   2402 
   2403       default:
   2404         *pPosMsec = 0;
   2405     }
   2406 }
   2407 
   2408 
   2409 //-----------------------------------------------------------------------------
   2410 SLresult android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
   2411     SLresult result = SL_RESULT_SUCCESS;
   2412 
   2413     switch (ap->mAndroidObjType) {
   2414 
   2415       case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
   2416       case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2417       case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2418         result = SL_RESULT_FEATURE_UNSUPPORTED;
   2419         break;
   2420 
   2421       case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
   2422       case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2423         if (ap->mAPlayer != 0) {
   2424             ap->mAPlayer->seek(posMsec);
   2425         }
   2426         break;
   2427 
   2428       default:
   2429         break;
   2430     }
   2431     return result;
   2432 }
   2433 
   2434 
   2435 //-----------------------------------------------------------------------------
   2436 SLresult android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
   2437     SLresult result = SL_RESULT_SUCCESS;
   2438 
   2439     switch (ap->mAndroidObjType) {
   2440     case AUDIOPLAYER_FROM_URIFD:
   2441     // case AUDIOPLAY_FROM_URIFD_TO_PCM_BUFFERQUEUE:
   2442     //      would actually work, but what's the point?
   2443       if (ap->mAPlayer != 0) {
   2444         ap->mAPlayer->loop((bool)loopEnable);
   2445       }
   2446       break;
   2447     default:
   2448       result = SL_RESULT_FEATURE_UNSUPPORTED;
   2449       break;
   2450     }
   2451     return result;
   2452 }
   2453 
   2454 
   2455 //-----------------------------------------------------------------------------
   2456 SLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
   2457         SLpermille threshold) {
   2458     SLresult result = SL_RESULT_SUCCESS;
   2459 
   2460     switch (ap->mAndroidObjType) {
   2461       case AUDIOPLAYER_FROM_URIFD:
   2462         if (ap->mAPlayer != 0) {
   2463             ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
   2464         }
   2465         break;
   2466 
   2467       default: {}
   2468     }
   2469 
   2470     return result;
   2471 }
   2472 
   2473 
   2474 //-----------------------------------------------------------------------------
   2475 void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
   2476     // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
   2477     // queue was stopped when the queue become empty, we restart as soon as a new buffer
   2478     // has been enqueued since we're in playing state
   2479     if (ap->mTrackPlayer->mAudioTrack != 0) {
   2480         ap->mTrackPlayer->reportEvent(android::PLAYER_STATE_STARTED);
   2481         // instead of ap->mTrackPlayer->mAudioTrack->start();
   2482         ap->mDeferredStart = true;
   2483     }
   2484 
   2485     // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
   2486     // has received new data, signal it has sufficient data
   2487     if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
   2488         // we wouldn't have been called unless we were previously in the underflow state
   2489         assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
   2490         assert(0 == ap->mPrefetchStatus.mLevel);
   2491         ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
   2492         ap->mPrefetchStatus.mLevel = 1000;
   2493         // callback or no callback?
   2494         SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
   2495                 (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
   2496         if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
   2497             ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
   2498             ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
   2499             ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
   2500         }
   2501     }
   2502 }
   2503 
   2504 
   2505 //-----------------------------------------------------------------------------
   2506 /*
   2507  * BufferQueue::Clear
   2508  */
   2509 SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
   2510     SLresult result = SL_RESULT_SUCCESS;
   2511 
   2512     switch (ap->mAndroidObjType) {
   2513     //-----------------------------------
   2514     // AudioTrack
   2515     case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
   2516         if (ap->mTrackPlayer->mAudioTrack != 0) {
   2517             ap->mTrackPlayer->mAudioTrack->flush();
   2518         }
   2519         break;
   2520     default:
   2521         result = SL_RESULT_INTERNAL_ERROR;
   2522         break;
   2523     }
   2524 
   2525     return result;
   2526 }
   2527 
   2528 
   2529 //-----------------------------------------------------------------------------
   2530 void android_audioPlayer_androidBufferQueue_clear_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->appClear_l();
   2536       } break;
   2537     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2538       // nothing to do here, fall through
   2539       FALLTHROUGH_INTENDED;
   2540     default:
   2541       break;
   2542     }
   2543 }
   2544 
   2545 void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
   2546     switch (ap->mAndroidObjType) {
   2547     case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
   2548       if (ap->mAPlayer != 0) {
   2549         android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
   2550         splr->queueRefilled();
   2551       } break;
   2552     case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
   2553       // FIXME this may require waking up the decoder if it is currently starved and isn't polling
   2554     default:
   2555       break;
   2556     }
   2557 }
   2558