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
audioManagerPlayerEvent(CAudioPlayer * ap,android::player_state_t event)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.
usageForStreamType(audio_stream_type_t streamType)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
aplayer_setPlayState(const android::sp<android::GenericPlayer> & ap,SLuint32 playState,AndroidObjectState * pObjState)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
adecoder_writeToBufferQueue(const uint8_t * data,size_t size,CAudioPlayer * ap)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 
android_audioPlayer_volumeUpdate(CAudioPlayer * ap)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 
android_player_volumeUpdate(float * pVolumes,const IVolume * volumeItf,unsigned channelCount,float amplFromDirectLevel,const bool * audibilityFactors)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 //-----------------------------------------------------------------------------
audioTrack_handleMarker_lockPlay(CAudioPlayer * ap)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 //-----------------------------------------------------------------------------
audioTrack_handleNewPos_lockPlay(CAudioPlayer * ap)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 //-----------------------------------------------------------------------------
audioTrack_handleUnderrun_lockPlay(CAudioPlayer * ap)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  */
audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer * ap,bool setPlayStateToPaused,bool needToLock)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 //-----------------------------------------------------------------------------
audioPlayer_setStreamType(CAudioPlayer * ap,SLint32 type)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 //-----------------------------------------------------------------------------
audioPlayer_setPerformanceMode(CAudioPlayer * ap,SLuint32 mode)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 //-----------------------------------------------------------------------------
audioPlayer_getStreamType(CAudioPlayer * ap,SLint32 * pType)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 //-----------------------------------------------------------------------------
audioPlayer_getPerformanceMode(CAudioPlayer * ap,SLuint32 * pMode)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 //-----------------------------------------------------------------------------
audioPlayer_auxEffectUpdate(CAudioPlayer * ap)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  */
audioPlayer_isSupportedNonOutputMixSink(const SLDataSink * pAudioSink)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
audioPlayer_getAndroidObjectTypeForSourceSink(const CAudioPlayer * ap)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  */
sfplayer_handlePrefetchEvent(int event,int data1,int data2,void * user)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
android_audioPlayer_validateChannelMask(uint32_t mask,uint32_t numChans)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 //-----------------------------------------------------------------------------
android_audioPlayer_checkSourceSink(CAudioPlayer * pAudioPlayer)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.
audioTrack_callBack_pullFromBuffQueue(int event,void * user,void * info)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 //-----------------------------------------------------------------------------
android_audioPlayer_create(CAudioPlayer * pAudioPlayer)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 //-----------------------------------------------------------------------------
android_audioPlayer_setConfig(CAudioPlayer * ap,const SLchar * configKey,const void * pConfigValue,SLuint32 valueSize)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 //-----------------------------------------------------------------------------
android_audioPlayer_getConfig(CAudioPlayer * ap,const SLchar * configKey,SLuint32 * pValueSize,void * pConfigValue)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
checkAndSetPerformanceModePre(CAudioPlayer * pAudioPlayer)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 denylist of interfaces that are incompatible with fast tracks.
1518     // The alternative, to check a allowlist 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 denylist method.
1522     // If a denylisted 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 denylist[] = {
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 denylist is remembering to add new interfaces here
1536     };
1537     for (unsigned i = 0; i < sizeof(denylist)/sizeof(denylist[0]); ++i) {
1538         if (IsInterfaceInitialized(&pAudioPlayer->mObject, denylist[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 denylistResult = (
1547             (allowedModes &
1548                 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
1549     bool allowlistResult = true;
1550     static const unsigned allowlist[] = {
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(allowlist)/sizeof(allowlist[0]); ++i) {
1565             if (mph == allowlist[i]) {
1566                 goto compatible;
1567             }
1568         }
1569         if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
1570             allowlistResult = false;
1571             break;
1572         }
1573 compatible: ;
1574     }
1575     if (allowlistResult != denylistResult) {
1576         SL_LOGW("allowlistResult != denylistResult");
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
checkAndSetPerformanceModePost(CAudioPlayer * pAudioPlayer)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
android_audioPlayer_realize(CAudioPlayer * pAudioPlayer,SLboolean async)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  */
android_audioPlayer_preDestroy(CAudioPlayer * pAudioPlayer)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 //-----------------------------------------------------------------------------
android_audioPlayer_destroy(CAudioPlayer * pAudioPlayer)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 //-----------------------------------------------------------------------------
android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer * ap,SLpermille rate,SLuint32 constraints)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
android_audioPlayer_metadata_getItemCount(CAudioPlayer * ap,SLuint32 * pItemCount)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
android_audioPlayer_metadata_getKeySize(CAudioPlayer * ap,SLuint32 index,SLuint32 * pKeySize)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
android_audioPlayer_metadata_getKey(CAudioPlayer * ap,SLuint32 index,SLuint32 size,SLMetadataInfo * pKey)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
android_audioPlayer_metadata_getValueSize(CAudioPlayer * ap,SLuint32 index,SLuint32 * pValueSize)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
android_audioPlayer_metadata_getValue(CAudioPlayer * ap,SLuint32 index,SLuint32 size,SLMetadataInfo * pValue)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
android_audioPlayer_setPlayState(CAudioPlayer * ap)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
android_audioPlayer_usePlayEventMask(CAudioPlayer * ap)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 //-----------------------------------------------------------------------------
android_audioPlayer_getDuration(IPlay * pPlayItf,SLmillisecond * pDurMsec)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 //-----------------------------------------------------------------------------
android_audioPlayer_getPosition(IPlay * pPlayItf,SLmillisecond * pPosMsec)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 //-----------------------------------------------------------------------------
android_audioPlayer_seek(CAudioPlayer * ap,SLmillisecond posMsec)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 //-----------------------------------------------------------------------------
android_audioPlayer_loop(CAudioPlayer * ap,SLboolean loopEnable)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 //-----------------------------------------------------------------------------
android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer * ap,SLpermille threshold)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 //-----------------------------------------------------------------------------
android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer * ap)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  */
android_audioPlayer_bufferQueue_onClear(CAudioPlayer * ap)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 //-----------------------------------------------------------------------------
android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer * ap)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 
android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer * ap)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