AudioPlayer_to_android.cpp revision ccabcf9073f0ccd12016ff1f05d1c4456c41b254
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    if (NULL == user) {
710        return;
711    }
712
713    CAudioPlayer *ap = (CAudioPlayer *)user;
714    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
715        // it is not safe to enter the callback (the track is about to go away)
716        return;
717    }
718    union {
719        char c[sizeof(int)];
720        int i;
721    } u;
722    u.i = event;
723    SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
724            "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
725    switch(event) {
726
727    case android::GenericPlayer::kEventPrepared: {
728
729        if (PLAYER_SUCCESS != data1) {
730            object_lock_exclusive(&ap->mObject);
731
732            // already initialized at object creation, and can only prepare once so never reset
733            assert(ap->mAudioTrack == 0);
734            assert(ap->mNumChannels == UNKNOWN_NUMCHANNELS);
735            assert(ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE);
736            assert(ap->mAndroidObjState == ANDROID_PREPARING);
737            ap->mAndroidObjState = ANDROID_READY;
738
739            object_unlock_exclusive(&ap->mObject);
740
741            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
742            //  indicate a prefetch error, so we signal it by sending simulataneously two events:
743            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
744            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
745            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
746            if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
747                break;
748            }
749
750            slPrefetchCallback callback = NULL;
751            void* callbackPContext = NULL;
752
753            interface_lock_exclusive(&ap->mPrefetchStatus);
754            ap->mPrefetchStatus.mLevel = 0;
755            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
756            if ((ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE)
757                    && (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE)) {
758                callback = ap->mPrefetchStatus.mCallback;
759                callbackPContext = ap->mPrefetchStatus.mContext;
760            }
761            interface_unlock_exclusive(&ap->mPrefetchStatus);
762
763            // callback with no lock held
764            if (NULL != callback) {
765                (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
766                        SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
767            }
768
769
770        } else {
771
772            object_lock_exclusive(&ap->mObject);
773
774            if (AUDIOPLAYER_FROM_URIFD == ap->mAndroidObjType) {
775                //**************************************
776                // FIXME move under GenericMediaPlayer
777#if 0
778                ap->mAudioTrack = ap->mSfPlayer->getAudioTrack();
779                ap->mNumChannels = ap->mSfPlayer->getNumChannels();
780                ap->mSampleRateMilliHz =
781                        android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz());
782                ap->mSfPlayer->startPrefetch_async();
783                // update the new track with the current settings
784                audioPlayer_auxEffectUpdate(ap);
785                android_audioPlayer_useEventMask(ap);
786                android_audioPlayer_volumeUpdate(ap);
787                android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/);
788#endif
789            } else if (AUDIOPLAYER_FROM_PCM_BUFFERQUEUE == ap->mAndroidObjType) {
790                if (ap->mAPlayer != 0) {
791                    ((android::AudioToCbRenderer*)ap->mAPlayer.get())->startPrefetch_async();
792                }
793            } else if (AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE == ap->mAndroidObjType) {
794                SL_LOGD("Received SfPlayer::kEventPrepared from AVPlayer for CAudioPlayer %p", ap);
795            }
796
797            ap->mAndroidObjState = ANDROID_READY;
798
799            object_unlock_exclusive(&ap->mObject);
800        }
801
802    }
803    break;
804
805    case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
806        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
807            break;
808        }
809        slPrefetchCallback callback = NULL;
810        void* callbackPContext = NULL;
811
812        // SLPrefetchStatusItf callback or no callback?
813        interface_lock_exclusive(&ap->mPrefetchStatus);
814        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
815            callback = ap->mPrefetchStatus.mCallback;
816            callbackPContext = ap->mPrefetchStatus.mContext;
817        }
818        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
819        interface_unlock_exclusive(&ap->mPrefetchStatus);
820
821        // callback with no lock held
822        if (NULL != callback) {
823            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
824                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
825        }
826    }
827    break;
828
829    case android::GenericPlayer::kEventPrefetchStatusChange: {
830        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
831            break;
832        }
833        slPrefetchCallback callback = NULL;
834        void* callbackPContext = NULL;
835
836        // SLPrefetchStatusItf callback or no callback?
837        object_lock_exclusive(&ap->mObject);
838        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
839            callback = ap->mPrefetchStatus.mCallback;
840            callbackPContext = ap->mPrefetchStatus.mContext;
841        }
842        if (data1 >= android::kStatusIntermediate) {
843            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
844            ap->mAndroidObjState = ANDROID_READY;
845        } else if (data1 < android::kStatusIntermediate) {
846            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
847        }
848        object_unlock_exclusive(&ap->mObject);
849
850        // callback with no lock held
851        if (NULL != callback) {
852            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
853        }
854        }
855        break;
856
857    case android::GenericPlayer::kEventEndOfStream: {
858        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
859        if ((ap->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
860            ap->mAudioTrack->stop();
861        }
862        }
863        break;
864
865    case android::GenericPlayer::kEventChannelCount: {
866        object_lock_exclusive(&ap->mObject);
867        if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
868            ap->mNumChannels = data1;
869            android_audioPlayer_volumeUpdate(ap);
870        }
871        object_unlock_exclusive(&ap->mObject);
872        }
873        break;
874
875    case android::GenericPlayer::kEventPlay: {
876        slPlayCallback callback = NULL;
877        void* callbackPContext = NULL;
878
879        interface_lock_shared(&ap->mPlay);
880        callback = ap->mPlay.mCallback;
881        callbackPContext = ap->mPlay.mContext;
882        interface_unlock_shared(&ap->mPlay);
883
884        if (NULL != callback) {
885            SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
886#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
887            // synchronous callback requires a synchronous GetPosition implementation
888            (*callback)(&ap->mPlay.mItf, callbackPContext, event);
889#else
890            // asynchronous callback works with any GetPosition implementation
891            SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
892                    callbackPContext, event);
893            if (SL_RESULT_SUCCESS != result) {
894                LOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
895                        &ap->mPlay.mItf, callbackPContext, event);
896            }
897#endif
898        }
899        }
900        break;
901
902    default:
903        break;
904    }
905
906    ap->mCallbackProtector->exitCb();
907}
908
909
910//-----------------------------------------------------------------------------
911SLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
912{
913    // verify that the locator types for the source / sink combination is supported
914    pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
915    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
916        return SL_RESULT_PARAMETER_INVALID;
917    }
918
919    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
920    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
921
922    // format check:
923    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
924    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
925    const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
926    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat;
927
928    switch (sourceLocatorType) {
929    //------------------
930    //   Buffer Queues
931    case SL_DATALOCATOR_BUFFERQUEUE:
932    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
933        {
934        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
935
936        // Buffer format
937        switch (sourceFormatType) {
938        //     currently only PCM buffer queues are supported,
939        case SL_DATAFORMAT_PCM: {
940            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
941            switch (df_pcm->numChannels) {
942            case 1:
943            case 2:
944                break;
945            default:
946                // this should have already been rejected by checkDataFormat
947                SL_LOGE("Cannot create audio player: unsupported " \
948                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
949                return SL_RESULT_CONTENT_UNSUPPORTED;
950            }
951            switch (df_pcm->samplesPerSec) {
952            case SL_SAMPLINGRATE_8:
953            case SL_SAMPLINGRATE_11_025:
954            case SL_SAMPLINGRATE_12:
955            case SL_SAMPLINGRATE_16:
956            case SL_SAMPLINGRATE_22_05:
957            case SL_SAMPLINGRATE_24:
958            case SL_SAMPLINGRATE_32:
959            case SL_SAMPLINGRATE_44_1:
960            case SL_SAMPLINGRATE_48:
961                break;
962            case SL_SAMPLINGRATE_64:
963            case SL_SAMPLINGRATE_88_2:
964            case SL_SAMPLINGRATE_96:
965            case SL_SAMPLINGRATE_192:
966            default:
967                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
968                    (unsigned) df_pcm->samplesPerSec);
969                return SL_RESULT_CONTENT_UNSUPPORTED;
970            }
971            switch (df_pcm->bitsPerSample) {
972            case SL_PCMSAMPLEFORMAT_FIXED_8:
973                // FIXME We should support this
974                //SL_LOGE("Cannot create audio player: unsupported 8-bit data");
975                //return SL_RESULT_CONTENT_UNSUPPORTED;
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            switch (df_pcm->channelMask) {
996                // FIXME needs work
997            default:
998                break;
999            }
1000            switch (df_pcm->endianness) {
1001            case SL_BYTEORDER_LITTLEENDIAN:
1002                break;
1003            case SL_BYTEORDER_BIGENDIAN:
1004                SL_LOGE("Cannot create audio player: unsupported big-endian byte order");
1005                return SL_RESULT_CONTENT_UNSUPPORTED;
1006                // native is proposed but not yet in spec
1007            default:
1008                SL_LOGE("Cannot create audio player: unsupported byte order %u",
1009                    (unsigned) df_pcm->endianness);
1010                return SL_RESULT_CONTENT_UNSUPPORTED;
1011            }
1012            } //case SL_DATAFORMAT_PCM
1013            break;
1014        case SL_DATAFORMAT_MIME:
1015        case XA_DATAFORMAT_RAWIMAGE:
1016            SL_LOGE("Cannot create audio player with buffer queue data source "
1017                "without SL_DATAFORMAT_PCM format");
1018            return SL_RESULT_CONTENT_UNSUPPORTED;
1019        default:
1020            // invalid data format is detected earlier
1021            assert(false);
1022            return SL_RESULT_INTERNAL_ERROR;
1023        } // switch (sourceFormatType)
1024        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
1025        break;
1026    //------------------
1027    //   URI
1028    case SL_DATALOCATOR_URI:
1029        {
1030        SLDataLocator_URI *dl_uri =  (SLDataLocator_URI *) pAudioSrc->pLocator;
1031        if (NULL == dl_uri->URI) {
1032            return SL_RESULT_PARAMETER_INVALID;
1033        }
1034        // URI format
1035        switch (sourceFormatType) {
1036        case SL_DATAFORMAT_MIME:
1037            break;
1038        case SL_DATAFORMAT_PCM:
1039        case XA_DATAFORMAT_RAWIMAGE:
1040            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
1041                "SL_DATAFORMAT_MIME format");
1042            return SL_RESULT_CONTENT_UNSUPPORTED;
1043        } // switch (sourceFormatType)
1044        // decoding format check
1045        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
1046                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
1047            return SL_RESULT_CONTENT_UNSUPPORTED;
1048        }
1049        } // case SL_DATALOCATOR_URI
1050        break;
1051    //------------------
1052    //   File Descriptor
1053    case SL_DATALOCATOR_ANDROIDFD:
1054        {
1055        // fd is already non null
1056        switch (sourceFormatType) {
1057        case SL_DATAFORMAT_MIME:
1058            break;
1059        case SL_DATAFORMAT_PCM:
1060            // FIXME implement
1061            SL_LOGD("[ FIXME implement PCM FD data sources ]");
1062            break;
1063        case XA_DATAFORMAT_RAWIMAGE:
1064            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
1065                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
1066            return SL_RESULT_CONTENT_UNSUPPORTED;
1067        default:
1068            // invalid data format is detected earlier
1069            assert(false);
1070            return SL_RESULT_INTERNAL_ERROR;
1071        } // switch (sourceFormatType)
1072        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
1073                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
1074            return SL_RESULT_CONTENT_UNSUPPORTED;
1075        }
1076        } // case SL_DATALOCATOR_ANDROIDFD
1077        break;
1078    //------------------
1079    //   Stream
1080    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
1081    {
1082        switch (sourceFormatType) {
1083        case SL_DATAFORMAT_MIME:
1084        {
1085            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
1086            if (NULL == df_mime) {
1087                SL_LOGE("MIME type null invalid");
1088                return SL_RESULT_CONTENT_UNSUPPORTED;
1089            }
1090            SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
1091            switch(df_mime->containerType) {
1092            case SL_CONTAINERTYPE_MPEG_TS:
1093                if (strcasecmp((char*)df_mime->mimeType, ANDROID_MIME_MP2TS)) {
1094                    SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
1095                            (char*)df_mime->mimeType, ANDROID_MIME_MP2TS);
1096                    return SL_RESULT_CONTENT_UNSUPPORTED;
1097                }
1098                break;
1099            case SL_CONTAINERTYPE_RAW:
1100            case SL_CONTAINERTYPE_AAC:
1101                if (strcasecmp((char*)df_mime->mimeType, ANDROID_MIME_AACADTS) &&
1102                        strcasecmp((char*)df_mime->mimeType,
1103                                ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
1104                    SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
1105                            (char*)df_mime->mimeType, df_mime->containerType,
1106                            ANDROID_MIME_AACADTS);
1107                    return SL_RESULT_CONTENT_UNSUPPORTED;
1108                }
1109                break;
1110            default:
1111                SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1112                                        "that is not fed MPEG-2 TS data or AAC ADTS data");
1113                return SL_RESULT_CONTENT_UNSUPPORTED;
1114            }
1115        }
1116        break;
1117        default:
1118            SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1119                    "without SL_DATAFORMAT_MIME format");
1120            return SL_RESULT_CONTENT_UNSUPPORTED;
1121        }
1122    }
1123    break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
1124    //------------------
1125    //   Address
1126    case SL_DATALOCATOR_ADDRESS:
1127    case SL_DATALOCATOR_IODEVICE:
1128    case SL_DATALOCATOR_OUTPUTMIX:
1129    case XA_DATALOCATOR_NATIVEDISPLAY:
1130    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
1131        SL_LOGE("Cannot create audio player with data locator type 0x%x",
1132                (unsigned) sourceLocatorType);
1133        return SL_RESULT_CONTENT_UNSUPPORTED;
1134    default:
1135        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
1136                (unsigned) sourceLocatorType);
1137        return SL_RESULT_PARAMETER_INVALID;
1138    }// switch (locatorType)
1139
1140    return SL_RESULT_SUCCESS;
1141}
1142
1143
1144
1145//-----------------------------------------------------------------------------
1146static void audioTrack_callBack_uri(int event, void* user, void *info) {
1147    // EVENT_MORE_DATA needs to be handled with priority over the other events
1148    // because it will be called the most often during playback
1149
1150    if (event == android::AudioTrack::EVENT_MORE_DATA) {
1151        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack");
1152        // set size to 0 to signal we're not using the callback to write more data
1153        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1154        pBuff->size = 0;
1155    } else if (NULL != user) {
1156        CAudioPlayer *ap = (CAudioPlayer *)user;
1157        if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
1158            // it is not safe to enter the callback (the track is about to go away)
1159            return;
1160        }
1161        switch (event) {
1162            case android::AudioTrack::EVENT_MARKER :
1163                audioTrack_handleMarker_lockPlay(ap);
1164                break;
1165            case android::AudioTrack::EVENT_NEW_POS :
1166                audioTrack_handleNewPos_lockPlay(ap);
1167                break;
1168            case android::AudioTrack::EVENT_UNDERRUN :
1169                audioTrack_handleUnderrun_lockPlay(ap);
1170                break;
1171            case android::AudioTrack::EVENT_BUFFER_END :
1172            case android::AudioTrack::EVENT_LOOP_END :
1173                break;
1174            default:
1175                SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1176                        ap);
1177                break;
1178        }
1179        ap->mCallbackProtector->exitCb();
1180    }
1181}
1182
1183//-----------------------------------------------------------------------------
1184// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
1185// from a buffer queue. This will not be called once the AudioTrack has been destroyed.
1186static void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
1187    CAudioPlayer *ap = (CAudioPlayer *)user;
1188
1189    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
1190        // it is not safe to enter the callback (the track is about to go away)
1191        return;
1192    }
1193
1194    void * callbackPContext = NULL;
1195    switch(event) {
1196
1197    case android::AudioTrack::EVENT_MORE_DATA: {
1198        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
1199        slBufferQueueCallback callback = NULL;
1200        slPrefetchCallback prefetchCallback = NULL;
1201        void *prefetchContext = NULL;
1202        SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
1203        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1204
1205        // retrieve data from the buffer queue
1206        interface_lock_exclusive(&ap->mBufferQueue);
1207
1208        if (ap->mBufferQueue.mState.count != 0) {
1209            //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
1210            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
1211
1212            BufferHeader *oldFront = ap->mBufferQueue.mFront;
1213            BufferHeader *newFront = &oldFront[1];
1214
1215            // FIXME handle 8bit based on buffer format
1216            short *pSrc = (short*)((char *)oldFront->mBuffer
1217                    + ap->mBufferQueue.mSizeConsumed);
1218            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
1219                // can't consume the whole or rest of the buffer in one shot
1220                ap->mBufferQueue.mSizeConsumed += pBuff->size;
1221                // leave pBuff->size untouched
1222                // consume data
1223                // FIXME can we avoid holding the lock during the copy?
1224                memcpy (pBuff->i16, pSrc, pBuff->size);
1225            } else {
1226                // finish consuming the buffer or consume the buffer in one shot
1227                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
1228                ap->mBufferQueue.mSizeConsumed = 0;
1229
1230                if (newFront ==
1231                        &ap->mBufferQueue.mArray
1232                            [ap->mBufferQueue.mNumBuffers + 1])
1233                {
1234                    newFront = ap->mBufferQueue.mArray;
1235                }
1236                ap->mBufferQueue.mFront = newFront;
1237
1238                ap->mBufferQueue.mState.count--;
1239                ap->mBufferQueue.mState.playIndex++;
1240
1241                // consume data
1242                // FIXME can we avoid holding the lock during the copy?
1243                memcpy (pBuff->i16, pSrc, pBuff->size);
1244
1245                // data has been consumed, and the buffer queue state has been updated
1246                // we will notify the client if applicable
1247                callback = ap->mBufferQueue.mCallback;
1248                // save callback data
1249                callbackPContext = ap->mBufferQueue.mContext;
1250            }
1251        } else { // empty queue
1252            // signal no data available
1253            pBuff->size = 0;
1254
1255            // signal we're at the end of the content, but don't pause (see note in function)
1256            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1257
1258            // signal underflow to prefetch status itf
1259            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1260                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
1261                ap->mPrefetchStatus.mLevel = 0;
1262                // callback or no callback?
1263                prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
1264                        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
1265                if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
1266                    prefetchCallback = ap->mPrefetchStatus.mCallback;
1267                    prefetchContext  = ap->mPrefetchStatus.mContext;
1268                }
1269            }
1270
1271            // stop the track so it restarts playing faster when new data is enqueued
1272            ap->mAudioTrack->stop();
1273        }
1274        interface_unlock_exclusive(&ap->mBufferQueue);
1275
1276        // notify client
1277        if (NULL != prefetchCallback) {
1278            assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
1279            // spec requires separate callbacks for each event
1280            if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
1281                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1282                        SL_PREFETCHEVENT_STATUSCHANGE);
1283            }
1284            if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
1285                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1286                        SL_PREFETCHEVENT_FILLLEVELCHANGE);
1287            }
1288        }
1289        if (NULL != callback) {
1290            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
1291        }
1292    }
1293    break;
1294
1295    case android::AudioTrack::EVENT_MARKER:
1296        //SL_LOGI("received event EVENT_MARKER from AudioTrack");
1297        audioTrack_handleMarker_lockPlay(ap);
1298        break;
1299
1300    case android::AudioTrack::EVENT_NEW_POS:
1301        //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
1302        audioTrack_handleNewPos_lockPlay(ap);
1303        break;
1304
1305    case android::AudioTrack::EVENT_UNDERRUN:
1306        //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
1307        audioTrack_handleUnderrun_lockPlay(ap);
1308        break;
1309
1310    default:
1311        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
1312        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
1313                (CAudioPlayer *)user);
1314        break;
1315    }
1316
1317    ap->mCallbackProtector->exitCb();
1318}
1319
1320
1321//-----------------------------------------------------------------------------
1322SLresult android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1323
1324    SLresult result = SL_RESULT_SUCCESS;
1325    // pAudioPlayer->mAndroidObjType has been set in audioPlayer_getAndroidObjectTypeForSourceSink()
1326    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
1327        audioPlayer_setInvalid(pAudioPlayer);
1328        result = SL_RESULT_PARAMETER_INVALID;
1329    } else {
1330
1331        // These initializations are in the same order as the field declarations in classes.h
1332
1333        // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
1334        pAudioPlayer->mpLock = new android::Mutex();
1335        // mAndroidObjType: see above comment
1336        pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1337        pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
1338        pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
1339
1340        // mAudioTrack
1341        pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
1342        // mAPLayer
1343        // mAuxEffect
1344
1345        pAudioPlayer->mAuxSendLevel = 0;
1346        pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
1347        pAudioPlayer->mDeferredStart = false;
1348
1349        // Already initialized in IEngine_CreateAudioPlayer, to be consolidated
1350        pAudioPlayer->mDirectLevel = 0; // no attenuation
1351
1352        // This section re-initializes interface-specific fields that
1353        // can be set or used regardless of whether the interface is
1354        // exposed on the AudioPlayer or not
1355
1356        // Only AudioTrack supports a non-trivial playback rate
1357        switch (pAudioPlayer->mAndroidObjType) {
1358        case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1359            pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
1360            pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
1361            break;
1362        default:
1363            // use the default range
1364            break;
1365        }
1366
1367    }
1368
1369    return result;
1370}
1371
1372
1373//-----------------------------------------------------------------------------
1374SLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
1375        const void *pConfigValue, SLuint32 valueSize) {
1376
1377    SLresult result;
1378
1379    assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
1380    if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1381
1382        // stream type
1383        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
1384            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1385            result = SL_RESULT_BUFFER_INSUFFICIENT;
1386        } else {
1387            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
1388        }
1389
1390    } else {
1391        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1392        result = SL_RESULT_PARAMETER_INVALID;
1393    }
1394
1395    return result;
1396}
1397
1398
1399//-----------------------------------------------------------------------------
1400SLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
1401        SLuint32* pValueSize, void *pConfigValue) {
1402
1403    SLresult result;
1404
1405    assert(NULL != ap && NULL != configKey && NULL != pValueSize);
1406    if(strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1407
1408        // stream type
1409        if (NULL == pConfigValue) {
1410            result = SL_RESULT_SUCCESS;
1411        } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
1412            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1413            result = SL_RESULT_BUFFER_INSUFFICIENT;
1414        } else {
1415            result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
1416        }
1417        *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
1418
1419    } else {
1420        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1421        result = SL_RESULT_PARAMETER_INVALID;
1422    }
1423
1424    return result;
1425}
1426
1427
1428//-----------------------------------------------------------------------------
1429SLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1430
1431    SLresult result = SL_RESULT_SUCCESS;
1432    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1433
1434    switch (pAudioPlayer->mAndroidObjType) {
1435    //-----------------------------------
1436    // AudioTrack
1437    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1438        {
1439        // initialize platform-specific CAudioPlayer fields
1440
1441        SLDataLocator_BufferQueue *dl_bq =  (SLDataLocator_BufferQueue *)
1442                pAudioPlayer->mDynamicSource.mDataSource;
1443        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
1444                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
1445
1446        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
1447
1448        pAudioPlayer->mAudioTrack = new android::AudioTrackProxy(new android::AudioTrack(
1449                pAudioPlayer->mStreamType,                           // streamType
1450                sampleRate,                                          // sampleRate
1451                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
1452                sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
1453                                                                     //channel mask
1454                0,                                                   // frameCount (here min)
1455                0,                                                   // flags
1456                audioTrack_callBack_pullFromBuffQueue,               // callback
1457                (void *) pAudioPlayer,                               // user
1458                0      // FIXME find appropriate frame count         // notificationFrame
1459                , pAudioPlayer->mSessionId
1460                ));
1461        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
1462        if (status != android::NO_ERROR) {
1463            SL_LOGE("AudioTrack::initCheck status %u", status);
1464            result = SL_RESULT_CONTENT_UNSUPPORTED;
1465            pAudioPlayer->mAudioTrack.clear();
1466            return result;
1467        }
1468
1469        // initialize platform-independent CAudioPlayer fields
1470
1471        pAudioPlayer->mNumChannels = df_pcm->numChannels;
1472        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
1473
1474        pAudioPlayer->mAndroidObjState = ANDROID_READY;
1475        }
1476        break;
1477    //-----------------------------------
1478    // MediaPlayer
1479    case AUDIOPLAYER_FROM_URIFD: {
1480        object_lock_exclusive(&pAudioPlayer->mObject);
1481
1482        assert(pAudioPlayer->mAndroidObjState == ANDROID_UNINITIALIZED);
1483        assert(pAudioPlayer->mNumChannels == UNKNOWN_NUMCHANNELS);
1484        assert(pAudioPlayer->mSampleRateMilliHz == UNKNOWN_SAMPLERATE);
1485        assert(pAudioPlayer->mAudioTrack == 0);
1486
1487        AudioPlayback_Parameters app;
1488        app.sessionId = pAudioPlayer->mSessionId;
1489        app.streamType = pAudioPlayer->mStreamType;
1490        app.trackcb = audioTrack_callBack_uri;
1491        app.trackcbUser = (void *) pAudioPlayer;
1492
1493        pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
1494        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
1495                        (void*)pAudioPlayer /*notifUSer*/);
1496
1497        object_unlock_exclusive(&pAudioPlayer->mObject);
1498
1499        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1500            case SL_DATALOCATOR_URI:
1501                pAudioPlayer->mAPlayer->setDataSource(
1502                        (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1503                break;
1504            case SL_DATALOCATOR_ANDROIDFD: {
1505                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1506                pAudioPlayer->mAPlayer->setDataSource(
1507                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1508                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1509                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1510                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1511                }
1512                break;
1513            default:
1514                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1515                break;
1516        }
1517
1518        }
1519        break;
1520    //-----------------------------------
1521    // StreamPlayer
1522    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
1523        object_lock_exclusive(&pAudioPlayer->mObject);
1524
1525        android_StreamPlayer_realize_l(pAudioPlayer, sfplayer_handlePrefetchEvent,
1526                (void*)pAudioPlayer);
1527
1528        object_unlock_exclusive(&pAudioPlayer->mObject);
1529        }
1530        break;
1531    //-----------------------------------
1532    // AudioToCbRenderer
1533    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
1534        object_lock_exclusive(&pAudioPlayer->mObject);
1535
1536        AudioPlayback_Parameters app;
1537        app.sessionId = pAudioPlayer->mSessionId;
1538        app.streamType = pAudioPlayer->mStreamType;
1539
1540        android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
1541        pAudioPlayer->mAPlayer = decoder;
1542        // configures the callback for the sink buffer queue
1543        decoder->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer);
1544        // configures the callback for the notifications coming from the SF code
1545        decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1546
1547        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
1548        case SL_DATALOCATOR_URI:
1549            decoder->setDataSource(
1550                    (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
1551            break;
1552        case SL_DATALOCATOR_ANDROIDFD: {
1553            int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1554            decoder->setDataSource(
1555                    (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
1556                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
1557                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1558                            (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1559            }
1560            break;
1561        default:
1562            SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
1563            break;
1564        }
1565
1566        object_unlock_exclusive(&pAudioPlayer->mObject);
1567        }
1568        break;
1569    //-----------------------------------
1570    // AacBqToPcmCbRenderer
1571    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
1572        object_lock_exclusive(&pAudioPlayer->mObject);
1573
1574        AudioPlayback_Parameters app;
1575        app.sessionId = pAudioPlayer->mSessionId;
1576        app.streamType = pAudioPlayer->mStreamType;
1577        app.trackcb = NULL;
1578        app.trackcbUser = NULL;
1579        android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app);
1580        // configures the callback for the sink buffer queue
1581        bqtobq->setDataPushListener(adecoder_writeToBufferQueue, (void*)pAudioPlayer);
1582        pAudioPlayer->mAPlayer = bqtobq;
1583        // configures the callback for the notifications coming from the SF code,
1584        // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
1585        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1586
1587        object_unlock_exclusive(&pAudioPlayer->mObject);
1588        }
1589        break;
1590    //-----------------------------------
1591    default:
1592        SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1593        result = SL_RESULT_INTERNAL_ERROR;
1594        break;
1595    }
1596
1597
1598    // proceed with effect initialization
1599    // initialize EQ
1600    // FIXME use a table of effect descriptors when adding support for more effects
1601    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
1602            sizeof(effect_uuid_t)) == 0) {
1603        SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1604        android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1605    }
1606    // initialize BassBoost
1607    if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
1608            sizeof(effect_uuid_t)) == 0) {
1609        SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1610        android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1611    }
1612    // initialize Virtualizer
1613    if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
1614               sizeof(effect_uuid_t)) == 0) {
1615        SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1616        android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1617    }
1618
1619    // initialize EffectSend
1620    // FIXME initialize EffectSend
1621
1622    return result;
1623}
1624
1625
1626//-----------------------------------------------------------------------------
1627/**
1628 * Called with a lock on AudioPlayer
1629 */
1630SLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
1631    SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
1632    SLresult result = SL_RESULT_SUCCESS;
1633
1634    if (pAudioPlayer->mAPlayer != 0) {
1635        pAudioPlayer->mAPlayer->preDestroy();
1636    }
1637    SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
1638
1639    object_unlock_exclusive(&pAudioPlayer->mObject);
1640    if (pAudioPlayer->mCallbackProtector != 0) {
1641        pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
1642    }
1643    object_lock_exclusive(&pAudioPlayer->mObject);
1644
1645    return result;
1646}
1647
1648
1649//-----------------------------------------------------------------------------
1650SLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1651    SLresult result = SL_RESULT_SUCCESS;
1652    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1653    switch (pAudioPlayer->mAndroidObjType) {
1654
1655    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1656        // We own the audio track for PCM buffer queue players
1657        if (pAudioPlayer->mAudioTrack != 0) {
1658            pAudioPlayer->mAudioTrack->stop();
1659            // Note that there may still be another reference in post-unlock phase of SetPlayState
1660            pAudioPlayer->mAudioTrack.clear();
1661        }
1662        break;
1663
1664    case AUDIOPLAYER_FROM_URIFD:     // intended fall-through
1665    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
1666    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
1667    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1668        pAudioPlayer->mAPlayer.clear();
1669        break;
1670    //-----------------------------------
1671    default:
1672        SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1673        result = SL_RESULT_INTERNAL_ERROR;
1674        break;
1675    }
1676
1677    pAudioPlayer->mCallbackProtector.clear();
1678
1679    // FIXME might not be needed
1680    pAudioPlayer->mAndroidObjType = INVALID_TYPE;
1681
1682    // explicit destructor
1683    pAudioPlayer->mAudioTrack.~sp();
1684    // note that SetPlayState(PLAYING) may still hold a reference
1685    pAudioPlayer->mCallbackProtector.~sp();
1686    pAudioPlayer->mAuxEffect.~sp();
1687    pAudioPlayer->mAPlayer.~sp();
1688
1689    if (pAudioPlayer->mpLock != NULL) {
1690        delete pAudioPlayer->mpLock;
1691        pAudioPlayer->mpLock = NULL;
1692    }
1693
1694    return result;
1695}
1696
1697
1698//-----------------------------------------------------------------------------
1699SLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
1700        SLuint32 constraints) {
1701    SLresult result = SL_RESULT_SUCCESS;
1702    switch(ap->mAndroidObjType) {
1703    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
1704        // these asserts were already checked by the platform-independent layer
1705        assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
1706                (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
1707        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
1708        // get the content sample rate
1709        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
1710        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
1711        if (ap->mAudioTrack != 0) {
1712            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
1713        }
1714        }
1715        break;
1716    case AUDIOPLAYER_FROM_URIFD:
1717        assert(rate == 1000);
1718        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
1719        // that was easy
1720        break;
1721
1722    default:
1723        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
1724        result = SL_RESULT_FEATURE_UNSUPPORTED;
1725        break;
1726    }
1727    return result;
1728}
1729
1730
1731//-----------------------------------------------------------------------------
1732// precondition
1733//  called with no lock held
1734//  ap != NULL
1735//  pItemCount != NULL
1736SLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
1737    if (ap->mAPlayer == 0) {
1738        return SL_RESULT_PARAMETER_INVALID;
1739    }
1740    switch(ap->mAndroidObjType) {
1741      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1742        {
1743            android::AudioSfDecoder* decoder =
1744                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1745            *pItemCount = decoder->getPcmFormatKeyCount();
1746        }
1747        break;
1748      default:
1749        *pItemCount = 0;
1750        break;
1751    }
1752    return SL_RESULT_SUCCESS;
1753}
1754
1755
1756//-----------------------------------------------------------------------------
1757// precondition
1758//  called with no lock held
1759//  ap != NULL
1760//  pKeySize != NULL
1761SLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
1762        SLuint32 index, SLuint32 *pKeySize) {
1763    if (ap->mAPlayer == 0) {
1764        return SL_RESULT_PARAMETER_INVALID;
1765    }
1766    SLresult res = SL_RESULT_SUCCESS;
1767    switch(ap->mAndroidObjType) {
1768      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1769        {
1770            android::AudioSfDecoder* decoder =
1771                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1772            SLuint32 keyNameSize = 0;
1773            if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
1774                res = SL_RESULT_PARAMETER_INVALID;
1775            } else {
1776                // *pKeySize is the size of the region used to store the key name AND
1777                //   the information about the key (size, lang, encoding)
1778                *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
1779            }
1780        }
1781        break;
1782      default:
1783        *pKeySize = 0;
1784        res = SL_RESULT_PARAMETER_INVALID;
1785        break;
1786    }
1787    return res;
1788}
1789
1790
1791//-----------------------------------------------------------------------------
1792// precondition
1793//  called with no lock held
1794//  ap != NULL
1795//  pKey != NULL
1796SLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
1797        SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
1798    if (ap->mAPlayer == 0) {
1799        return SL_RESULT_PARAMETER_INVALID;
1800    }
1801    SLresult res = SL_RESULT_SUCCESS;
1802    switch(ap->mAndroidObjType) {
1803      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1804        {
1805            android::AudioSfDecoder* decoder =
1806                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1807            if ((size < sizeof(SLMetadataInfo) ||
1808                    (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
1809                            (char*)pKey->data)))) {
1810                res = SL_RESULT_PARAMETER_INVALID;
1811            } else {
1812                // successfully retrieved the key value, update the other fields
1813                pKey->encoding = SL_CHARACTERENCODING_UTF8;
1814                memcpy((char *) pKey->langCountry, "en", 3);
1815                pKey->size = strlen((char*)pKey->data) + 1;
1816            }
1817        }
1818        break;
1819      default:
1820        res = SL_RESULT_PARAMETER_INVALID;
1821        break;
1822    }
1823    return res;
1824}
1825
1826
1827//-----------------------------------------------------------------------------
1828// precondition
1829//  called with no lock held
1830//  ap != NULL
1831//  pValueSize != NULL
1832SLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
1833        SLuint32 index, SLuint32 *pValueSize) {
1834    if (ap->mAPlayer == 0) {
1835        return SL_RESULT_PARAMETER_INVALID;
1836    }
1837    SLresult res = SL_RESULT_SUCCESS;
1838    switch(ap->mAndroidObjType) {
1839      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1840        {
1841            android::AudioSfDecoder* decoder =
1842                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1843            SLuint32 valueSize = 0;
1844            if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
1845                res = SL_RESULT_PARAMETER_INVALID;
1846            } else {
1847                // *pValueSize is the size of the region used to store the key value AND
1848                //   the information about the value (size, lang, encoding)
1849                *pValueSize = valueSize + sizeof(SLMetadataInfo);
1850            }
1851        }
1852        break;
1853      default:
1854          *pValueSize = 0;
1855          res = SL_RESULT_PARAMETER_INVALID;
1856          break;
1857    }
1858    return res;
1859}
1860
1861
1862//-----------------------------------------------------------------------------
1863// precondition
1864//  called with no lock held
1865//  ap != NULL
1866//  pValue != NULL
1867SLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
1868        SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
1869    if (ap->mAPlayer == 0) {
1870        return SL_RESULT_PARAMETER_INVALID;
1871    }
1872    SLresult res = SL_RESULT_SUCCESS;
1873    switch(ap->mAndroidObjType) {
1874      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1875        {
1876            android::AudioSfDecoder* decoder =
1877                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1878            pValue->encoding = SL_CHARACTERENCODING_BINARY;
1879            memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
1880            SLuint32 valueSize = 0;
1881            if ((size < sizeof(SLMetadataInfo)
1882                    || (!decoder->getPcmFormatValueSize(index, &valueSize))
1883                    || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
1884                            (SLuint32*)pValue->data)))) {
1885                res = SL_RESULT_PARAMETER_INVALID;
1886            } else {
1887                pValue->size = valueSize;
1888            }
1889        }
1890        break;
1891      default:
1892        res = SL_RESULT_PARAMETER_INVALID;
1893        break;
1894    }
1895    return res;
1896}
1897
1898//-----------------------------------------------------------------------------
1899// preconditions
1900//  ap != NULL
1901//  mutex is locked
1902//  play state has changed
1903void android_audioPlayer_setPlayState(CAudioPlayer *ap) {
1904
1905    SLuint32 playState = ap->mPlay.mState;
1906    AndroidObjectState objState = ap->mAndroidObjState;
1907
1908    switch(ap->mAndroidObjType) {
1909    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1910        switch (playState) {
1911        case SL_PLAYSTATE_STOPPED:
1912            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1913            if (ap->mAudioTrack != 0) {
1914                ap->mAudioTrack->stop();
1915            }
1916            break;
1917        case SL_PLAYSTATE_PAUSED:
1918            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1919            if (ap->mAudioTrack != 0) {
1920                ap->mAudioTrack->pause();
1921            }
1922            break;
1923        case SL_PLAYSTATE_PLAYING:
1924            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1925            if (ap->mAudioTrack != 0) {
1926                // instead of ap->mAudioTrack->start();
1927                ap->mDeferredStart = true;
1928            }
1929            break;
1930        default:
1931            // checked by caller, should not happen
1932            break;
1933        }
1934        break;
1935
1936    case AUDIOPLAYER_FROM_URIFD:      // intended fall-through
1937    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
1938    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
1939    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1940        // FIXME report and use the return code to the lock mechanism, which is where play state
1941        //   changes are updated (see object_unlock_exclusive_attributes())
1942        aplayer_setPlayState(ap->mAPlayer, playState, &(ap->mAndroidObjState));
1943        break;
1944    default:
1945        SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
1946        break;
1947    }
1948}
1949
1950
1951//-----------------------------------------------------------------------------
1952// call when either player event flags, marker position, or position update period changes
1953void android_audioPlayer_useEventMask(CAudioPlayer *ap) {
1954    IPlay *pPlayItf = &ap->mPlay;
1955    SLuint32 eventFlags = pPlayItf->mEventFlags;
1956    /*switch(ap->mAndroidObjType) {
1957    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
1958
1959    if (ap->mAPlayer != 0) {
1960        assert(ap->mAudioTrack == 0);
1961        ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
1962                (int32_t) pPlayItf->mPositionUpdatePeriod);
1963        return;
1964    }
1965
1966    if (ap->mAudioTrack == 0) {
1967        return;
1968    }
1969
1970    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1971        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1972                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1973    } else {
1974        // clear marker
1975        ap->mAudioTrack->setMarkerPosition(0);
1976    }
1977
1978    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1979         ap->mAudioTrack->setPositionUpdatePeriod(
1980                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
1981                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1982    } else {
1983        // clear periodic update
1984        ap->mAudioTrack->setPositionUpdatePeriod(0);
1985    }
1986
1987    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
1988        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
1989    }
1990
1991    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
1992        // FIXME support SL_PLAYEVENT_HEADMOVING
1993        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
1994            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
1995    }
1996    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
1997        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
1998    }
1999
2000}
2001
2002
2003//-----------------------------------------------------------------------------
2004SLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
2005    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2006    switch(ap->mAndroidObjType) {
2007
2008      case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
2009      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
2010        int32_t durationMsec = ANDROID_UNKNOWN_TIME;
2011        if (ap->mAPlayer != 0) {
2012            ap->mAPlayer->getDurationMsec(&durationMsec);
2013        }
2014        *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
2015        break;
2016      }
2017
2018      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
2019      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:       // intended fall-through
2020      default: {
2021        *pDurMsec = SL_TIME_UNKNOWN;
2022      }
2023    }
2024    return SL_RESULT_SUCCESS;
2025}
2026
2027
2028//-----------------------------------------------------------------------------
2029void android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
2030    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
2031    switch(ap->mAndroidObjType) {
2032
2033      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2034        if ((ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) || (ap->mAudioTrack == 0)) {
2035            *pPosMsec = 0;
2036        } else {
2037            uint32_t positionInFrames;
2038            ap->mAudioTrack->getPosition(&positionInFrames);
2039            *pPosMsec = ((int64_t)positionInFrames * 1000) /
2040                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
2041        }
2042        break;
2043
2044      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
2045      case AUDIOPLAYER_FROM_URIFD:                    // intended fall-through
2046      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
2047        int32_t posMsec = ANDROID_UNKNOWN_TIME;
2048        if (ap->mAPlayer != 0) {
2049            ap->mAPlayer->getPositionMsec(&posMsec);
2050        }
2051        *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
2052        break;
2053      }
2054
2055      default:
2056        *pPosMsec = 0;
2057    }
2058}
2059
2060
2061//-----------------------------------------------------------------------------
2062void android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
2063
2064    switch(ap->mAndroidObjType) {
2065
2066      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
2067      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2068        break;
2069
2070      case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
2071      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2072        if (ap->mAPlayer != 0) {
2073            ap->mAPlayer->seek(posMsec);
2074        }
2075        break;
2076
2077      default:
2078        break;
2079    }
2080}
2081
2082
2083//-----------------------------------------------------------------------------
2084void android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
2085
2086    if ((AUDIOPLAYER_FROM_URIFD == ap->mAndroidObjType) && (ap->mAPlayer != 0)) {
2087        ap->mAPlayer->loop((bool)loopEnable);
2088    }
2089}
2090
2091
2092//-----------------------------------------------------------------------------
2093SLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
2094        SLpermille threshold) {
2095    SLresult result = SL_RESULT_SUCCESS;
2096
2097    switch (ap->mAndroidObjType) {
2098      case AUDIOPLAYER_FROM_URIFD:
2099        if (ap->mAPlayer != 0) {
2100            ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
2101        }
2102        break;
2103
2104      default: {}
2105    }
2106
2107    return result;
2108}
2109
2110
2111//-----------------------------------------------------------------------------
2112void android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
2113    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
2114    // queue was stopped when the queue become empty, we restart as soon as a new buffer
2115    // has been enqueued since we're in playing state
2116    if (ap->mAudioTrack != 0) {
2117        // instead of ap->mAudioTrack->start();
2118        ap->mDeferredStart = true;
2119    }
2120
2121    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
2122    // has received new data, signal it has sufficient data
2123    if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
2124        // we wouldn't have been called unless we were previously in the underflow state
2125        assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
2126        assert(0 == ap->mPrefetchStatus.mLevel);
2127        ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2128        ap->mPrefetchStatus.mLevel = 1000;
2129        // callback or no callback?
2130        SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
2131                (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
2132        if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
2133            ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
2134            ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
2135            ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
2136        }
2137    }
2138}
2139
2140
2141//-----------------------------------------------------------------------------
2142/*
2143 * BufferQueue::Clear
2144 */
2145SLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
2146    SLresult result = SL_RESULT_SUCCESS;
2147
2148    switch (ap->mAndroidObjType) {
2149    //-----------------------------------
2150    // AudioTrack
2151    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2152        if (ap->mAudioTrack != 0) {
2153            ap->mAudioTrack->flush();
2154        }
2155        break;
2156    default:
2157        result = SL_RESULT_INTERNAL_ERROR;
2158        break;
2159    }
2160
2161    return result;
2162}
2163
2164
2165//-----------------------------------------------------------------------------
2166SLresult android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) {
2167    SLresult result = SL_RESULT_SUCCESS;
2168    assert(ap->mAPlayer != 0);
2169    switch (ap->mAndroidObjType) {
2170      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
2171          android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2172          splr->registerQueueCallback(
2173                  (const void*)ap /*user*/, true /*userIsAudioPlayer*/,
2174                  ap->mAndroidBufferQueue.mContext /*context*/,
2175                  (const void*)&(ap->mAndroidBufferQueue.mItf) /*caller*/);
2176        } break;
2177      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
2178          android::AacBqToPcmCbRenderer* dec =
2179                  static_cast<android::AacBqToPcmCbRenderer*>(ap->mAPlayer.get());
2180          dec->registerSourceQueueCallback((const void*)ap /*user*/,
2181                  ap->mAndroidBufferQueue.mContext /*context*/,
2182                  (const void*)&(ap->mAndroidBufferQueue.mItf) /*caller*/);
2183        } break;
2184      default:
2185        SL_LOGE("Error registering AndroidBufferQueue callback: unexpected object type %d",
2186                ap->mAndroidObjType);
2187        result = SL_RESULT_INTERNAL_ERROR;
2188        break;
2189    }
2190    return result;
2191}
2192
2193//-----------------------------------------------------------------------------
2194void android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
2195    if ((ap->mAndroidObjType == AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) && (ap->mAPlayer != 0)) {
2196        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2197        splr->appClear_l();
2198    }
2199}
2200
2201void android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
2202    if ((ap->mAndroidObjType == AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE) && (ap->mAPlayer != 0)) {
2203        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2204        splr->queueRefilled_l();
2205    }
2206}
2207