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