AudioPlayer_to_android.cpp revision c623c89c0a32c5fc77c998f1742d58e7be69e8c1
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
24#include <system/audio.h>
25
26template class android::KeyedVector<SLuint32, android::AudioEffect* > ;
27
28#define KEY_STREAM_TYPE_PARAMSIZE  sizeof(SLint32)
29
30#define AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE  500
31#define AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE 2000
32
33//-----------------------------------------------------------------------------
34// FIXME this method will be absorbed into android_audioPlayer_setPlayState() once
35//       bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object
36SLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState,
37        AndroidObjectState* pObjState) {
38    SLresult result = SL_RESULT_SUCCESS;
39    AndroidObjectState objState = *pObjState;
40
41    switch (playState) {
42     case SL_PLAYSTATE_STOPPED:
43         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
44         ap->stop();
45         break;
46     case SL_PLAYSTATE_PAUSED:
47         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
48         switch(objState) {
49         case ANDROID_UNINITIALIZED:
50             *pObjState = ANDROID_PREPARING;
51             ap->prepare();
52             break;
53         case ANDROID_PREPARING:
54             break;
55         case ANDROID_READY:
56             ap->pause();
57             break;
58         default:
59             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
60             result = SL_RESULT_INTERNAL_ERROR;
61             break;
62         }
63         break;
64     case SL_PLAYSTATE_PLAYING: {
65         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
66         switch(objState) {
67         case ANDROID_UNINITIALIZED:
68             *pObjState = ANDROID_PREPARING;
69             ap->prepare();
70             // intended fall through
71         case ANDROID_PREPARING:
72             // intended fall through
73         case ANDROID_READY:
74             ap->play();
75             break;
76         default:
77             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
78             result = SL_RESULT_INTERNAL_ERROR;
79             break;
80         }
81         }
82         break;
83     default:
84         // checked by caller, should not happen
85         SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
86         result = SL_RESULT_INTERNAL_ERROR;
87         break;
88     }
89
90    return result;
91}
92
93
94//-----------------------------------------------------------------------------
95// Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data
96// from a URI or FD, to write the decoded audio data to a buffer queue
97static size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, void* user) {
98    size_t sizeConsumed = 0;
99    if (NULL == user) {
100        return sizeConsumed;
101    }
102    SL_LOGD("received %d bytes from decoder", size);
103    CAudioPlayer *ap = (CAudioPlayer *)user;
104    slBufferQueueCallback callback = NULL;
105    void * callbackPContext = NULL;
106
107    // push decoded data to the buffer queue
108    object_lock_exclusive(&ap->mObject);
109
110    if (ap->mBufferQueue.mState.count != 0) {
111        assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
112
113        BufferHeader *oldFront = ap->mBufferQueue.mFront;
114        BufferHeader *newFront = &oldFront[1];
115
116        uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
117        if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) {
118            // room to consume the whole or rest of the decoded data in one shot
119            ap->mBufferQueue.mSizeConsumed += size;
120            // consume data but no callback to the BufferQueue interface here
121            memcpy (pDest, data, size);
122            sizeConsumed = size;
123        } else {
124            // push as much as possible of the decoded data into the buffer queue
125            sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
126
127            // the buffer at the head of the buffer queue is full, update the state
128            ap->mBufferQueue.mSizeConsumed = 0;
129            if (newFront ==  &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) {
130                newFront = ap->mBufferQueue.mArray;
131            }
132            ap->mBufferQueue.mFront = newFront;
133
134            ap->mBufferQueue.mState.count--;
135            ap->mBufferQueue.mState.playIndex++;
136            // consume data
137            memcpy (pDest, data, sizeConsumed);
138            // data has been copied to the buffer, and the buffer queue state has been updated
139            // we will notify the client if applicable
140            callback = ap->mBufferQueue.mCallback;
141            // save callback data
142            callbackPContext = ap->mBufferQueue.mContext;
143        }
144
145    } else {
146        // no available buffers in the queue to write the decoded data
147        sizeConsumed = 0;
148    }
149
150    object_unlock_exclusive(&ap->mObject);
151    // notify client
152    if (NULL != callback) {
153        (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
154    }
155
156    return sizeConsumed;
157}
158
159//-----------------------------------------------------------------------------
160int android_getMinFrameCount(uint32_t sampleRate) {
161    int afSampleRate;
162    if (android::AudioSystem::getOutputSamplingRate(&afSampleRate,
163            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
164        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
165    }
166    int afFrameCount;
167    if (android::AudioSystem::getOutputFrameCount(&afFrameCount,
168            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
169        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
170    }
171    uint32_t afLatency;
172    if (android::AudioSystem::getOutputLatency(&afLatency,
173            ANDROID_DEFAULT_OUTPUT_STREAM_TYPE) != android::NO_ERROR) {
174        return ANDROID_DEFAULT_AUDIOTRACK_BUFFER_SIZE;
175    }
176    // minimum nb of buffers to cover output latency, given the size of each hardware audio buffer
177    uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
178    if (minBufCount < 2) minBufCount = 2;
179    // minimum number of frames to cover output latency at the sample rate of the content
180    return (afFrameCount*sampleRate*minBufCount)/afSampleRate;
181}
182
183
184//-----------------------------------------------------------------------------
185#define LEFT_CHANNEL_MASK  0x1 << 0
186#define RIGHT_CHANNEL_MASK 0x1 << 1
187
188void android_audioPlayer_volumeUpdate(CAudioPlayer* ap)
189{
190    assert(ap != NULL);
191
192    // the source's channel count, where zero means unknown
193    SLuint8 channelCount = ap->mNumChannels;
194
195    // whether each channel is audible
196    bool leftAudibilityFactor, rightAudibilityFactor;
197
198    // mute has priority over solo
199    if (channelCount >= STEREO_CHANNELS) {
200        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
201            // left muted
202            leftAudibilityFactor = false;
203        } else {
204            // left not muted
205            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
206                // left soloed
207                leftAudibilityFactor = true;
208            } else {
209                // left not soloed
210                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
211                    // right solo silences left
212                    leftAudibilityFactor = false;
213                } else {
214                    // left and right are not soloed, and left is not muted
215                    leftAudibilityFactor = true;
216                }
217            }
218        }
219
220        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
221            // right muted
222            rightAudibilityFactor = false;
223        } else {
224            // right not muted
225            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
226                // right soloed
227                rightAudibilityFactor = true;
228            } else {
229                // right not soloed
230                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
231                    // left solo silences right
232                    rightAudibilityFactor = false;
233                } else {
234                    // left and right are not soloed, and right is not muted
235                    rightAudibilityFactor = true;
236                }
237            }
238        }
239
240    // channel mute and solo are ignored for mono and unknown channel count sources
241    } else {
242        leftAudibilityFactor = true;
243        rightAudibilityFactor = true;
244    }
245
246    // compute volumes without setting
247    const bool audibilityFactors[2] = {leftAudibilityFactor, rightAudibilityFactor};
248    float volumes[2];
249    android_player_volumeUpdate(volumes, &ap->mVolume, channelCount, ap->mAmplFromDirectLevel,
250            audibilityFactors);
251    float leftVol = volumes[0], rightVol = volumes[1];
252
253    // set volume on the underlying media player or audio track
254    if (ap->mAPlayer != 0) {
255        ap->mAPlayer->setVolume(leftVol, rightVol);
256    } else if (ap->mAudioTrack != 0) {
257        ap->mAudioTrack->setVolume(leftVol, rightVol);
258    }
259
260    // changes in the AudioPlayer volume must be reflected in the send level:
261    //  in SLEffectSendItf or in SLAndroidEffectSendItf?
262    // FIXME replace interface test by an internal API once we have one.
263    if (NULL != ap->mEffectSend.mItf) {
264        for (unsigned int i=0 ; i<AUX_MAX ; i++) {
265            if (ap->mEffectSend.mEnableLevels[i].mEnable) {
266                android_fxSend_setSendLevel(ap,
267                        ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
268                // there's a single aux bus on Android, so we can stop looking once the first
269                // aux effect is found.
270                break;
271            }
272        }
273    } else if (NULL != ap->mAndroidEffectSend.mItf) {
274        android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
275    }
276}
277
278// Called by android_audioPlayer_volumeUpdate and android_mediaPlayer_volumeUpdate to compute
279// volumes, but setting volumes is handled by the caller.
280
281void android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf, unsigned
282channelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/)
283{
284    assert(pVolumes != NULL);
285    assert(volumeItf != NULL);
286    // OK for audibilityFactors to be NULL
287
288    bool leftAudibilityFactor, rightAudibilityFactor;
289
290    // apply player mute factor
291    // note that AudioTrack has mute() but not MediaPlayer, so it's easier to use volume
292    // to mute for both rather than calling mute() for AudioTrack
293
294    // player is muted
295    if (volumeItf->mMute) {
296        leftAudibilityFactor = false;
297        rightAudibilityFactor = false;
298    // player isn't muted, and channel mute/solo audibility factors are available (AudioPlayer)
299    } else if (audibilityFactors != NULL) {
300        leftAudibilityFactor = audibilityFactors[0];
301        rightAudibilityFactor = audibilityFactors[1];
302    // player isn't muted, and channel mute/solo audibility factors aren't available (MediaPlayer)
303    } else {
304        leftAudibilityFactor = true;
305        rightAudibilityFactor = true;
306    }
307
308    // compute amplification as the combination of volume level and stereo position
309    //   amplification (or attenuation) from volume level
310    float amplFromVolLevel = sles_to_android_amplification(volumeItf->mLevel);
311    //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
312    float leftVol  = amplFromVolLevel * amplFromDirectLevel;
313    float rightVol = leftVol;
314
315    // amplification from stereo position
316    if (volumeItf->mEnableStereoPosition) {
317        // Left/right amplification (can be attenuations) factors derived for the StereoPosition
318        float amplFromStereoPos[STEREO_CHANNELS];
319        // panning law depends on content channel count: mono to stereo panning vs stereo balance
320        if (1 == channelCount) {
321            // mono to stereo panning
322            double theta = (1000+volumeItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
323            amplFromStereoPos[0] = cos(theta);
324            amplFromStereoPos[1] = sin(theta);
325        // channel count is 0 (unknown), 2 (stereo), or > 2 (multi-channel)
326        } else {
327            // stereo balance
328            if (volumeItf->mStereoPosition > 0) {
329                amplFromStereoPos[0] = (1000-volumeItf->mStereoPosition)/1000.0f;
330                amplFromStereoPos[1] = 1.0f;
331            } else {
332                amplFromStereoPos[0] = 1.0f;
333                amplFromStereoPos[1] = (1000+volumeItf->mStereoPosition)/1000.0f;
334            }
335        }
336        leftVol  *= amplFromStereoPos[0];
337        rightVol *= amplFromStereoPos[1];
338    }
339
340    // apply audibility factors
341    if (!leftAudibilityFactor) {
342        leftVol = 0.0;
343    }
344    if (!rightAudibilityFactor) {
345        rightVol = 0.0;
346    }
347
348    // return the computed volumes
349    pVolumes[0] = leftVol;
350    pVolumes[1] = rightVol;
351}
352
353//-----------------------------------------------------------------------------
354void audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
355    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
356    slPlayCallback callback = NULL;
357    void* callbackPContext = NULL;
358
359    interface_lock_shared(&ap->mPlay);
360    callback = ap->mPlay.mCallback;
361    callbackPContext = ap->mPlay.mContext;
362    interface_unlock_shared(&ap->mPlay);
363
364    if (NULL != callback) {
365        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
366        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
367    }
368}
369
370//-----------------------------------------------------------------------------
371void audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
372    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
373    slPlayCallback callback = NULL;
374    void* callbackPContext = NULL;
375
376    interface_lock_shared(&ap->mPlay);
377    callback = ap->mPlay.mCallback;
378    callbackPContext = ap->mPlay.mContext;
379    interface_unlock_shared(&ap->mPlay);
380
381    if (NULL != callback) {
382        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
383        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
384    }
385}
386
387
388//-----------------------------------------------------------------------------
389void audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
390    slPlayCallback callback = NULL;
391    void* callbackPContext = NULL;
392
393    interface_lock_shared(&ap->mPlay);
394    callback = ap->mPlay.mCallback;
395    callbackPContext = ap->mPlay.mContext;
396    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
397    interface_unlock_shared(&ap->mPlay);
398
399    if ((NULL != callback) && headStalled) {
400        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
401    }
402}
403
404
405//-----------------------------------------------------------------------------
406/**
407 * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
408 *
409 * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
410 *       needs to be changed when the player reaches the end of the content to play. This is
411 *       relative to what the specification describes for buffer queues vs the
412 *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
413 *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
414 *          buffers in the queue, the playing of audio data stops. The player remains in the
415 *          SL_PLAYSTATE_PLAYING state."
416 *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
417 *          of the current content and the player has paused."
418 */
419void audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
420        bool needToLock) {
421    //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
422    //        needToLock);
423    slPlayCallback playCallback = NULL;
424    void * playContext = NULL;
425    // SLPlayItf callback or no callback?
426    if (needToLock) {
427        interface_lock_exclusive(&ap->mPlay);
428    }
429    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
430        playCallback = ap->mPlay.mCallback;
431        playContext = ap->mPlay.mContext;
432    }
433    if (setPlayStateToPaused) {
434        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
435    }
436    if (needToLock) {
437        interface_unlock_exclusive(&ap->mPlay);
438    }
439    // enqueue callback with no lock held
440    if (NULL != playCallback) {
441        SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
442                SL_PLAYEVENT_HEADATEND);
443        if (SL_RESULT_SUCCESS != result) {
444            LOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback,
445                    &ap->mPlay.mItf, playContext);
446        }
447    }
448
449}
450
451
452//-----------------------------------------------------------------------------
453/**
454 * pre-condition: AudioPlayer has SLPrefetchStatusItf initialized
455 * post-condition:
456 *  - ap->mPrefetchStatus.mStatus == status
457 *  - the prefetch status callback, if any, has been notified if a change occurred
458 *
459 */
460void audioPlayer_dispatch_prefetchStatus_lockPrefetch(CAudioPlayer *ap, SLuint32 status,
461        bool needToLock) {
462    slPrefetchCallback prefetchCallback = NULL;
463    void * prefetchContext = NULL;
464
465    if (needToLock) {
466        interface_lock_exclusive(&ap->mPrefetchStatus);
467    }
468    // status change?
469    if (ap->mPrefetchStatus.mStatus != status) {
470        ap->mPrefetchStatus.mStatus = status;
471        // callback or no callback?
472        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
473            prefetchCallback = ap->mPrefetchStatus.mCallback;
474            prefetchContext  = ap->mPrefetchStatus.mContext;
475        }
476    }
477    if (needToLock) {
478        interface_unlock_exclusive(&ap->mPrefetchStatus);
479    }
480
481    // callback with no lock held
482    if (NULL != prefetchCallback) {
483        (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, status);
484    }
485}
486
487
488//-----------------------------------------------------------------------------
489SLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
490    SLresult result = SL_RESULT_SUCCESS;
491    SL_LOGV("type %d", type);
492
493    int newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
494    switch(type) {
495    case SL_ANDROID_STREAM_VOICE:
496        newStreamType = AUDIO_STREAM_VOICE_CALL;
497        break;
498    case SL_ANDROID_STREAM_SYSTEM:
499        newStreamType = AUDIO_STREAM_SYSTEM;
500        break;
501    case SL_ANDROID_STREAM_RING:
502        newStreamType = AUDIO_STREAM_RING;
503        break;
504    case SL_ANDROID_STREAM_MEDIA:
505        newStreamType = AUDIO_STREAM_MUSIC;
506        break;
507    case SL_ANDROID_STREAM_ALARM:
508        newStreamType = AUDIO_STREAM_ALARM;
509        break;
510    case SL_ANDROID_STREAM_NOTIFICATION:
511        newStreamType = AUDIO_STREAM_NOTIFICATION;
512        break;
513    default:
514        SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
515        result = SL_RESULT_PARAMETER_INVALID;
516        break;
517    }
518
519    // stream type needs to be set before the object is realized
520    // (ap->mAudioTrack is supposed to be NULL until then)
521    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
522        SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
523        result = SL_RESULT_PRECONDITIONS_VIOLATED;
524    } else {
525        ap->mStreamType = newStreamType;
526    }
527
528    return result;
529}
530
531
532//-----------------------------------------------------------------------------
533SLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
534    SLresult result = SL_RESULT_SUCCESS;
535
536    switch(ap->mStreamType) {
537    case AUDIO_STREAM_VOICE_CALL:
538        *pType = SL_ANDROID_STREAM_VOICE;
539        break;
540    case AUDIO_STREAM_SYSTEM:
541        *pType = SL_ANDROID_STREAM_SYSTEM;
542        break;
543    case AUDIO_STREAM_RING:
544        *pType = SL_ANDROID_STREAM_RING;
545        break;
546    case AUDIO_STREAM_DEFAULT:
547    case AUDIO_STREAM_MUSIC:
548        *pType = SL_ANDROID_STREAM_MEDIA;
549        break;
550    case AUDIO_STREAM_ALARM:
551        *pType = SL_ANDROID_STREAM_ALARM;
552        break;
553    case AUDIO_STREAM_NOTIFICATION:
554        *pType = SL_ANDROID_STREAM_NOTIFICATION;
555        break;
556    default:
557        result = SL_RESULT_INTERNAL_ERROR;
558        *pType = SL_ANDROID_STREAM_MEDIA;
559        break;
560    }
561
562    return result;
563}
564
565
566//-----------------------------------------------------------------------------
567void audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
568    if ((ap->mAudioTrack != 0) && (ap->mAuxEffect != 0)) {
569        android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
570    }
571}
572
573
574//-----------------------------------------------------------------------------
575void audioPlayer_setInvalid(CAudioPlayer* ap) {
576    ap->mAndroidObjType = INVALID_TYPE;
577    ap->mpLock = NULL;
578}
579
580
581//-----------------------------------------------------------------------------
582/*
583 * returns true if the given data sink is supported by AudioPlayer that doesn't
584 *   play to an OutputMix object, false otherwise
585 *
586 * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
587 */
588bool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
589    bool result = true;
590    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
591    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
592
593    switch (sinkLocatorType) {
594
595    case SL_DATALOCATOR_BUFFERQUEUE:
596    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
597        if (SL_DATAFORMAT_PCM != sinkFormatType) {
598            SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM",
599                    (unsigned)sinkFormatType);
600            result = false;
601        }
602        // it's no use checking the PCM format fields because additional characteristics
603        // such as the number of channels, or sample size are unknown to the player at this stage
604        break;
605
606    default:
607        SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
608        result = false;
609        break;
610    }
611
612    return result;
613}
614
615
616//-----------------------------------------------------------------------------
617/*
618 * returns the Android object type if the locator type combinations for the source and sinks
619 *   are supported by this implementation, INVALID_TYPE otherwise
620 */
621AndroidObjectType audioPlayer_getAndroidObjectTypeForSourceSink(CAudioPlayer *ap) {
622
623    const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource;
624    const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink;
625    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
626    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
627    AndroidObjectType type = INVALID_TYPE;
628
629    //--------------------------------------
630    // Sink / source matching check:
631    // the following source / sink combinations are supported
632    //     SL_DATALOCATOR_BUFFERQUEUE                / SL_DATALOCATOR_OUTPUTMIX
633    //     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE   / SL_DATALOCATOR_OUTPUTMIX
634    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_OUTPUTMIX
635    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_OUTPUTMIX
636    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_OUTPUTMIX
637    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_BUFFERQUEUE
638    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_BUFFERQUEUE
639    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_BUFFERQUEUE
640    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
641    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
642    switch (sinkLocatorType) {
643
644    case SL_DATALOCATOR_OUTPUTMIX: {
645        switch (sourceLocatorType) {
646
647        //   Buffer Queue to AudioTrack
648        case SL_DATALOCATOR_BUFFERQUEUE:
649        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
650            type = AUDIOPLAYER_FROM_PCM_BUFFERQUEUE;
651            break;
652
653        //   URI or FD to MediaPlayer
654        case SL_DATALOCATOR_URI:
655        case SL_DATALOCATOR_ANDROIDFD:
656            type = AUDIOPLAYER_FROM_URIFD;
657            break;
658
659        //   Android BufferQueue to MediaPlayer (shared memory streaming)
660        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
661            type = AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE;
662            break;
663
664        default:
665            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
666                    (unsigned)sourceLocatorType);
667            break;
668        }
669        }
670        break;
671
672    case SL_DATALOCATOR_BUFFERQUEUE:
673    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
674        switch (sourceLocatorType) {
675
676        //   URI or FD decoded to PCM in a buffer queue
677        case SL_DATALOCATOR_URI:
678        case SL_DATALOCATOR_ANDROIDFD:
679            type = AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE;
680            break;
681
682        //   AAC ADTS Android buffer queue decoded to PCM in a buffer queue
683        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
684            type = AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE;
685            break;
686
687        default:
688            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
689                    (unsigned)sourceLocatorType);
690            break;
691        }
692        break;
693
694    default:
695        SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
696        break;
697    }
698
699    return type;
700}
701
702
703//-----------------------------------------------------------------------------
704/*
705 * Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
706 * from a URI or FD, for prepare, prefetch, and play events
707 */
708static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
709
710    // FIXME see similar code and comment in player_handleMediaPlayerEventNotifications
711
712    if (NULL == user) {
713        return;
714    }
715
716    CAudioPlayer *ap = (CAudioPlayer *)user;
717    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
718        // it is not safe to enter the callback (the track is about to go away)
719        return;
720    }
721    union {
722        char c[sizeof(int)];
723        int i;
724    } u;
725    u.i = event;
726    SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
727            "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
728    switch(event) {
729
730    case android::GenericPlayer::kEventPrepared: {
731
732        if (PLAYER_SUCCESS != data1) {
733            object_lock_exclusive(&ap->mObject);
734
735            // already initialized at object creation, and can only prepare once so never reset
736            assert(ap->mAudioTrack == 0);
737            assert(ap->mNumChannels == UNKNOWN_NUMCHANNELS);
738            assert(ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE);
739            assert(ap->mAndroidObjState == ANDROID_PREPARING);
740            ap->mAndroidObjState = ANDROID_READY;
741
742            object_unlock_exclusive(&ap->mObject);
743
744            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
745            //  indicate a prefetch error, so we signal it by sending simulataneously two events:
746            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
747            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
748            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
749            if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
750                break;
751            }
752
753            slPrefetchCallback callback = NULL;
754            void* callbackPContext = NULL;
755
756            interface_lock_exclusive(&ap->mPrefetchStatus);
757            ap->mPrefetchStatus.mLevel = 0;
758            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
759            if ((ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE)
760                    && (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE)) {
761                callback = ap->mPrefetchStatus.mCallback;
762                callbackPContext = ap->mPrefetchStatus.mContext;
763            }
764            interface_unlock_exclusive(&ap->mPrefetchStatus);
765
766            // callback with no lock held
767            if (NULL != callback) {
768                (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
769                        SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
770            }
771
772
773        } else {
774
775            object_lock_exclusive(&ap->mObject);
776
777            if (AUDIOPLAYER_FROM_URIFD == ap->mAndroidObjType) {
778                //**************************************
779                // FIXME move under GenericMediaPlayer
780#if 0
781                ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
782                ap->mNumChannels = ap->mSfPlayer->getNumChannels();
783                ap->mSampleRateMilliHz =
784                        android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
785                ap->mSfPlayer->startPrefetch_async();
786                // update the new track with the current settings
787                audioPlayer_auxEffectUpdate(ap);
788                android_audioPlayer_useEventMask(ap);
789                android_audioPlayer_volumeUpdate(ap);
790                android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/);
791#endif
792            } else if (AUDIOPLAYER_FROM_PCM_BUFFERQUEUE == ap->mAndroidObjType) {
793                if (ap->mAPlayer != 0) {
794                    ((android::AudioToCbRenderer*)ap->mAPlayer.get())->startPrefetch_async();
795                }
796            } else if (AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE == ap->mAndroidObjType) {
797                SL_LOGD("Received SfPlayer::kEventPrepared from AVPlayer for CAudioPlayer %p", ap);
798            }
799
800            ap->mAndroidObjState = ANDROID_READY;
801
802            object_unlock_exclusive(&ap->mObject);
803        }
804
805    }
806    break;
807
808    case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
809        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
810            break;
811        }
812        slPrefetchCallback callback = NULL;
813        void* callbackPContext = NULL;
814
815        // SLPrefetchStatusItf callback or no callback?
816        interface_lock_exclusive(&ap->mPrefetchStatus);
817        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
818            callback = ap->mPrefetchStatus.mCallback;
819            callbackPContext = ap->mPrefetchStatus.mContext;
820        }
821        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
822        interface_unlock_exclusive(&ap->mPrefetchStatus);
823
824        // callback with no lock held
825        if (NULL != callback) {
826            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
827                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
828        }
829    }
830    break;
831
832    case android::GenericPlayer::kEventPrefetchStatusChange: {
833        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
834            break;
835        }
836        slPrefetchCallback callback = NULL;
837        void* callbackPContext = NULL;
838
839        // SLPrefetchStatusItf callback or no callback?
840        object_lock_exclusive(&ap->mObject);
841        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
842            callback = ap->mPrefetchStatus.mCallback;
843            callbackPContext = ap->mPrefetchStatus.mContext;
844        }
845        if (data1 >= android::kStatusIntermediate) {
846            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
847            ap->mAndroidObjState = ANDROID_READY;
848        } else if (data1 < android::kStatusIntermediate) {
849            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
850        }
851        object_unlock_exclusive(&ap->mObject);
852
853        // callback with no lock held
854        if (NULL != callback) {
855            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
856        }
857        }
858        break;
859
860    case android::GenericPlayer::kEventEndOfStream: {
861        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
862        if ((ap->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
863            ap->mAudioTrack->stop();
864        }
865        }
866        break;
867
868    case android::GenericPlayer::kEventChannelCount: {
869        object_lock_exclusive(&ap->mObject);
870        if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
871            ap->mNumChannels = data1;
872            android_audioPlayer_volumeUpdate(ap);
873        }
874        object_unlock_exclusive(&ap->mObject);
875        }
876        break;
877
878    case android::GenericPlayer::kEventPlay: {
879        slPlayCallback callback = NULL;
880        void* callbackPContext = NULL;
881
882        interface_lock_shared(&ap->mPlay);
883        callback = ap->mPlay.mCallback;
884        callbackPContext = ap->mPlay.mContext;
885        interface_unlock_shared(&ap->mPlay);
886
887        if (NULL != callback) {
888            SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
889#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
890            // synchronous callback requires a synchronous GetPosition implementation
891            (*callback)(&ap->mPlay.mItf, callbackPContext, event);
892#else
893            // asynchronous callback works with any GetPosition implementation
894            SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
895                    callbackPContext, event);
896            if (SL_RESULT_SUCCESS != result) {
897                LOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
898                        &ap->mPlay.mItf, callbackPContext, event);
899            }
900#endif
901        }
902        }
903        break;
904
905    default:
906        break;
907    }
908
909    ap->mCallbackProtector->exitCb();
910}
911
912
913//-----------------------------------------------------------------------------
914SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
915{
916    // verify that the locator types for the source / sink combination is supported
917    pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
918    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
919        return SL_RESULT_PARAMETER_INVALID;
920    }
921
922    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
923    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
924
925    // format check:
926    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
927    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
928    const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
929    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat;
930
931    switch (sourceLocatorType) {
932    //------------------
933    //   Buffer Queues
934    case SL_DATALOCATOR_BUFFERQUEUE:
935    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
936        {
937        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
938
939        // Buffer format
940        switch (sourceFormatType) {
941        //     currently only PCM buffer queues are supported,
942        case SL_DATAFORMAT_PCM: {
943            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
944            switch (df_pcm->numChannels) {
945            case 1:
946            case 2:
947                break;
948            default:
949                // this should have already been rejected by checkDataFormat
950                SL_LOGE("Cannot create audio player: unsupported " \
951                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
952                return SL_RESULT_CONTENT_UNSUPPORTED;
953            }
954            switch (df_pcm->samplesPerSec) {
955            case SL_SAMPLINGRATE_8:
956            case SL_SAMPLINGRATE_11_025:
957            case SL_SAMPLINGRATE_12:
958            case SL_SAMPLINGRATE_16:
959            case SL_SAMPLINGRATE_22_05:
960            case SL_SAMPLINGRATE_24:
961            case SL_SAMPLINGRATE_32:
962            case SL_SAMPLINGRATE_44_1:
963            case SL_SAMPLINGRATE_48:
964                break;
965            case SL_SAMPLINGRATE_64:
966            case SL_SAMPLINGRATE_88_2:
967            case SL_SAMPLINGRATE_96:
968            case SL_SAMPLINGRATE_192:
969            default:
970                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
971                    (unsigned) df_pcm->samplesPerSec);
972                return SL_RESULT_CONTENT_UNSUPPORTED;
973            }
974            switch (df_pcm->bitsPerSample) {
975            case SL_PCMSAMPLEFORMAT_FIXED_8:
976            case SL_PCMSAMPLEFORMAT_FIXED_16:
977                break;
978                // others
979            default:
980                // this should have already been rejected by checkDataFormat
981                SL_LOGE("Cannot create audio player: unsupported sample bit depth %u",
982                        (SLuint32)df_pcm->bitsPerSample);
983                return SL_RESULT_CONTENT_UNSUPPORTED;
984            }
985            switch (df_pcm->containerSize) {
986            case 8:
987            case 16:
988                break;
989                // others
990            default:
991                SL_LOGE("Cannot create audio player: unsupported container size %u",
992                    (unsigned) df_pcm->containerSize);
993                return SL_RESULT_CONTENT_UNSUPPORTED;
994            }
995            // df_pcm->channelMask: the earlier platform-independent check and the
996            //     upcoming check by sles_to_android_channelMaskOut are sufficient
997            switch (df_pcm->endianness) {
998            case SL_BYTEORDER_LITTLEENDIAN:
999                break;
1000            case SL_BYTEORDER_BIGENDIAN:
1001                SL_LOGE("Cannot create audio player: unsupported big-endian byte order");
1002                return SL_RESULT_CONTENT_UNSUPPORTED;
1003                // native is proposed but not yet in spec
1004            default:
1005                SL_LOGE("Cannot create audio player: unsupported byte order %u",
1006                    (unsigned) df_pcm->endianness);
1007                return SL_RESULT_CONTENT_UNSUPPORTED;
1008            }
1009            } //case SL_DATAFORMAT_PCM
1010            break;
1011        case SL_DATAFORMAT_MIME:
1012        case XA_DATAFORMAT_RAWIMAGE:
1013            SL_LOGE("Cannot create audio player with buffer queue data source "
1014                "without SL_DATAFORMAT_PCM format");
1015            return SL_RESULT_CONTENT_UNSUPPORTED;
1016        default:
1017            // invalid data format is detected earlier
1018            assert(false);
1019            return SL_RESULT_INTERNAL_ERROR;
1020        } // switch (sourceFormatType)
1021        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
1022        break;
1023    //------------------
1024    //   URI
1025    case SL_DATALOCATOR_URI:
1026        {
1027        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
1028        if (NULL == dl_uri->URI) {
1029            return SL_RESULT_PARAMETER_INVALID;
1030        }
1031        // URI format
1032        switch (sourceFormatType) {
1033        case SL_DATAFORMAT_MIME:
1034            break;
1035        case SL_DATAFORMAT_PCM:
1036        case XA_DATAFORMAT_RAWIMAGE:
1037            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
1038                "SL_DATAFORMAT_MIME format");
1039            return SL_RESULT_CONTENT_UNSUPPORTED;
1040        } // switch (sourceFormatType)
1041        // decoding format check
1042        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
1043                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
1044            return SL_RESULT_CONTENT_UNSUPPORTED;
1045        }
1046        } // case SL_DATALOCATOR_URI
1047        break;
1048    //------------------
1049    //   File Descriptor
1050    case SL_DATALOCATOR_ANDROIDFD:
1051        {
1052        // fd is already non null
1053        switch (sourceFormatType) {
1054        case SL_DATAFORMAT_MIME:
1055            break;
1056        case SL_DATAFORMAT_PCM:
1057            // FIXME implement
1058            SL_LOGD("[ FIXME implement PCM FD data sources ]");
1059            break;
1060        case XA_DATAFORMAT_RAWIMAGE:
1061            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
1062                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
1063            return SL_RESULT_CONTENT_UNSUPPORTED;
1064        default:
1065            // invalid data format is detected earlier
1066            assert(false);
1067            return SL_RESULT_INTERNAL_ERROR;
1068        } // switch (sourceFormatType)
1069        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
1070                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
1071            return SL_RESULT_CONTENT_UNSUPPORTED;
1072        }
1073        } // case SL_DATALOCATOR_ANDROIDFD
1074        break;
1075    //------------------
1076    //   Stream
1077    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
1078    {
1079        switch (sourceFormatType) {
1080        case SL_DATAFORMAT_MIME:
1081        {
1082            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
1083            if (NULL == df_mime) {
1084                SL_LOGE("MIME type null invalid");
1085                return SL_RESULT_CONTENT_UNSUPPORTED;
1086            }
1087            SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
1088            switch(df_mime->containerType) {
1089            case SL_CONTAINERTYPE_MPEG_TS:
1090                if (strcasecmp((char*)df_mime->mimeType, ANDROID_MIME_MP2TS)) {
1091                    SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
1092                            (char*)df_mime->mimeType, ANDROID_MIME_MP2TS);
1093                    return SL_RESULT_CONTENT_UNSUPPORTED;
1094                }
1095                break;
1096            case SL_CONTAINERTYPE_RAW:
1097            case SL_CONTAINERTYPE_AAC:
1098                if (strcasecmp((char*)df_mime->mimeType, ANDROID_MIME_AACADTS) &&
1099                        strcasecmp((char*)df_mime->mimeType,
1100                                ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
1101                    SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
1102                            (char*)df_mime->mimeType, df_mime->containerType,
1103                            ANDROID_MIME_AACADTS);
1104                    return SL_RESULT_CONTENT_UNSUPPORTED;
1105                }
1106                break;
1107            default:
1108                SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1109                                        "that is not fed MPEG-2 TS data or AAC ADTS data");
1110                return SL_RESULT_CONTENT_UNSUPPORTED;
1111            }
1112        }
1113        break;
1114        default:
1115            SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1116                    "without SL_DATAFORMAT_MIME format");
1117            return SL_RESULT_CONTENT_UNSUPPORTED;
1118        }
1119    }
1120    break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
1121    //------------------
1122    //   Address
1123    case SL_DATALOCATOR_ADDRESS:
1124    case SL_DATALOCATOR_IODEVICE:
1125    case SL_DATALOCATOR_OUTPUTMIX:
1126    case XA_DATALOCATOR_NATIVEDISPLAY:
1127    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
1128        SL_LOGE("Cannot create audio player with data locator type 0x%x",
1129                (unsigned) sourceLocatorType);
1130        return SL_RESULT_CONTENT_UNSUPPORTED;
1131    default:
1132        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
1133                (unsigned) sourceLocatorType);
1134        return SL_RESULT_PARAMETER_INVALID;
1135    }// switch (locatorType)
1136
1137    return SL_RESULT_SUCCESS;
1138}
1139
1140
1141
1142//-----------------------------------------------------------------------------
1143static void audioTrack_callBack_uri(int event, void* user, void *info) {
1144    // EVENT_MORE_DATA needs to be handled with priority over the other events
1145    // because it will be called the most often during playback
1146
1147    if (event == android::AudioTrack::EVENT_MORE_DATA) {
1148        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
1149        // set size to 0 to signal we're not using the callback to write more data
1150        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1151        pBuff->size = 0;
1152    } else if (NULL != user) {
1153        CAudioPlayer *ap = (CAudioPlayer *)user;
1154        if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
1155            // it is not safe to enter the callback (the track is about to go away)
1156            return;
1157        }
1158        switch (event) {
1159            case android::AudioTrack::EVENT_MARKER :
1160                audioTrack_handleMarker_lockPlay(ap);
1161                break;
1162            case android::AudioTrack::EVENT_NEW_POS :
1163                audioTrack_handleNewPos_lockPlay(ap);
1164                break;
1165            case android::AudioTrack::EVENT_UNDERRUN :
1166                audioTrack_handleUnderrun_lockPlay(ap);
1167                break;
1168            case android::AudioTrack::EVENT_BUFFER_END :
1169            case android::AudioTrack::EVENT_LOOP_END :
1170                break;
1171            default:
1172                SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1173                        ap);
1174                break;
1175        }
1176        ap->mCallbackProtector->exitCb();
1177    }
1178}
1179
1180//-----------------------------------------------------------------------------
1181// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
1182// from a buffer queue. This will not be called once the AudioTrack has been destroyed.
1183static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
1184    CAudioPlayer *ap = (CAudioPlayer *)user;
1185
1186    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
1187        // it is not safe to enter the callback (the track is about to go away)
1188        return;
1189    }
1190
1191    void * callbackPContext = NULL;
1192    switch(event) {
1193
1194    case android::AudioTrack::EVENT_MORE_DATA: {
1195        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
1196        slBufferQueueCallback callback = NULL;
1197        slPrefetchCallback prefetchCallback = NULL;
1198        void *prefetchContext = NULL;
1199        SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
1200        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1201
1202        // retrieve data from the buffer queue
1203        interface_lock_exclusive(&ap->mBufferQueue);
1204
1205        if (ap->mBufferQueue.mState.count != 0) {
1206            //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
1207            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
1208
1209            BufferHeader *oldFront = ap->mBufferQueue.mFront;
1210            BufferHeader *newFront = &oldFront[1];
1211
1212            // declared as void * because this code supports both 8-bit and 16-bit PCM data
1213            void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
1214            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
1215                // can't consume the whole or rest of the buffer in one shot
1216                ap->mBufferQueue.mSizeConsumed += pBuff->size;
1217                // leave pBuff->size untouched
1218                // consume data
1219                // FIXME can we avoid holding the lock during the copy?
1220                memcpy (pBuff->raw, pSrc, pBuff->size);
1221            } else {
1222                // finish consuming the buffer or consume the buffer in one shot
1223                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
1224                ap->mBufferQueue.mSizeConsumed = 0;
1225
1226                if (newFront ==
1227                        &ap->mBufferQueue.mArray
1228                            [ap->mBufferQueue.mNumBuffers + 1])
1229                {
1230                    newFront = ap->mBufferQueue.mArray;
1231                }
1232                ap->mBufferQueue.mFront = newFront;
1233
1234                ap->mBufferQueue.mState.count--;
1235                ap->mBufferQueue.mState.playIndex++;
1236
1237                // consume data
1238                // FIXME can we avoid holding the lock during the copy?
1239                memcpy (pBuff->raw, pSrc, pBuff->size);
1240
1241                // data has been consumed, and the buffer queue state has been updated
1242                // we will notify the client if applicable
1243                callback = ap->mBufferQueue.mCallback;
1244                // save callback data
1245                callbackPContext = ap->mBufferQueue.mContext;
1246            }
1247        } else { // empty queue
1248            // signal no data available
1249            pBuff->size = 0;
1250
1251            // signal we're at the end of the content, but don't pause (see note in function)
1252            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1253
1254            // signal underflow to prefetch status itf
1255            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1256                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
1257                ap->mPrefetchStatus.mLevel = 0;
1258                // callback or no callback?
1259                prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
1260                        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
1261                if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
1262                    prefetchCallback = ap->mPrefetchStatus.mCallback;
1263                    prefetchContext  = ap->mPrefetchStatus.mContext;
1264                }
1265            }
1266
1267            // stop the track so it restarts playing faster when new data is enqueued
1268            ap->mAudioTrack->stop();
1269        }
1270        interface_unlock_exclusive(&ap->mBufferQueue);
1271
1272        // notify client
1273        if (NULL != prefetchCallback) {
1274            assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
1275            // spec requires separate callbacks for each event
1276            if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
1277                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1278                        SL_PREFETCHEVENT_STATUSCHANGE);
1279            }
1280            if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
1281                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1282                        SL_PREFETCHEVENT_FILLLEVELCHANGE);
1283            }
1284        }
1285        if (NULL != callback) {
1286            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
1287        }
1288    }
1289    break;
1290
1291    case android::AudioTrack::EVENT_MARKER:
1292        //SL_LOGI("received event EVENT_MARKER from AudioTrack");
1293        audioTrack_handleMarker_lockPlay(ap);
1294        break;
1295
1296    case android::AudioTrack::EVENT_NEW_POS:
1297        //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
1298        audioTrack_handleNewPos_lockPlay(ap);
1299        break;
1300
1301    case android::AudioTrack::EVENT_UNDERRUN:
1302        //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
1303        audioTrack_handleUnderrun_lockPlay(ap);
1304        break;
1305
1306    default:
1307        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
1308        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1309                (CAudioPlayer *)user);
1310        break;
1311    }
1312
1313    ap->mCallbackProtector->exitCb();
1314}
1315
1316
1317//-----------------------------------------------------------------------------
1318SLresult android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1319
1320    SLresult result = SL_RESULT_SUCCESS;
1321    // pAudioPlayer->mAndroidObjType has been set in audioPlayer_getAndroidObjectTypeForSourceSink()
1322    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
1323        audioPlayer_setInvalid(pAudioPlayer);
1324        result = SL_RESULT_PARAMETER_INVALID;
1325    } else {
1326
1327        // These initializations are in the same order as the field declarations in classes.h
1328
1329        // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
1330        pAudioPlayer->mpLock = new android::Mutex();
1331        // mAndroidObjType: see above comment
1332        pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1333        pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
1334        pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
1335
1336        // mAudioTrack
1337        pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
1338        // mAPLayer
1339        // mAuxEffect
1340
1341        pAudioPlayer->mAuxSendLevel = 0;
1342        pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
1343        pAudioPlayer->mDeferredStart = false;
1344
1345        // Already initialized in IEngine_CreateAudioPlayer, to be consolidated
1346        pAudioPlayer->mDirectLevel = 0; // no attenuation
1347
1348        // This section re-initializes interface-specific fields that
1349        // can be set or used regardless of whether the interface is
1350        // exposed on the AudioPlayer or not
1351
1352        // Only AudioTrack supports a non-trivial playback rate
1353        switch (pAudioPlayer->mAndroidObjType) {
1354        case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1355            pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
1356            pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
1357            break;
1358        default:
1359            // use the default range
1360            break;
1361        }
1362
1363    }
1364
1365    return result;
1366}
1367
1368
1369//-----------------------------------------------------------------------------
1370SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
1371        const void *pConfigValue, SLuint32 valueSize) {
1372
1373    SLresult result;
1374
1375    assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
1376    if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1377
1378        // stream type
1379        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
1380            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1381            result = SL_RESULT_BUFFER_INSUFFICIENT;
1382        } else {
1383            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
1384        }
1385
1386    } else {
1387        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1388        result = SL_RESULT_PARAMETER_INVALID;
1389    }
1390
1391    return result;
1392}
1393
1394
1395//-----------------------------------------------------------------------------
1396SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
1397        SLuint32* pValueSize, void *pConfigValue) {
1398
1399    SLresult result;
1400
1401    assert(NULL != ap && NULL != configKey && NULL != pValueSize);
1402    if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1403
1404        // stream type
1405        if (NULL == pConfigValue) {
1406            result = SL_RESULT_SUCCESS;
1407        } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
1408            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1409            result = SL_RESULT_BUFFER_INSUFFICIENT;
1410        } else {
1411            result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
1412        }
1413        *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
1414
1415    } else {
1416        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1417        result = SL_RESULT_PARAMETER_INVALID;
1418    }
1419
1420    return result;
1421}
1422
1423
1424//-----------------------------------------------------------------------------
1425SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1426
1427    SLresult result = SL_RESULT_SUCCESS;
1428    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1429
1430    switch (pAudioPlayer->mAndroidObjType) {
1431    //-----------------------------------
1432    // AudioTrack
1433    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1434        {
1435        // initialize platform-specific CAudioPlayer fields
1436
1437        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
1438                pAudioPlayer->mDynamicSource.mDataSource;
1439        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1440                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1441
1442        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1443
1444        pAudioPlayer->mAudioTrack = new android::AudioTrackProxy(new android::AudioTrack(
1445                pAudioPlayer->mStreamType,                           // streamType
1446                sampleRate,                                          // sampleRate
1447                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
1448                sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
1449                                                                     //channel mask
1450                0,                                                   // frameCount (here min)
1451                0,                                                   // flags
1452                audioTrack_callBack_pullFromBuffQueue,               // callback
1453                (void *) pAudioPlayer,                               // user
1454                0      // FIXME find appropriate frame count         // notificationFrame
1455                , pAudioPlayer->mSessionId
1456                ));
1457        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
1458        if (status != android::NO_ERROR) {
1459            SL_LOGE("AudioTrack::initCheck status %u", status);
1460            result = SL_RESULT_CONTENT_UNSUPPORTED;
1461            pAudioPlayer->mAudioTrack.clear();
1462            return result;
1463        }
1464
1465        // initialize platform-independent CAudioPlayer fields
1466
1467        pAudioPlayer->mNumChannels = df_pcm->numChannels;
1468        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
1469
1470        pAudioPlayer->mAndroidObjState = ANDROID_READY;
1471        }
1472        break;
1473    //-----------------------------------
1474    // MediaPlayer
1475    case AUDIOPLAYER_FROM_URIFD: {
1476        object_lock_exclusive(&pAudioPlayer->mObject);
1477
1478        assert(pAudioPlayer->mAndroidObjState == ANDROID_UNINITIALIZED);
1479        assert(pAudioPlayer->mNumChannels == UNKNOWN_NUMCHANNELS);
1480        assert(pAudioPlayer->mSampleRateMilliHz == UNKNOWN_SAMPLERATE);
1481        assert(pAudioPlayer->mAudioTrack == 0);
1482
1483        AudioPlayback_Parameters app;
1484        app.sessionId = pAudioPlayer->mSessionId;
1485        app.streamType = pAudioPlayer->mStreamType;
1486        app.trackcb = audioTrack_callBack_uri;
1487        app.trackcbUser = (void *) pAudioPlayer;
1488
1489        pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
1490        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
1491                        (void*)pAudioPlayer /*notifUSer*/);
1492
1493        object_unlock_exclusive(&pAudioPlayer->mObject);
1494
1495        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1496            case SL_DATALOCATOR_URI:
1497                pAudioPlayer->mAPlayer->setDataSource(
1498                        (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1499                break;
1500            case SL_DATALOCATOR_ANDROIDFD: {
1501                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1502                pAudioPlayer->mAPlayer->setDataSource(
1503                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1504                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1505                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1506                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1507                }
1508                break;
1509            default:
1510                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1511                break;
1512        }
1513
1514        }
1515        break;
1516    //-----------------------------------
1517    // StreamPlayer
1518    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
1519        object_lock_exclusive(&pAudioPlayer->mObject);
1520
1521        android_StreamPlayer_realize_l(pAudioPlayer, sfplayer_handlePrefetchEvent,
1522                (void*)pAudioPlayer);
1523
1524        object_unlock_exclusive(&pAudioPlayer->mObject);
1525        }
1526        break;
1527    //-----------------------------------
1528    // AudioToCbRenderer
1529    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
1530        object_lock_exclusive(&pAudioPlayer->mObject);
1531
1532        AudioPlayback_Parameters app;
1533        app.sessionId = pAudioPlayer->mSessionId;
1534        app.streamType = pAudioPlayer->mStreamType;
1535
1536        android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
1537        pAudioPlayer->mAPlayer = decoder;
1538        // configures the callback for the sink buffer queue
1539        decoder->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer);
1540        // configures the callback for the notifications coming from the SF code
1541        decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1542
1543        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1544        case SL_DATALOCATOR_URI:
1545            decoder->setDataSource(
1546                    (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1547            break;
1548        case SL_DATALOCATOR_ANDROIDFD: {
1549            int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1550            decoder->setDataSource(
1551                    (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1552                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1553                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1554                            (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1555            }
1556            break;
1557        default:
1558            SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1559            break;
1560        }
1561
1562        object_unlock_exclusive(&pAudioPlayer->mObject);
1563        }
1564        break;
1565    //-----------------------------------
1566    // AacBqToPcmCbRenderer
1567    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
1568        object_lock_exclusive(&pAudioPlayer->mObject);
1569
1570        AudioPlayback_Parameters app;
1571        app.sessionId = pAudioPlayer->mSessionId;
1572        app.streamType = pAudioPlayer->mStreamType;
1573        app.trackcb = NULL;
1574        app.trackcbUser = NULL;
1575        android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app);
1576        // configures the callback for the sink buffer queue
1577        bqtobq->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer);
1578        pAudioPlayer->mAPlayer = bqtobq;
1579        // configures the callback for the notifications coming from the SF code,
1580        // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
1581        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1582
1583        object_unlock_exclusive(&pAudioPlayer->mObject);
1584        }
1585        break;
1586    //-----------------------------------
1587    default:
1588        SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1589        result = SL_RESULT_INTERNAL_ERROR;
1590        break;
1591    }
1592
1593
1594    // proceed with effect initialization
1595    // initialize EQ
1596    // FIXME use a table of effect descriptors when adding support for more effects
1597    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1598            sizeof(effect_uuid_t)) == 0) {
1599        SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1600        android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1601    }
1602    // initialize BassBoost
1603    if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1604            sizeof(effect_uuid_t)) == 0) {
1605        SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1606        android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1607    }
1608    // initialize Virtualizer
1609    if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1610               sizeof(effect_uuid_t)) == 0) {
1611        SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1612        android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1613    }
1614
1615    // initialize EffectSend
1616    // FIXME initialize EffectSend
1617
1618    return result;
1619}
1620
1621
1622//-----------------------------------------------------------------------------
1623/**
1624 * Called with a lock on AudioPlayer
1625 */
1626SLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
1627    SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
1628    SLresult result = SL_RESULT_SUCCESS;
1629
1630    if (pAudioPlayer->mAPlayer != 0) {
1631        pAudioPlayer->mAPlayer->preDestroy();
1632    }
1633    SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
1634
1635    object_unlock_exclusive(&pAudioPlayer->mObject);
1636    if (pAudioPlayer->mCallbackProtector != 0) {
1637        pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
1638    }
1639    object_lock_exclusive(&pAudioPlayer->mObject);
1640
1641    return result;
1642}
1643
1644
1645//-----------------------------------------------------------------------------
1646SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1647    SLresult result = SL_RESULT_SUCCESS;
1648    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1649    switch (pAudioPlayer->mAndroidObjType) {
1650
1651    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1652        // We own the audio track for PCM buffer queue players
1653        if (pAudioPlayer->mAudioTrack != 0) {
1654            pAudioPlayer->mAudioTrack->stop();
1655            // Note that there may still be another reference in post-unlock phase of SetPlayState
1656            pAudioPlayer->mAudioTrack.clear();
1657        }
1658        break;
1659
1660    case AUDIOPLAYER_FROM_URIFD:     // intended fall-through
1661    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
1662    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
1663    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1664        pAudioPlayer->mAPlayer.clear();
1665        break;
1666    //-----------------------------------
1667    default:
1668        SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1669        result = SL_RESULT_INTERNAL_ERROR;
1670        break;
1671    }
1672
1673    pAudioPlayer->mCallbackProtector.clear();
1674
1675    // FIXME might not be needed
1676    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
1677
1678    // explicit destructor
1679    pAudioPlayer->mAudioTrack.~sp();
1680    // note that SetPlayState(PLAYING) may still hold a reference
1681    pAudioPlayer->mCallbackProtector.~sp();
1682    pAudioPlayer->mAuxEffect.~sp();
1683    pAudioPlayer->mAPlayer.~sp();
1684
1685    if (pAudioPlayer->mpLock != NULL) {
1686        delete pAudioPlayer->mpLock;
1687        pAudioPlayer->mpLock = NULL;
1688    }
1689
1690    return result;
1691}
1692
1693
1694//-----------------------------------------------------------------------------
1695SLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
1696        SLuint32 constraints) {
1697    SLresult result = SL_RESULT_SUCCESS;
1698    switch(ap->mAndroidObjType) {
1699    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
1700        // these asserts were already checked by the platform-independent layer
1701        assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
1702                (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
1703        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
1704        // get the content sample rate
1705        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1706        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
1707        if (ap->mAudioTrack != 0) {
1708            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
1709        }
1710        }
1711        break;
1712    case AUDIOPLAYER_FROM_URIFD:
1713        assert(rate == 1000);
1714        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
1715        // that was easy
1716        break;
1717
1718    default:
1719        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1720        result = SL_RESULT_FEATURE_UNSUPPORTED;
1721        break;
1722    }
1723    return result;
1724}
1725
1726
1727//-----------------------------------------------------------------------------
1728// precondition
1729//  called with no lock held
1730//  ap != NULL
1731//  pItemCount != NULL
1732SLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
1733    if (ap->mAPlayer == 0) {
1734        return SL_RESULT_PARAMETER_INVALID;
1735    }
1736    switch(ap->mAndroidObjType) {
1737      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1738        {
1739            android::AudioSfDecoder* decoder =
1740                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1741            *pItemCount = decoder->getPcmFormatKeyCount();
1742        }
1743        break;
1744      default:
1745        *pItemCount = 0;
1746        break;
1747    }
1748    return SL_RESULT_SUCCESS;
1749}
1750
1751
1752//-----------------------------------------------------------------------------
1753// precondition
1754//  called with no lock held
1755//  ap != NULL
1756//  pKeySize != NULL
1757SLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
1758        SLuint32 index, SLuint32 *pKeySize) {
1759    if (ap->mAPlayer == 0) {
1760        return SL_RESULT_PARAMETER_INVALID;
1761    }
1762    SLresult res = SL_RESULT_SUCCESS;
1763    switch(ap->mAndroidObjType) {
1764      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1765        {
1766            android::AudioSfDecoder* decoder =
1767                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1768            SLuint32 keyNameSize = 0;
1769            if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
1770                res = SL_RESULT_PARAMETER_INVALID;
1771            } else {
1772                // *pKeySize is the size of the region used to store the key name AND
1773                //   the information about the key (size, lang, encoding)
1774                *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
1775            }
1776        }
1777        break;
1778      default:
1779        *pKeySize = 0;
1780        res = SL_RESULT_PARAMETER_INVALID;
1781        break;
1782    }
1783    return res;
1784}
1785
1786
1787//-----------------------------------------------------------------------------
1788// precondition
1789//  called with no lock held
1790//  ap != NULL
1791//  pKey != NULL
1792SLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
1793        SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
1794    if (ap->mAPlayer == 0) {
1795        return SL_RESULT_PARAMETER_INVALID;
1796    }
1797    SLresult res = SL_RESULT_SUCCESS;
1798    switch(ap->mAndroidObjType) {
1799      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1800        {
1801            android::AudioSfDecoder* decoder =
1802                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1803            if ((size < sizeof(SLMetadataInfo) ||
1804                    (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
1805                            (char*)pKey->data)))) {
1806                res = SL_RESULT_PARAMETER_INVALID;
1807            } else {
1808                // successfully retrieved the key value, update the other fields
1809                pKey->encoding = SL_CHARACTERENCODING_UTF8;
1810                memcpy((char *) pKey->langCountry, "en", 3);
1811                pKey->size = strlen((char*)pKey->data) + 1;
1812            }
1813        }
1814        break;
1815      default:
1816        res = SL_RESULT_PARAMETER_INVALID;
1817        break;
1818    }
1819    return res;
1820}
1821
1822
1823//-----------------------------------------------------------------------------
1824// precondition
1825//  called with no lock held
1826//  ap != NULL
1827//  pValueSize != NULL
1828SLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
1829        SLuint32 index, SLuint32 *pValueSize) {
1830    if (ap->mAPlayer == 0) {
1831        return SL_RESULT_PARAMETER_INVALID;
1832    }
1833    SLresult res = SL_RESULT_SUCCESS;
1834    switch(ap->mAndroidObjType) {
1835      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1836        {
1837            android::AudioSfDecoder* decoder =
1838                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1839            SLuint32 valueSize = 0;
1840            if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
1841                res = SL_RESULT_PARAMETER_INVALID;
1842            } else {
1843                // *pValueSize is the size of the region used to store the key value AND
1844                //   the information about the value (size, lang, encoding)
1845                *pValueSize = valueSize + sizeof(SLMetadataInfo);
1846            }
1847        }
1848        break;
1849      default:
1850          *pValueSize = 0;
1851          res = SL_RESULT_PARAMETER_INVALID;
1852          break;
1853    }
1854    return res;
1855}
1856
1857
1858//-----------------------------------------------------------------------------
1859// precondition
1860//  called with no lock held
1861//  ap != NULL
1862//  pValue != NULL
1863SLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
1864        SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
1865    if (ap->mAPlayer == 0) {
1866        return SL_RESULT_PARAMETER_INVALID;
1867    }
1868    SLresult res = SL_RESULT_SUCCESS;
1869    switch(ap->mAndroidObjType) {
1870      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1871        {
1872            android::AudioSfDecoder* decoder =
1873                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1874            pValue->encoding = SL_CHARACTERENCODING_BINARY;
1875            memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
1876            SLuint32 valueSize = 0;
1877            if ((size < sizeof(SLMetadataInfo)
1878                    || (!decoder->getPcmFormatValueSize(index, &valueSize))
1879                    || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
1880                            (SLuint32*)pValue->data)))) {
1881                res = SL_RESULT_PARAMETER_INVALID;
1882            } else {
1883                pValue->size = valueSize;
1884            }
1885        }
1886        break;
1887      default:
1888        res = SL_RESULT_PARAMETER_INVALID;
1889        break;
1890    }
1891    return res;
1892}
1893
1894//-----------------------------------------------------------------------------
1895// preconditions
1896//  ap != NULL
1897//  mutex is locked
1898//  play state has changed
1899void android_audioPlayer_setPlayState(CAudioPlayer *ap) {
1900
1901    SLuint32 playState = ap->mPlay.mState;
1902    AndroidObjectState objState = ap->mAndroidObjState;
1903
1904    switch(ap->mAndroidObjType) {
1905    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1906        switch (playState) {
1907        case SL_PLAYSTATE_STOPPED:
1908            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1909            if (ap->mAudioTrack != 0) {
1910                ap->mAudioTrack->stop();
1911            }
1912            break;
1913        case SL_PLAYSTATE_PAUSED:
1914            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1915            if (ap->mAudioTrack != 0) {
1916                ap->mAudioTrack->pause();
1917            }
1918            break;
1919        case SL_PLAYSTATE_PLAYING:
1920            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1921            if (ap->mAudioTrack != 0) {
1922                // instead of ap->mAudioTrack->start();
1923                ap->mDeferredStart = true;
1924            }
1925            break;
1926        default:
1927            // checked by caller, should not happen
1928            break;
1929        }
1930        break;
1931
1932    case AUDIOPLAYER_FROM_URIFD:      // intended fall-through
1933    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
1934    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
1935    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1936        // FIXME report and use the return code to the lock mechanism, which is where play state
1937        //   changes are updated (see object_unlock_exclusive_attributes())
1938        aplayer_setPlayState(ap->mAPlayer, playState, &(ap->mAndroidObjState));
1939        break;
1940    default:
1941        SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
1942        break;
1943    }
1944}
1945
1946
1947//-----------------------------------------------------------------------------
1948// call when either player event flags, marker position, or position update period changes
1949void android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1950    IPlay *pPlayItf = &ap->mPlay;
1951    SLuint32 eventFlags = pPlayItf->mEventFlags;
1952    /*switch(ap->mAndroidObjType) {
1953    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
1954
1955    if (ap->mAPlayer != 0) {
1956        assert(ap->mAudioTrack == 0);
1957        ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
1958                (int32_t) pPlayItf->mPositionUpdatePeriod);
1959        return;
1960    }
1961
1962    if (ap->mAudioTrack == 0) {
1963        return;
1964    }
1965
1966    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1967        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1968                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1969    } else {
1970        // clear marker
1971        ap->mAudioTrack->setMarkerPosition(0);
1972    }
1973
1974    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1975         ap->mAudioTrack->setPositionUpdatePeriod(
1976                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
1977                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1978    } else {
1979        // clear periodic update
1980        ap->mAudioTrack->setPositionUpdatePeriod(0);
1981    }
1982
1983    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1984        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
1985    }
1986
1987    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
1988        // FIXME support SL_PLAYEVENT_HEADMOVING
1989        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
1990            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
1991    }
1992    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1993        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
1994    }
1995
1996}
1997
1998
1999//-----------------------------------------------------------------------------
2000SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
2001    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2002    switch(ap->mAndroidObjType) {
2003
2004      case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
2005      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
2006        int32_t durationMsec = ANDROID_UNKNOWN_TIME;
2007        if (ap->mAPlayer != 0) {
2008            ap->mAPlayer->getDurationMsec(&durationMsec);
2009        }
2010        *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
2011        break;
2012      }
2013
2014      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
2015      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:       // intended fall-through
2016      default: {
2017        *pDurMsec = SL_TIME_UNKNOWN;
2018      }
2019    }
2020    return SL_RESULT_SUCCESS;
2021}
2022
2023
2024//-----------------------------------------------------------------------------
2025void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
2026    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2027    switch(ap->mAndroidObjType) {
2028
2029      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2030        if ((ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) || (ap->mAudioTrack == 0)) {
2031            *pPosMsec = 0;
2032        } else {
2033            uint32_t positionInFrames;
2034            ap->mAudioTrack->getPosition(&positionInFrames);
2035            *pPosMsec = ((int64_t)positionInFrames * 1000) /
2036                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2037        }
2038        break;
2039
2040      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
2041      case AUDIOPLAYER_FROM_URIFD:                    // intended fall-through
2042      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
2043        int32_t posMsec = ANDROID_UNKNOWN_TIME;
2044        if (ap->mAPlayer != 0) {
2045            ap->mAPlayer->getPositionMsec(&posMsec);
2046        }
2047        *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
2048        break;
2049      }
2050
2051      default:
2052        *pPosMsec = 0;
2053    }
2054}
2055
2056
2057//-----------------------------------------------------------------------------
2058void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
2059
2060    switch(ap->mAndroidObjType) {
2061
2062      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
2063      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2064        break;
2065
2066      case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
2067      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2068        if (ap->mAPlayer != 0) {
2069            ap->mAPlayer->seek(posMsec);
2070        }
2071        break;
2072
2073      default:
2074        break;
2075    }
2076}
2077
2078
2079//-----------------------------------------------------------------------------
2080void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
2081
2082    if ((AUDIOPLAYER_FROM_URIFD == ap->mAndroidObjType) && (ap->mAPlayer != 0)) {
2083        ap->mAPlayer->loop((bool)loopEnable);
2084    }
2085}
2086
2087
2088//-----------------------------------------------------------------------------
2089SLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
2090        SLpermille threshold) {
2091    SLresult result = SL_RESULT_SUCCESS;
2092
2093    switch (ap->mAndroidObjType) {
2094      case AUDIOPLAYER_FROM_URIFD:
2095        if (ap->mAPlayer != 0) {
2096            ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
2097        }
2098        break;
2099
2100      default: {}
2101    }
2102
2103    return result;
2104}
2105
2106
2107//-----------------------------------------------------------------------------
2108void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
2109    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
2110    // queue was stopped when the queue become empty, we restart as soon as a new buffer
2111    // has been enqueued since we're in playing state
2112    if (ap->mAudioTrack != 0) {
2113        // instead of ap->mAudioTrack->start();
2114        ap->mDeferredStart = true;
2115    }
2116
2117    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
2118    // has received new data, signal it has sufficient data
2119    if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
2120        // we wouldn't have been called unless we were previously in the underflow state
2121        assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
2122        assert(0 == ap->mPrefetchStatus.mLevel);
2123        ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2124        ap->mPrefetchStatus.mLevel = 1000;
2125        // callback or no callback?
2126        SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
2127                (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
2128        if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
2129            ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
2130            ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
2131            ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
2132        }
2133    }
2134}
2135
2136
2137//-----------------------------------------------------------------------------
2138/*
2139 * BufferQueue::Clear
2140 */
2141SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
2142    SLresult result = SL_RESULT_SUCCESS;
2143
2144    switch (ap->mAndroidObjType) {
2145    //-----------------------------------
2146    // AudioTrack
2147    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2148        if (ap->mAudioTrack != 0) {
2149            ap->mAudioTrack->flush();
2150        }
2151        break;
2152    default:
2153        result = SL_RESULT_INTERNAL_ERROR;
2154        break;
2155    }
2156
2157    return result;
2158}
2159
2160
2161//-----------------------------------------------------------------------------
2162SLresult android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) {
2163    SLresult result = SL_RESULT_SUCCESS;
2164    assert(ap->mAPlayer != 0);
2165    switch (ap->mAndroidObjType) {
2166      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
2167          android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2168          splr->registerQueueCallback(
2169                  (const void*)ap /*user*/, true /*userIsAudioPlayer*/,
2170                  ap->mAndroidBufferQueue.mContext /*context*/,
2171                  (const void*)&(ap->mAndroidBufferQueue.mItf) /*caller*/);
2172        } break;
2173      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
2174          android::AacBqToPcmCbRenderer* dec =
2175                  static_cast<android::AacBqToPcmCbRenderer*>(ap->mAPlayer.get());
2176          dec->registerSourceQueueCallback((const void*)ap /*user*/,
2177                  ap->mAndroidBufferQueue.mContext /*context*/,
2178                  (const void*)&(ap->mAndroidBufferQueue.mItf) /*caller*/);
2179        } break;
2180      default:
2181        SL_LOGE("Error registering AndroidBufferQueue callback: unexpected object type %d",
2182                ap->mAndroidObjType);
2183        result = SL_RESULT_INTERNAL_ERROR;
2184        break;
2185    }
2186    return result;
2187}
2188
2189//-----------------------------------------------------------------------------
2190void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
2191    if ((ap->mAndroidObjType == AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) && (ap->mAPlayer != 0)) {
2192        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2193        splr->appClear_l();
2194    }
2195}
2196
2197void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
2198    if ((ap->mAndroidObjType == AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) && (ap->mAPlayer != 0)) {
2199        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2200        splr->queueRefilled_l();
2201    }
2202}
2203