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