1dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi/*
2dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
3dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi *
4dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * you may not use this file except in compliance with the License.
6dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * You may obtain a copy of the License at
7dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi *
8dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi *
10dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * See the License for the specific language governing permissions and
14dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi * limitations under the License.
15dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi */
16dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
17333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi//#define USE_LOG SLAndroidLogLevel_Verbose
18dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
19dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi#include "sles_allinclusive.h"
20d004feb25e830dd92a8d6e6af0d363e4d11721a2Jean-Michel Trivi#include "android/android_AudioSfDecoder.h"
21dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
2294d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi#include <binder/IServiceManager.h>
238ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#include <media/stagefright/foundation/ADebug.h>
248ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
258ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
268ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#define SIZE_CACHED_HIGH_BYTES 1000000
278ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#define SIZE_CACHED_MED_BYTES   700000
288ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#define SIZE_CACHED_LOW_BYTES   400000
298ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
30dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivinamespace android {
31dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
32dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
33dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel TriviAudioSfDecoder::AudioSfDecoder(const AudioPlayback_Parameters* params) : GenericPlayer(params),
344639bda67e9b7b93d87c42c3321787dd45df0f0dJean-Michel Trivi        mDataSource(0),
354639bda67e9b7b93d87c42c3321787dd45df0f0dJean-Michel Trivi        mAudioSource(0),
361209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        mAudioSourceStarted(false),
37dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mBitrate(-1),
387a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        mDurationUsec(ANDROID_UNKNOWN_TIME),
39dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mDecodeBuffer(NULL),
40dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mSeekTimeMsec(0),
41332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten        // play event logic depends on the initial time being zero not ANDROID_UNKNOWN_TIME
42332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten        mLastDecodedPositionUs(0)
43dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi{
44347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    SL_LOGD("AudioSfDecoder::AudioSfDecoder()");
45dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
46dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
47dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
48dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel TriviAudioSfDecoder::~AudioSfDecoder() {
49347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    SL_LOGD("AudioSfDecoder::~AudioSfDecoder()");
501209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi}
511209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
521209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
531209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivivoid AudioSfDecoder::preDestroy() {
541209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    GenericPlayer::preDestroy();
551209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    SL_LOGD("AudioSfDecoder::preDestroy()");
561209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    {
571209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        Mutex::Autolock _l(mBufferSourceLock);
581209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
591209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        if (NULL != mDecodeBuffer) {
601209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            mDecodeBuffer->release();
611209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            mDecodeBuffer = NULL;
621209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        }
631209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
641209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        if ((mAudioSource != 0) && mAudioSourceStarted) {
651209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            mAudioSource->stop();
661209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            mAudioSourceStarted = false;
671209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        }
684639bda67e9b7b93d87c42c3321787dd45df0f0dJean-Michel Trivi    }
69dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
70dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
71dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
72dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi//--------------------------------------------------
73dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::play() {
74347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    SL_LOGD("AudioSfDecoder::play");
75dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
76dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    GenericPlayer::play();
77dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    (new AMessage(kWhatDecode, id()))->post();
78dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
79dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
80dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
817a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivivoid AudioSfDecoder::getPositionMsec(int* msec) {
827a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    int64_t timeUsec = getPositionUsec();
837a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    if (timeUsec == ANDROID_UNKNOWN_TIME) {
847a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        *msec = ANDROID_UNKNOWN_TIME;
857a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    } else {
86a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten        *msec = timeUsec / 1000;
877a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    }
887a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi}
897a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi
907a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi
91dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi//--------------------------------------------------
92bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kastenuint32_t AudioSfDecoder::getPcmFormatKeyCount() const {
93bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    return NB_PCMMETADATA_KEYS;
94be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi}
95be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
96be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
97be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi//--------------------------------------------------
98be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivibool AudioSfDecoder::getPcmFormatKeySize(uint32_t index, uint32_t* pKeySize) {
99bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    if (index >= NB_PCMMETADATA_KEYS) {
100be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
101be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    } else {
102be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        *pKeySize = strlen(kPcmDecodeMetadataKeys[index]) +1;
103be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return true;
104be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
105be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi}
106be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
107be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
108be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi//--------------------------------------------------
109be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivibool AudioSfDecoder::getPcmFormatKeyName(uint32_t index, uint32_t keySize, char* keyName) {
110be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    uint32_t actualKeySize;
111be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    if (!getPcmFormatKeySize(index, &actualKeySize)) {
112be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
113be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
114be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    if (keySize < actualKeySize) {
115be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
116be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
117be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    strncpy(keyName, kPcmDecodeMetadataKeys[index], actualKeySize);
118be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    return true;
119be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi}
120be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
121be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
122be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi//--------------------------------------------------
123be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivibool AudioSfDecoder::getPcmFormatValueSize(uint32_t index, uint32_t* pValueSize) {
124bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    if (index >= NB_PCMMETADATA_KEYS) {
125be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        *pValueSize = 0;
126be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
127be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    } else {
128be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        *pValueSize = sizeof(uint32_t);
129be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return true;
130be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
131be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi}
132be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
133be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
134be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi//--------------------------------------------------
135be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivibool AudioSfDecoder::getPcmFormatKeyValue(uint32_t index, uint32_t size, uint32_t* pValue) {
136be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    uint32_t valueSize = 0;
137be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    if (!getPcmFormatValueSize(index, &valueSize)) {
138be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
13956d72f3683268937c92786b35532729e1e54cf80Jean-Michel Trivi    } else if (size != valueSize) {
140be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        // this ensures we are accessing mPcmFormatValues with a valid size for that index
14156d72f3683268937c92786b35532729e1e54cf80Jean-Michel Trivi        SL_LOGE("Error retrieving metadata value at index %d: using size of %d, should be %d",
14256d72f3683268937c92786b35532729e1e54cf80Jean-Michel Trivi                index, size, valueSize);
143be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return false;
144be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    } else {
145bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten        android::Mutex::Autolock autoLock(mPcmFormatLock);
146be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        *pValue = mPcmFormatValues[index];
147be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi        return true;
148be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
149be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi}
150be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
151be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
152be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi//--------------------------------------------------
153dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi// Event handlers
1541209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi//  it is strictly verboten to call those methods outside of the event loop
1551209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
1561209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi// Initializes the data and audio sources, and update the PCM format info
1571209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi// post-condition: upon successful initialization based on the player data locator
1581209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi//    GenericPlayer::onPrepare() was called
1591209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi//    mDataSource != 0
1601209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi//    mAudioSource != 0
1611209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi//    mAudioSourceStarted == true
16249cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten// All error returns from this method are via notifyPrepared(status) followed by "return".
163dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onPrepare() {
16430ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("AudioSfDecoder::onPrepare()");
1651209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    Mutex::Autolock _l(mBufferSourceLock);
166dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
167bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    {
168bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    android::Mutex::Autolock autoLock(mPcmFormatLock);
1691209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    // Initialize the PCM format info with the known parameters before the start of the decode
170be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_BITSPERSAMPLE] = SL_PCMSAMPLEFORMAT_FIXED_16;
171be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CONTAINERSIZE] = 16;
172be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_ENDIANNESS] = SL_BYTEORDER_LITTLEENDIAN;
1731209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    //    initialization with the default values: they will be replaced by the actual values
1741209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    //      once the decoder has figured them out
175e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = UNKNOWN_NUMCHANNELS;
176e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = UNKNOWN_SAMPLERATE;
177e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] = UNKNOWN_CHANNELMASK;
178bf02afef1224b349d396d34c7a97bc5dd7e97f37Glenn Kasten    }
179be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
1801209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    //---------------------------------
1811209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    // Instantiate and initialize the data source for the decoder
182dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<DataSource> dataSource;
183dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
184dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    switch (mDataLocatorType) {
185dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
186dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    case kDataLocatorNone:
187dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGE("AudioSfDecoder::onPrepare: no data locator set");
188dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyPrepared(MEDIA_ERROR_BASE);
189dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
190dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
191dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    case kDataLocatorUri:
19240c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi        dataSource = DataSource::CreateFromURI(mDataLocator.uriRef);
19340c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi        if (dataSource == NULL) {
19440c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi            SL_LOGE("AudioSfDecoder::onPrepare(): Error opening %s", mDataLocator.uriRef);
195dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            notifyPrepared(MEDIA_ERROR_BASE);
196dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            return;
197dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
198dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        break;
199dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
20040c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi    case kDataLocatorFd:
20140c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi    {
202d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        // As FileSource unconditionally takes ownership of the fd and closes it, then
203d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        // we have to make a dup for FileSource if the app wants to keep ownership itself
204d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        int fd = mDataLocator.fdi.fd;
205d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        if (mDataLocator.fdi.mCloseAfterUse) {
206d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten            mDataLocator.fdi.mCloseAfterUse = false;
207d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        } else {
208d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten            fd = ::dup(fd);
209d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        }
210d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        dataSource = new FileSource(fd, mDataLocator.fdi.offset, mDataLocator.fdi.length);
211dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        status_t err = dataSource->initCheck();
212dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (err != OK) {
213dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            notifyPrepared(err);
214dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            return;
215dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
21640c08fcbfac815da96c2db0a0586fd5b12bc0a5fJean-Michel Trivi        break;
217dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
218dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
219dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    default:
220dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        TRESPASS();
221dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
222dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
2231209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    //---------------------------------
2241209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    // Instanciate and initialize the decoder attached to the data source
225dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
226dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (extractor == NULL) {
227dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate extractor.");
228dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyPrepared(ERROR_UNSUPPORTED);
229dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
230dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
231dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
232dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    ssize_t audioTrackIndex = -1;
233dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    bool isRawAudio = false;
234dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    for (size_t i = 0; i < extractor->countTracks(); ++i) {
235dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        sp<MetaData> meta = extractor->getTrackMetaData(i);
236dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
237dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        const char *mime;
238dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        CHECK(meta->findCString(kKeyMIMEType, &mime));
239dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
240dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (!strncasecmp("audio/", mime, 6)) {
241c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi            if (isSupportedCodec(mime)) {
242c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi                audioTrackIndex = i;
243dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
244c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
245c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi                    isRawAudio = true;
246c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi                }
247c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi                break;
248dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            }
249dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
250dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
251dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
252dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (audioTrackIndex < 0) {
253dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGE("AudioSfDecoder::onPrepare: Could not find a supported audio track.");
254dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyPrepared(ERROR_UNSUPPORTED);
255dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
256dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
257dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
258dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<MediaSource> source = extractor->getTrack(audioTrackIndex);
259dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<MetaData> meta = source->getFormat();
260dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
261347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    // we can't trust the OMXCodec (if there is one) to issue a INFO_FORMAT_CHANGED so we want
262347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    // to have some meaningful values as soon as possible.
263e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    int32_t channelCount;
264e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    bool hasChannelCount = meta->findInt32(kKeyChannelCount, &channelCount);
265347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    int32_t sr;
266347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    bool hasSampleRate = meta->findInt32(kKeySampleRate, &sr);
267be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi
268891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten    // first compute the duration
269dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    off64_t size;
270dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    int64_t durationUs;
271891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten    int32_t durationMsec;
272dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (dataSource->getSize(&size) == OK
273dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            && meta->findInt64(kKeyDuration, &durationUs)) {
2747a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        if (durationUs != 0) {
2757a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            mBitrate = size * 8000000ll / durationUs;  // in bits/sec
2767a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        } else {
2777a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            mBitrate = -1;
2787a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        }
279dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mDurationUsec = durationUs;
280891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten        durationMsec = durationUs / 1000;
281dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    } else {
282dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mBitrate = -1;
2837a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        mDurationUsec = ANDROID_UNKNOWN_TIME;
284891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten        durationMsec = ANDROID_UNKNOWN_TIME;
285891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten    }
286891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten
287891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten    // then assign the duration under the settings lock
288891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten    {
289891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten        Mutex::Autolock _l(mSettingsLock);
290891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten        mDurationMsec = durationMsec;
291dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
292dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
2931209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    // the audio content is not raw PCM, so we need a decoder
294dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (!isRawAudio) {
295dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        OMXClient client;
296dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        CHECK_EQ(client.connect(), (status_t)OK);
297dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
298dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        source = OMXCodec::Create(
299dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                client.interface(), meta, false /* createEncoder */,
300dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                source);
301dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
302dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (source == NULL) {
303dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate decoder.");
304dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            notifyPrepared(ERROR_UNSUPPORTED);
305dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            return;
306dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
307dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
308dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        meta = source->getFormat();
309dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
310dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
311dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
312dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (source->start() != OK) {
313dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGE("AudioSfDecoder::onPrepare: Failed to start source/decoder.");
314dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyPrepared(MEDIA_ERROR_BASE);
315dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
316dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
317dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
3181209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    //---------------------------------
3191209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    // The data source, and audio source (a decoder if required) are ready to be used
320dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    mDataSource = dataSource;
321dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    mAudioSource = source;
3221209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    mAudioSourceStarted = true;
323dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
324be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    if (!hasChannelCount) {
325e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        CHECK(meta->findInt32(kKeyChannelCount, &channelCount));
326be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    }
327347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
328347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    if (!hasSampleRate) {
329347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        CHECK(meta->findInt32(kKeySampleRate, &sr));
330347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    }
331be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    // FIXME add code below once channel mask support is in, currently initialized to default
3329923b038db25831fdb481e73e90374f57fd4c871Glenn Kasten    //       value computed from the channel count
3339923b038db25831fdb481e73e90374f57fd4c871Glenn Kasten    //    if (!hasChannelMask) {
334e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    //        CHECK(meta->findInt32(kKeyChannelMask, &channelMask));
335be91f6328a084475e1cf58b54b8b732e088940b5Jean-Michel Trivi    //    }
336dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
337dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (!wantPrefetch()) {
338dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("AudioSfDecoder::onPrepare: no need to prefetch");
339dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        // doesn't need prefetching, notify good to go
340dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mCacheStatus = kStatusHigh;
341dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mCacheFill = 1000;
342dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyStatus();
343dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyCacheFill();
344dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
345dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
346347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    {
347347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        android::Mutex::Autolock autoLock(mPcmFormatLock);
348e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = sr;
349e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = channelCount;
350e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] =
351e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten                channelCountToMask(channelCount);
352347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    }
353347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
354dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    // at this point we have enough information about the source to create the sink that
355dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    // will consume the data
356dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    createAudioSink();
357dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
35849cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    // signal successful completion of prepare
35949cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    mStateFlags |= kFlagPrepared;
360333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi
361dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    GenericPlayer::onPrepare();
36230ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("AudioSfDecoder::onPrepare() done, mStateFlags=0x%x", mStateFlags);
363dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
364dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
365dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
366dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onPause() {
367347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    SL_LOGV("AudioSfDecoder::onPause()");
368dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    GenericPlayer::onPause();
369dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    pauseAudioSink();
370dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
371dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
372dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
373dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onPlay() {
374347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    SL_LOGV("AudioSfDecoder::onPlay()");
375dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    GenericPlayer::onPlay();
376dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    startAudioSink();
377dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
378dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
379dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
380dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onSeek(const sp<AMessage> &msg) {
381dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    SL_LOGV("AudioSfDecoder::onSeek");
382dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    int64_t timeMsec;
383dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    CHECK(msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec));
384dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
3857a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    Mutex::Autolock _l(mTimeLock);
386dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    mStateFlags |= kFlagSeeking;
387dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    mSeekTimeMsec = timeMsec;
388332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    // don't set mLastDecodedPositionUs to ANDROID_UNKNOWN_TIME; getPositionUsec
389332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    // ignores mLastDecodedPositionUs while seeking, and substitutes the seek goal instead
390332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten
391332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    // nop for now
392332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    GenericPlayer::onSeek(msg);
393dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
394dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
395dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
396dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onLoop(const sp<AMessage> &msg) {
397dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    SL_LOGV("AudioSfDecoder::onLoop");
398dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    int32_t loop;
399dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    CHECK(msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop));
400dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
401dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (loop) {
402dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        //SL_LOGV("AudioSfDecoder::onLoop start looping");
403dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mStateFlags |= kFlagLooping;
404dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    } else {
405dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        //SL_LOGV("AudioSfDecoder::onLoop stop looping");
406dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mStateFlags &= ~kFlagLooping;
407dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
408332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten
409332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    // nop for now
410332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten    GenericPlayer::onLoop(msg);
411dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
412dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
413dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
414dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onCheckCache(const sp<AMessage> &msg) {
415dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //SL_LOGV("AudioSfDecoder::onCheckCache");
416dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    bool eos;
4178ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CacheStatus_t status = getCacheRemaining(&eos);
418dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
419dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (eos || status == kStatusHigh
420dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            || ((mStateFlags & kFlagPreparing) && (status >= kStatusEnough))) {
421dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mStateFlags & kFlagPlaying) {
422dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            startAudioSink();
423dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
424dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mStateFlags &= ~kFlagBuffering;
425dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
426dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("AudioSfDecoder::onCheckCache: buffering done.");
427dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
428dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mStateFlags & kFlagPreparing) {
429dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //SL_LOGV("AudioSfDecoder::onCheckCache: preparation done.");
430dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            mStateFlags &= ~kFlagPreparing;
431dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
432dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
433dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mStateFlags & kFlagPlaying) {
434dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            (new AMessage(kWhatDecode, id()))->post();
435dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
436dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
437dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
438dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
439dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    msg->post(100000);
440dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
441dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
442dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
443dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onDecode() {
444dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    SL_LOGV("AudioSfDecoder::onDecode");
445dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
446dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //-------------------------------- Need to buffer some more before decoding?
447dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    bool eos;
448dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (mDataSource == 0) {
449dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        // application set play state to paused which failed, then set play state to playing
450dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
451dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
4521209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
453dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (wantPrefetch()
454dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            && (getCacheRemaining(&eos) == kStatusLow)
455dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            && !eos) {
456dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("buffering more.");
457dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
458dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mStateFlags & kFlagPlaying) {
459dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            pauseAudioSink();
460dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
461dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mStateFlags |= kFlagBuffering;
462dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        (new AMessage(kWhatCheckCache, id()))->post(100000);
463dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
464dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
465dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
466dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (!(mStateFlags & (kFlagPlaying | kFlagBuffering | kFlagPreparing))) {
467dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        // don't decode if we're not buffering, prefetching or playing
468dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        //SL_LOGV("don't decode: not buffering, prefetching or playing");
469dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return;
470dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
471dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
472dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //-------------------------------- Decode
473dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    status_t err;
474dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    MediaSource::ReadOptions readOptions;
475dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (mStateFlags & kFlagSeeking) {
4767a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        assert(mSeekTimeMsec != ANDROID_UNKNOWN_TIME);
477dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        readOptions.setSeekTo(mSeekTimeMsec * 1000);
478dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
479dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
4807a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    int64_t timeUsec = ANDROID_UNKNOWN_TIME;
481dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    {
4821209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        Mutex::Autolock _l(mBufferSourceLock);
4831209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi
484dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (NULL != mDecodeBuffer) {
485dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            // the current decoded buffer hasn't been rendered, drop it
486dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            mDecodeBuffer->release();
487dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            mDecodeBuffer = NULL;
488dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
4891209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        if(!mAudioSourceStarted) {
4901209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            return;
4911209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        }
492dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        err = mAudioSource->read(&mDecodeBuffer, &readOptions);
493dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (err == OK) {
494456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten            // FIXME workaround apparent bug in AAC decoder: kKeyTime is 3 frames old if length is 0
495456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten            if (mDecodeBuffer->range_length() == 0) {
496456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten                timeUsec = ANDROID_UNKNOWN_TIME;
497456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten            } else {
498456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten                CHECK(mDecodeBuffer->meta_data()->findInt64(kKeyTime, &timeUsec));
499456ab720f41efee12ca572475fbe3ade530b5aa0Glenn Kasten            }
500dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
501dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
502dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
503dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    {
5047a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        Mutex::Autolock _l(mTimeLock);
505dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mStateFlags & kFlagSeeking) {
506dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            mStateFlags &= ~kFlagSeeking;
5077a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            mSeekTimeMsec = ANDROID_UNKNOWN_TIME;
5087a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        }
5097a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi        if (timeUsec != ANDROID_UNKNOWN_TIME) {
510becfe88080f47bce3206836abf738ffddeb5cc47Glenn Kasten            // Note that though we've decoded this position, we haven't rendered it yet.
511becfe88080f47bce3206836abf738ffddeb5cc47Glenn Kasten            // So a GetPosition called after this point will observe the advanced position,
512becfe88080f47bce3206836abf738ffddeb5cc47Glenn Kasten            // even though the PCM may not have been supplied to the sink.  That's OK as
513becfe88080f47bce3206836abf738ffddeb5cc47Glenn Kasten            // we don't claim to provide frame-accurate (let alone sample-accurate) GetPosition.
5147a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            mLastDecodedPositionUs = timeUsec;
515dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
516dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
517dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
518dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //-------------------------------- Handle return of decode
519dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (err != OK) {
520dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        bool continueDecoding = false;
521dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        switch(err) {
522dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            case ERROR_END_OF_STREAM:
523dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                if (0 < mDurationUsec) {
5247a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                    Mutex::Autolock _l(mTimeLock);
525dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                    mLastDecodedPositionUs = mDurationUsec;
526dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                }
527dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                // handle notification and looping at end of stream
528dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                if (mStateFlags & kFlagPlaying) {
529dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                    notify(PLAYEREVENT_ENDOFSTREAM, 1, true);
530dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                }
531dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                if (mStateFlags & kFlagLooping) {
532dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                    seek(0);
533dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                    // kick-off decoding again
534dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                    continueDecoding = true;
535dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                }
536dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                break;
537dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            case INFO_FORMAT_CHANGED:
53830ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi                SL_LOGD("MediaSource::read encountered INFO_FORMAT_CHANGED");
539dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                // reconfigure output
540347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi                {
541347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi                    Mutex::Autolock _l(mBufferSourceLock);
542347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi                    hasNewDecodeParams();
543347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi                }
544dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                continueDecoding = true;
545dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                break;
546dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            case INFO_DISCONTINUITY:
54730ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi                SL_LOGD("MediaSource::read encountered INFO_DISCONTINUITY");
548dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                continueDecoding = true;
549dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                break;
550dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            default:
551dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                SL_LOGE("MediaSource::read returned error %d", err);
552dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                break;
553dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
554dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (continueDecoding) {
555dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            if (NULL == mDecodeBuffer) {
556dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                (new AMessage(kWhatDecode, id()))->post();
557dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                return;
558dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            }
559dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        } else {
560dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            return;
561dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
562dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
563dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
564dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //-------------------------------- Render
565dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<AMessage> msg = new AMessage(kWhatRender, id());
566dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    msg->post();
567dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
568dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
569dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
570dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
571dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onMessageReceived(const sp<AMessage> &msg) {
572dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    switch (msg->what()) {
573dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        case kWhatDecode:
574dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            onDecode();
575dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            break;
576dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
577dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        case kWhatRender:
578dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            onRender();
579dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            break;
580dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
581dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        case kWhatCheckCache:
582dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            onCheckCache(msg);
583dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            break;
584dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
585dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        default:
586dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            GenericPlayer::onMessageReceived(msg);
587dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            break;
588dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
589dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
590dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
591dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi//--------------------------------------------------
592dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi// Prepared state, prefetch status notifications
593dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::notifyPrepared(status_t prepareRes) {
59449cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    assert(!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully)));
59549cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    if (NO_ERROR == prepareRes) {
59649cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten        // The "then" fork is not currently used, but is kept here to make it easier
59749cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten        // to replace by a new signalPrepareCompletion(status) if we re-visit this later.
59849cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten        mStateFlags |= kFlagPrepared;
59949cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    } else {
60049cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten        mStateFlags |= kFlagPreparedUnsuccessfully;
60149cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    }
60249cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    // Do not call the superclass onPrepare to notify, because it uses a default error
60349cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    // status code but we can provide a more specific one.
60449cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    // GenericPlayer::onPrepare();
605dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    notify(PLAYEREVENT_PREPARED, (int32_t)prepareRes, true);
60649cfc9858d3a610b52e3e6b2fc1733888f7743f5Glenn Kasten    SL_LOGD("AudioSfDecoder::onPrepare() done, mStateFlags=0x%x", mStateFlags);
607dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
608dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
609dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
610dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivivoid AudioSfDecoder::onNotify(const sp<AMessage> &msg) {
6111209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    notif_cbf_t notifyClient;
6121209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    void*       notifyUser;
6131209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi    {
6141209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        android::Mutex::Autolock autoLock(mNotifyClientLock);
6151209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        if (NULL == mNotifyClient) {
6161209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            return;
6171209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        } else {
6181209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            notifyClient = mNotifyClient;
6191209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi            notifyUser   = mNotifyUser;
6201209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        }
621dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
622dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    int32_t val;
623dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val)) {
624dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val);
6251209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        notifyClient(kEventPrefetchStatusChange, val, 0, notifyUser);
626dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
627dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val)) {
628dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val);
6291209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        notifyClient(kEventPrefetchFillLevelUpdate, val, 0, notifyUser);
630dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
631dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val)) {
632dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val);
6331209c173a13a62d0f7d9f1d605e3665a5818fa90Jean-Michel Trivi        notifyClient(kEventEndOfStream, val, 0, notifyUser);
634dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
635dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    else {
636dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        GenericPlayer::onNotify(msg);
637dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
638dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
639dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
640dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
641dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi//--------------------------------------------------
642dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi// Private utility functions
643dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
644dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivibool AudioSfDecoder::wantPrefetch() {
6455afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi    if (mDataSource != 0) {
6465afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        return (mDataSource->flags() & DataSource::kWantsPrefetching);
6475afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi    } else {
6485afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        // happens if an improper data locator was passed, if the media extractor couldn't be
6495afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        //  initialized, if there is no audio track in the media, if the OMX decoder couldn't be
6505afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        //  instantiated, if the source couldn't be opened, or if the MediaSource
6515afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        //  couldn't be started
6525afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        SL_LOGV("AudioSfDecoder::wantPrefetch() tries to access NULL mDataSource");
6535afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi        return false;
6545afa50bca331f7ac29002f97421abf276919f2d6Jean-Michel Trivi    }
655dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
656dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
657dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
658dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Triviint64_t AudioSfDecoder::getPositionUsec() {
6597a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi    Mutex::Autolock _l(mTimeLock);
660dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (mStateFlags & kFlagSeeking) {
661dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        return mSeekTimeMsec * 1000;
662dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    } else {
663332b3a2a95b76ea90ce23be0b48403a9dd88c1b3Glenn Kasten        return mLastDecodedPositionUs;
664dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
665dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
666dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
667dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
6688ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel TriviCacheStatus_t AudioSfDecoder::getCacheRemaining(bool *eos) {
669dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    sp<NuCachedSource2> cachedSource =
670dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        static_cast<NuCachedSource2 *>(mDataSource.get());
671dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
6728ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    CacheStatus_t oldStatus = mCacheStatus;
673dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
674dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    status_t finalStatus;
675dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    size_t dataRemaining = cachedSource->approxDataRemaining(&finalStatus);
676dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    *eos = (finalStatus != OK);
677dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
678dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    CHECK_GE(mBitrate, 0);
679dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
680dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    int64_t dataRemainingUs = dataRemaining * 8000000ll / mBitrate;
681dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //SL_LOGV("AudioSfDecoder::getCacheRemaining: approx %.2f secs remaining (eos=%d)",
682dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    //       dataRemainingUs / 1E6, *eos);
683dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
684dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (*eos) {
685dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        // data is buffered up to the end of the stream, it can't get any better than this
686dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mCacheStatus = kStatusHigh;
687dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        mCacheFill = 1000;
688dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
689dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    } else {
690dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        if (mDurationUsec > 0) {
691dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            // known duration:
692dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
693dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //   fill level is ratio of how much has been played + how much is
694dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //   cached, divided by total duration
695dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            uint32_t currentPositionUsec = getPositionUsec();
6967a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            if (currentPositionUsec == ANDROID_UNKNOWN_TIME) {
6977a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                // if we don't know where we are, assume the worst for the fill ratio
6987a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                currentPositionUsec = 0;
6997a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            }
7007a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            if (mDurationUsec > 0) {
7017a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                mCacheFill = (int16_t) ((1000.0
7027a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                        * (double)(currentPositionUsec + dataRemainingUs) / mDurationUsec));
7037a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            } else {
7047a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi                mCacheFill = 0;
7057a114799472e645dbd4061ff5bed793fd6d8e84fJean-Michel Trivi            }
706dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //SL_LOGV("cacheFill = %d", mCacheFill);
707dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
708dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //   cache status is evaluated against duration thresholds
7098ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            if (dataRemainingUs > DURATION_CACHED_HIGH_MS*1000) {
710dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusHigh;
711dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                //LOGV("high");
7128ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            } else if (dataRemainingUs > DURATION_CACHED_MED_MS*1000) {
713dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                //LOGV("enough");
714dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusEnough;
7158ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            } else if (dataRemainingUs < DURATION_CACHED_LOW_MS*1000) {
716dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                //LOGV("low");
717dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusLow;
718dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            } else {
719dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusIntermediate;
720dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            }
721dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
722dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        } else {
723dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            // unknown duration:
724dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
725dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //   cache status is evaluated against cache amount thresholds
726dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            //   (no duration so we don't have the bitrate either, could be derived from format?)
727dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            if (dataRemaining > SIZE_CACHED_HIGH_BYTES) {
728dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusHigh;
729dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            } else if (dataRemaining > SIZE_CACHED_MED_BYTES) {
730dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusEnough;
731dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            } else if (dataRemaining < SIZE_CACHED_LOW_BYTES) {
732dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusLow;
733dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            } else {
734dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi                mCacheStatus = kStatusIntermediate;
735dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi            }
736dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        }
737dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
738dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
739dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
740dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (oldStatus != mCacheStatus) {
741dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyStatus();
742dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
743dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
744dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    if (abs(mCacheFill - mLastNotifiedCacheFill) > mCacheFillNotifThreshold) {
745dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi        notifyCacheFill();
746dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    }
747dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
748dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi    return mCacheStatus;
749dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi}
750dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi
751347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
752347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivivoid AudioSfDecoder::hasNewDecodeParams() {
753347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
754347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    if ((mAudioSource != 0) && mAudioSourceStarted) {
755347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        sp<MetaData> meta = mAudioSource->getFormat();
756347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
757e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        int32_t channelCount;
758e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        CHECK(meta->findInt32(kKeyChannelCount, &channelCount));
759347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        int32_t sr;
760347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        CHECK(meta->findInt32(kKeySampleRate, &sr));
761347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
7629923b038db25831fdb481e73e90374f57fd4c871Glenn Kasten        // FIXME similar to onPrepare()
763347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        {
764347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi            android::Mutex::Autolock autoLock(mPcmFormatLock);
765e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten            SL_LOGV("format changed: old sr=%d, channels=%d; new sr=%d, channels=%d",
766e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten                    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE],
767e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten                    mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS],
768e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten                    sr, channelCount);
769e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_NUMCHANNELS] = channelCount;
770e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_SAMPLERATE] = sr;
771e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten            mPcmFormatValues[ANDROID_KEY_INDEX_PCMFORMAT_CHANNELMASK] =
772e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten                    channelCountToMask(channelCount);
773347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi        }
774347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    }
775347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
776347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    // alert users of those params
777347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi    updateAudioSink();
778347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi}
779347285f59e4aa7a062f67c4ae3a854cbdacb6378Jean-Michel Trivi
78094d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivistatic const char* const kPlaybackOnlyCodecs[] = { MEDIA_MIMETYPE_AUDIO_AMR_NB,
781c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi        MEDIA_MIMETYPE_AUDIO_AMR_WB };
78294d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi#define NB_PLAYBACK_ONLY_CODECS (sizeof(kPlaybackOnlyCodecs)/sizeof(kPlaybackOnlyCodecs[0]))
783c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi
784c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivibool AudioSfDecoder::isSupportedCodec(const char* mime) {
78594d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi    bool codecRequiresPermission = false;
78694d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi    for (unsigned int i = 0 ; i < NB_PLAYBACK_ONLY_CODECS ; i++) {
78794d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi        if (!strcasecmp(mime, kPlaybackOnlyCodecs[i])) {
78894d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi            codecRequiresPermission = true;
78994d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi            break;
790c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi        }
791c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi    }
79294d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi    if (codecRequiresPermission) {
79394d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi        // verify only the system can decode, for playback only
79494d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi        return checkCallingPermission(
79594d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi                String16("android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"));
79694d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi    } else {
79794d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi        return true;
79894d351603f83fdaa0c2bb5df7911c3e61fab01e2Jean-Michel Trivi    }
799c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi}
800c157a9c259474d4e1736c4f9ccccad10b5000734Jean-Michel Trivi
801dff1b1fc1f687c544e19df56bef225c45f7256a9Jean-Michel Trivi} // namespace android
802