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