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