AudioPlayer_to_android.cpp revision b42e943393b119b42b8fdca29be067800c35c78e
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root#include "sles_allinclusive.h"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_prompts.h"
19854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey#include "android/android_AudioToCbRenderer.h"
209527b223a9d4a4d149bb005afc77148dbeeff785Jeff Sharkey#include "android/android_StreamPlayer.h"
2132e80d7588720bdc9f8a3e961ac4566d7c80b2b9Jeff Sharkey#include "android/android_LocAVPlayer.h"
222798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root#include "android/include/AacBqToPcmCbRenderer.h"
232798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root
24fd7adedebf88427162a3ce27fcc9cfd3893c869dDianne Hackborn#include <fcntl.h>
250ac3031c159a0904e73eb4439cdc724d8df4a6e6Dianne Hackborn#include <sys/stat.h>
262798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root
27354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov#include <system/audio.h>
284a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav
294a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslavtemplate class android::KeyedVector<SLuint32, android::AudioEffect* > ;
309c165d76010d9f79f5cd71978742a335b6b8d1b4Svet Ganov
314a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav#define KEY_STREAM_TYPE_PARAMSIZE  sizeof(SLint32)
324a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav
334a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav#define AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE  500
344a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav#define AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE 2000
35be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey
36e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#define MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE
37e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey#define MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE
38a0e10434c49c6fe075e853da2046fd281318c4c4David Brazdil
39e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey//-----------------------------------------------------------------------------
40e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey// FIXME this method will be absorbed into android_audioPlayer_setPlayState() once
412699f065558ba78066887210b0c7346105959860Todd Kennedy//       bufferqueue and uri/fd playback are moved under the GenericPlayer C++ object
42e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff SharkeySLresult aplayer_setPlayState(const android::sp<android::GenericPlayer> &ap, SLuint32 playState,
43e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey        AndroidObjectState* pObjState) {
44e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey    SLresult result = SL_RESULT_SUCCESS;
45e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey    AndroidObjectState objState = *pObjState;
46e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey
47e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey    switch (playState) {
48e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey     case SL_PLAYSTATE_STOPPED:
49e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_STOPPED");
50e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey         ap->stop();
51e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey         break;
52513a074de68a4772a9900e90f38e74ff92c15e7cJeff Sharkey     case SL_PLAYSTATE_PAUSED:
5388d2a3c0e1b4a8c53a489db5d627beb80b1b9957Jeff Sharkey         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PAUSED");
54be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey         switch(objState) {
55b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey         case ANDROID_UNINITIALIZED:
56e0b0bef75b66f0a87039c8f58c17b1596a2baebeJeff Sharkey             *pObjState = ANDROID_PREPARING;
57b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey             ap->prepare();
582a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey             break;
59b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey         case ANDROID_PREPARING:
601c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio             break;
611c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio         case ANDROID_READY:
629f7e39fc9d278642a29df48daf44dceff11acd17Fabrice Di Meglio             ap->pause();
63cd65448ccd13c4c2d0fe9e9623fec3a898ab9372Jeff Sharkey             break;
648a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey         default:
658a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
662a90f673f5819e05ea72f6aba3e75956e0f807dcJeff Sharkey             result = SL_RESULT_INTERNAL_ERROR;
67d6ee0ba57906f83f45ca2a2cd835d7ff6e7a88dfTodd Kennedy             break;
682a90f673f5819e05ea72f6aba3e75956e0f807dcJeff Sharkey         }
692a90f673f5819e05ea72f6aba3e75956e0f807dcJeff Sharkey         break;
70f34db0a17ee035c165a4e81e9192f73d2455bd1cMakoto Onuki     case SL_PLAYSTATE_PLAYING: {
71b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey         SL_LOGV("setting GenericPlayer to SL_PLAYSTATE_PLAYING");
72b9f3674c11ed9c89b80a69f728cbc5f540b2ecdeJeff Sharkey         switch(objState) {
73b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey         case ANDROID_UNINITIALIZED:
74b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey             *pObjState = ANDROID_PREPARING;
756ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov             ap->prepare();
769527b223a9d4a4d149bb005afc77148dbeeff785Jeff Sharkey             // intended fall through
77354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov         case ANDROID_PREPARING:
7873767b9d607d99b3a027619b5c6b7f1a09b7673dJeff Sharkey             // intended fall through
796422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom         case ANDROID_READY:
806422abef786632e53337c6c298ffa64f7ddf4d90Brian Carlstrom             ap->play();
81c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy             break;
82be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey         default:
83be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey             SL_LOGE(ERROR_PLAYERSETPLAYSTATE_INVALID_OBJECT_STATE_D, playState);
84b92b05bb4bcaa6f7869128e925d0331eee62e4daJeff Sharkey             result = SL_RESULT_INTERNAL_ERROR;
8510fa67c77e11699391e27975fc2d276a0b8c7cbbNicolas Prevot             break;
86741abfc12074623d24297ebb67d98cb2d9126addNicolas Prevot         }
87941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey         }
88941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey         break;
89854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey     default:
90fa54ab7950b7ad7605cb842b47826b71a685bc28Todd Kennedy         // checked by caller, should not happen
91eeea67b8c3678d882d3774edc41242c63daa60faFyodor Kupolov         SL_LOGE(ERROR_SHOULDNT_BE_HERE_S, "aplayer_setPlayState");
92eeea67b8c3678d882d3774edc41242c63daa60faFyodor Kupolov         result = SL_RESULT_INTERNAL_ERROR;
93eeea67b8c3678d882d3774edc41242c63daa60faFyodor Kupolov         break;
94eeea67b8c3678d882d3774edc41242c63daa60faFyodor Kupolov     }
95b94c1657eb0140f7b91f5372a9f76de5a3d87e36Fyodor Kupolov
96bdd30d86ef98456161069d11481b2ccd25a11b4eAndreas Gampe    return result;
97bdd30d86ef98456161069d11481b2ccd25a11b4eAndreas Gampe}
984a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav
994a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav
1004a5f4a2bc7a379a5b4174f78fefeefe745e6cd37Svetoslav//-----------------------------------------------------------------------------
1012798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root// Callback associated with a AudioToCbRenderer of an SL ES AudioPlayer that gets its data
1021c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio// from a URI or FD, to write the decoded audio data to a buffer queue
1032a90f673f5819e05ea72f6aba3e75956e0f807dcJeff Sharkeystatic size_t adecoder_writeToBufferQueue(const uint8_t *data, size_t size, CAudioPlayer* ap) {
1042a90f673f5819e05ea72f6aba3e75956e0f807dcJeff Sharkey    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
105c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki        // it is not safe to enter the callback (the player is about to go away)
106a2064df6ab77f71e9187da380cbe355c5eaf5a64rich cannings        return 0;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t sizeConsumed = 0;
10998bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey    SL_LOGD("received %d bytes from decoder", size);
11087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    slBufferQueueCallback callback = NULL;
111b52a461851f322b0edf3cb9383da5f449b533311Michal Karpinski    void * callbackPContext = NULL;
1124528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tate
1135ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    // push decoded data to the buffer queue
114a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks    object_lock_exclusive(&ap->mObject);
1152798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root
116ecb0e637870553f9c12dc6b9178de0512563af9cDianne Hackborn    if (ap->mBufferQueue.mState.count != 0) {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1191ccac75e1f1b97eccb916a8de04fc1012b30f6e5Suchi Amalapurapu        BufferHeader *oldFront = ap->mBufferQueue.mFront;
120a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks        BufferHeader *newFront = &oldFront[1];
1211378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint8_t *pDest = (uint8_t *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ap->mBufferQueue.mSizeConsumed + size < oldFront->mSize) {
1241682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            // room to consume the whole or rest of the decoded data in one shot
1252f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey            ap->mBufferQueue.mSizeConsumed += size;
1262acf063da08dfff69f184c9a6a90a7a5fe60d818Svet Ganov            // consume data but no callback to the BufferQueue interface here
1272a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey            memcpy (pDest, data, size);
1282a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey            sizeConsumed = size;
12949237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn        } else {
130f7c06eb03ab4479b9d0656a23a4733d17e995183Svetoslav            // push as much as possible of the decoded data into the buffer queue
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sizeConsumed = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
133fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey            // the buffer at the head of the buffer queue is full, update the state
134f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate            ap->mBufferQueue.mSizeConsumed = 0;
1353a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            if (newFront == &ap->mBufferQueue.mArray[ap->mBufferQueue.mNumBuffers + 1]) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newFront = ap->mBufferQueue.mArray;
1378946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu            }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ap->mBufferQueue.mFront = newFront;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
140b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            ap->mBufferQueue.mState.count--;
141c6f22499f3046684d7175e10ca42cce1492cd36fdcashman            ap->mBufferQueue.mState.playIndex++;
1427767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn            // consume data
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy (pDest, data, sizeConsumed);
144a2b6c3775ed6b8924232d6a01bae4a19740a15f8Suchi Amalapurapu            // data has been copied to the buffer, and the buffer queue state has been updated
145a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            // we will notify the client if applicable
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback = ap->mBufferQueue.mCallback;
1476c0b9da65e36543bb50833d1b54ca532d0bd3aabJeff Sharkey            // save callback data
148adc1cf46045ae756d3a9ccbccf6b0f894e4c1eddSvet Ganov            callbackPContext = ap->mBufferQueue.mContext;
149b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        }
150ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
151d746057f2414cba2bdc69257cc5be8cb681bb592Jeff Sharkey    } else {
152c4858a2ba972e86436d629c4d3f18eb49116de14Jeff Sharkey        // no available buffers in the queue to write the decoded data
1532798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root        sizeConsumed = 0;
1541378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi    }
1550e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
156a3cdaa5337fa573c4c61770195d6232c2e587090Jason parks    object_unlock_exclusive(&ap->mObject);
1572798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root    // notify client
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != callback) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1627f7b0c759e2970178ef68805b21f06a26e24eb76Nicolas Prevot    ap->mCallbackProtector->exitCb();
1630aaa0d931716e9f57a1d84d795fab2df75092756Kenny Root    return sizeConsumed;
16405ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root}
165bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima
1662acf063da08dfff69f184c9a6a90a7a5fe60d818Svet Ganov
167ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski//-----------------------------------------------------------------------------
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LEFT_CHANNEL_MASK  0x1 << 0
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define RIGHT_CHANNEL_MASK 0x1 << 1
170851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid android_audioPlayer_volumeUpdate(CAudioPlayer* ap)
1722a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey{
1732798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root    assert(ap != NULL);
1741378aba7aeeb7f6dd6cc2503968ba7b0e58d9333Ramin Zaghi
1752798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root    // the source's channel count, where zero means unknown
1762798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root    SLuint8 channelCount = ap->mNumChannels;
177c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu
1780214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    // whether each channel is audible
1790214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    bool leftAudibilityFactor, rightAudibilityFactor;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // mute has priority over solo
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (channelCount >= STEREO_CHANNELS) {
183620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey        if (ap->mMuteMask & LEFT_CHANNEL_MASK) {
1842798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root            // left muted
18560459abb211a11caf71238a44f543fdc18289772Todd Kennedy            leftAudibilityFactor = false;
186554cb0c290406f5bba34908489db5382a69d0a9arpcraig        } else {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // left not muted
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // left soloed
190c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                leftAudibilityFactor = true;
191f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            } else {
192d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root                // left not soloed
1936c915ead38db0a2a6393c40d4fbac959399439c5Fyodor Kupolov                if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
194b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey                    // right solo silences left
1956ee871e59812fea4525c50231f677c4bd10c74b8Svet Ganov                    leftAudibilityFactor = false;
196b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey                } else {
197b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey                    // left and right are not soloed, and left is not muted
198b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey                    leftAudibilityFactor = true;
19950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey                }
200d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            }
201d02546b4151214abb2db1c88bf7debfc70bd2421Oscar Montemayor        }
20234385d352da19805ae948215e2edbeedd16b7941Elliott Hughes
20334385d352da19805ae948215e2edbeedd16b7941Elliott Hughes        if (ap->mMuteMask & RIGHT_CHANNEL_MASK) {
204bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima            // right muted
2057265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate            rightAudibilityFactor = false;
206b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        } else {
207b87de28f50e9f02a365f35348f8da6cc2629bc1cJeff Sharkey            // right not muted
208ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            if (ap->mSoloMask & RIGHT_CHANNEL_MASK) {
2092798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                // right soloed
2102798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                rightAudibilityFactor = true;
21178a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey            } else {
2122798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                // right not soloed
2132798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                if (ap->mSoloMask & LEFT_CHANNEL_MASK) {
214bd0e9e4958acdc6ab5f607bc252fddba877d20f9Jeff Sharkey                    // left solo silences right
215e9ecc8b49992840249bfb9d5d52b8824dd5de39bAmith Yamasani                    rightAudibilityFactor = false;
2162798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                } else {
2172798942bc4c0aeb8dd31d8471a367aaa5d8a2667Kenny Root                    // left and right are not soloed, and right is not muted
21863798c596dc757135950313eb4bb44ca58696c68Nicolas Prevot                    rightAudibilityFactor = true;
219620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey                }
220e012a235569fe307d165dfd0784ae847d0b13739Christopher Tate            }
221f720a9d91eb964b7772e3d42aae6bef83f531aacTodd Kennedy        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // channel mute and solo are ignored for mono and unknown channel count sources
224b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    } else {
2257440f177c3e70da0b883f8abffd6c8fc1d507bb8Todd Kennedy        leftAudibilityFactor = true;
226b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        rightAudibilityFactor = true;
227b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    }
228b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey
229b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    // compute volumes without setting
230966210b7218a99f57d7e9b40f7d2c0ff69151776Narayan Kamath    const bool audibilityFactors[2] = {leftAudibilityFactor, rightAudibilityFactor};
231b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    float volumes[2];
232fdeeeea6cfdebdb98dd70a7dd48965743af01750Jeff Sharkey    android_player_volumeUpdate(volumes, &ap->mVolume, channelCount, ap->mAmplFromDirectLevel,
233620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey            audibilityFactors);
2349527b223a9d4a4d149bb005afc77148dbeeff785Jeff Sharkey    float leftVol = volumes[0], rightVol = volumes[1];
235e68b127525c23e8e0cbe1e9dee75534d99e2833dJeff Davidson
236b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    // set volume on the underlying media player or audio track
237b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    if (ap->mAPlayer != 0) {
238b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        ap->mAPlayer->setVolume(leftVol, rightVol);
239b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    } else if (ap->mAudioTrack != 0) {
240620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey        ap->mAudioTrack->setVolume(leftVol, rightVol);
241e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate    }
24298bf12f99989ba2550fac83ee48ecbb6f1582f07Jeff Sharkey
243b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    // changes in the AudioPlayer volume must be reflected in the send level:
244620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey    //  in SLEffectSendItf or in SLAndroidEffectSendItf?
245b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    // FIXME replace interface test by an internal API once we have one.
246b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    if (NULL != ap->mEffectSend.mItf) {
247b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        for (unsigned int i=0 ; i<AUX_MAX ; i++) {
248b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            if (ap->mEffectSend.mEnableLevels[i].mEnable) {
249b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey                android_fxSend_setSendLevel(ap,
250d17fda40cdcf875002086fbe98bf34ba7cbdb03cFelipe Leme                        ap->mEffectSend.mEnableLevels[i].mSendLevel + ap->mVolume.mLevel);
2518c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov                // there's a single aux bus on Android, so we can stop looking once the first
2529527b223a9d4a4d149bb005afc77148dbeeff785Jeff Sharkey                // aux effect is found.
253f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey                break;
254b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            }
255b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        }
256d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    } else if (NULL != ap->mAndroidEffectSend.mItf) {
2572a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey        android_fxSend_setSendLevel(ap, ap->mAndroidEffectSend.mSendLevel + ap->mVolume.mLevel);
2582a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey    }
2592a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey}
2602a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey
2612a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey// Called by android_audioPlayer_volumeUpdate and android_mediaPlayer_volumeUpdate to compute
2622a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey// volumes, but setting volumes is handled by the caller.
263b9f3674c11ed9c89b80a69f728cbc5f540b2ecdeJeff Sharkey
2646038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tatevoid android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf, unsigned
265b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff SharkeychannelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/)
266b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey{
267ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    assert(pVolumes != NULL);
268fc8b7fe02630f64a1d6c8ecb06f4c250e7478f1dDianne Hackborn    assert(volumeItf != NULL);
2691c133105774835deaa99db78d9668b107246abefJeff Sharkey    // OK for audibilityFactors to be NULL
270e012a235569fe307d165dfd0784ae847d0b13739Christopher Tate
271e012a235569fe307d165dfd0784ae847d0b13739Christopher Tate    bool leftAudibilityFactor, rightAudibilityFactor;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // apply player mute factor
274fdd241a1e026afeeb68d30cb3d999ee9506769ceTodd Kennedy    // note that AudioTrack has mute() but not MediaPlayer, so it's easier to use volume
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // to mute for both rather than calling mute() for AudioTrack
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2771c133105774835deaa99db78d9668b107246abefJeff Sharkey    // player is muted
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (volumeItf->mMute) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        leftAudibilityFactor = false;
280ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        rightAudibilityFactor = false;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // player isn't muted, and channel mute/solo audibility factors are available (AudioPlayer)
282ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    } else if (audibilityFactors != NULL) {
283fdd241a1e026afeeb68d30cb3d999ee9506769ceTodd Kennedy        leftAudibilityFactor = audibilityFactors[0];
284b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        rightAudibilityFactor = audibilityFactors[1];
285d02546b4151214abb2db1c88bf7debfc70bd2421Oscar Montemayor    // player isn't muted, and channel mute/solo audibility factors aren't available (MediaPlayer)
28605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    } else {
287d9d438ac4e851275abb4ddc6671f74701e07b4fcTodd Kennedy        leftAudibilityFactor = true;
288a8e65fd82a323e6065ae9ae6cc8eaa130d3c1efdKenny Root        rightAudibilityFactor = true;
28905ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    }
290b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // compute amplification as the combination of volume level and stereo position
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //   amplification (or attenuation) from volume level
29349237345d83e62fdb9eb8d50b13ad086636a04faDianne Hackborn    float amplFromVolLevel = sles_to_android_amplification(volumeItf->mLevel);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //   amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    float leftVol  = amplFromVolLevel * amplFromDirectLevel;
296b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn    float rightVol = leftVol;
297a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // amplification from stereo position
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (volumeItf->mEnableStereoPosition) {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Left/right amplification (can be attenuations) factors derived for the StereoPosition
301bfed9f34c0cf7cdf7d25e6a7677e03f5a3d87e0eJeff Sharkey        float amplFromStereoPos[STEREO_CHANNELS];
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // panning law depends on content channel count: mono to stereo panning vs stereo balance
303bd0e9e4958acdc6ab5f607bc252fddba877d20f9Jeff Sharkey        if (1 == channelCount) {
304bd0e9e4958acdc6ab5f607bc252fddba877d20f9Jeff Sharkey            // mono to stereo panning
305ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            double theta = (1000+volumeItf->mStereoPosition)*M_PI_4/1000.0f; // 0 <= theta <= Pi/2
306620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey            amplFromStereoPos[0] = cos(theta);
307ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            amplFromStereoPos[1] = sin(theta);
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // channel count is 0 (unknown), 2 (stereo), or > 2 (multi-channel)
309d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn        } else {
310d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            // stereo balance
311d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            if (volumeItf->mStereoPosition > 0) {
312d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey                amplFromStereoPos[0] = (1000-volumeItf->mStereoPosition)/1000.0f;
313d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey                amplFromStereoPos[1] = 1.0f;
314d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            } else {
315d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey                amplFromStereoPos[0] = 1.0f;
316d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey                amplFromStereoPos[1] = (1000+volumeItf->mStereoPosition)/1000.0f;
317d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            }
318d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        }
319d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        leftVol  *= amplFromStereoPos[0];
320d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        rightVol *= amplFromStereoPos[1];
321d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    }
322d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey
323d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    // apply audibility factors
324d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    if (!leftAudibilityFactor) {
325d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        leftVol = 0.0;
326d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    }
327d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    if (!rightAudibilityFactor) {
328d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        rightVol = 0.0;
329d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    }
330d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey
331d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    // return the computed volumes
332d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    pVolumes[0] = leftVol;
333d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    pVolumes[1] = rightVol;
334d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey}
335d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey
3362a880312086147577e1e814bda6985fa97fb343bJeff Davidson//-----------------------------------------------------------------------------
337d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkeyvoid audioTrack_handleMarker_lockPlay(CAudioPlayer* ap) {
338d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    //SL_LOGV("received event EVENT_MARKER from AudioTrack");
339d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    slPlayCallback callback = NULL;
340d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    void* callbackPContext = NULL;
341d4310ac944e5f3063bb23558ba25ccf76fec0968Dianne Hackborn
342cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root    interface_lock_shared(&ap->mPlay);
343cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root    callback = ap->mPlay.mCallback;
344cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root    callbackPContext = ap->mPlay.mContext;
345c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn    interface_unlock_shared(&ap->mPlay);
346cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root
34772c10a25f0b91bac8d50ec512d37d516ece7c9d5Christopher Tate    if (NULL != callback) {
348f0d6cb38c47ee37583034dc3a68238ed13c91742Christopher Tate        // getting this event implies SL_PLAYEVENT_HEADATMARKER was set in the event mask
3491bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATMARKER);
3509718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root    }
3517767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn}
3529718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root
3539718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root//-----------------------------------------------------------------------------
3549718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Rootvoid audioTrack_handleNewPos_lockPlay(CAudioPlayer* ap) {
3559718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root    //SL_LOGV("received event EVENT_NEW_POS from AudioTrack");
35605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    slPlayCallback callback = NULL;
3575585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    void* callbackPContext = NULL;
358a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
359a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    interface_lock_shared(&ap->mPlay);
360a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    callback = ap->mPlay.mCallback;
361a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    callbackPContext = ap->mPlay.mContext;
362a89087542f774c585b6a6ec535fc294721710521Andreas Gampe    interface_unlock_shared(&ap->mPlay);
363a89087542f774c585b6a6ec535fc294721710521Andreas Gampe
364ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath    if (NULL != callback) {
365b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        // getting this event implies SL_PLAYEVENT_HEADATNEWPOS was set in the event mask
3662f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADATNEWPOS);
3670e62384ccbd00e9f78851929ca88b919679ee32eJeff Sharkey    }
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
369f480f2899cf4667170d93f6d7637e735b82d5baeSvet Ganov
370adc1cf46045ae756d3a9ccbccf6b0f894e4c1eddSvet Ganov
37112705131b95d5d6bcfae79d7991ff3e6f02457e4Todd Kennedy//-----------------------------------------------------------------------------
37212705131b95d5d6bcfae79d7991ff3e6f02457e4Todd Kennedyvoid audioTrack_handleUnderrun_lockPlay(CAudioPlayer* ap) {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    slPlayCallback callback = NULL;
374d42685d5de1dbd6d75b48d42418f370adaa4daefMike Lockwood    void* callbackPContext = NULL;
375cd0e839a2448deea50f79bddeba782c546b33893Nick Pelly
3761abb1cb3a8fe17f7866150604c2fd73751da787eJaikumar Ganesh    interface_lock_shared(&ap->mPlay);
377514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn    callback = ap->mPlay.mCallback;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    callbackPContext = ap->mPlay.mContext;
379c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate    bool headStalled = (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADSTALLED) != 0;
380c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate    interface_unlock_shared(&ap->mPlay);
381c55f9c04427796d5b6f833fe43adffd9d7b99ad2Christopher Tate
3828946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu    if ((NULL != callback) && headStalled) {
3838946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu        (*callback)(&ap->mPlay.mItf, callbackPContext, SL_PLAYEVENT_HEADSTALLED);
3848946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu    }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//-----------------------------------------------------------------------------
389af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu/**
390af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu * post-condition: play state of AudioPlayer is SL_PLAYSTATE_PAUSED if setPlayStateToPaused is true
39178d688369a2240009d3bbe4126996a973b2e2fe2Dianne Hackborn *
392661cd52e0e1d527132eb1cae604d3e64da7ec0cbDianne Hackborn * note: a conditional flag, setPlayStateToPaused, is used here to specify whether the play state
393d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn *       needs to be changed when the player reaches the end of the content to play. This is
39448d22323ce39f9aab003dce74456889b6414af55MÃ¥rten Kongstad *       relative to what the specification describes for buffer queues vs the
395d5c8044e7e1f1402fdd4a035690329294ab07b33Nick Kralevich *       SL_PLAYEVENT_HEADATEND event. In the OpenSL ES specification 1.0.1:
3966b0c8315e4c0db24522675c05ecd6a0b9bfb6d9eTodd Kennedy *        - section 8.12 SLBufferQueueItf states "In the case of starvation due to insufficient
397dbe0dd160e93feef1335830a36e86ae83b19b793Christopher Tate *          buffers in the queue, the playing of audio data stops. The player remains in the
398623b58b2cfcb778f52d2393bc4093ee721c3f16cNarayan Kamath *          SL_PLAYSTATE_PLAYING state."
399c293d3ad1a4fbbf616d4dfb041eb9cbf45262b45Todd Kennedy *        - section 9.2.31 SL_PLAYEVENT states "SL_PLAYEVENT_HEADATEND Playback head is at the end
400354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov *          of the current content and the player has paused."
40139bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy */
402d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkeyvoid audioPlayer_dispatch_headAtEnd_lockPlay(CAudioPlayer *ap, bool setPlayStateToPaused,
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool needToLock) {
404399cccb85749e02f6d3e12d1d2846310e7cbfdf1Dianne Hackborn    //SL_LOGV("ap=%p, setPlayStateToPaused=%d, needToLock=%d", ap, setPlayStateToPaused,
405111285763204cabff682b381928fd5447a5c6a90Kenny Root    //        needToLock);
4068c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    slPlayCallback playCallback = NULL;
4078c7f700a59ad26e75c9791335d78f14322cad49aSvet Ganov    void * playContext = NULL;
4085ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    // SLPlayItf callback or no callback?
409e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    if (needToLock) {
410e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        interface_lock_exclusive(&ap->mPlay);
411e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    }
412e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    if (ap->mPlay.mEventFlags & SL_PLAYEVENT_HEADATEND) {
413e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        playCallback = ap->mPlay.mCallback;
414e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        playContext = ap->mPlay.mContext;
415e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    }
416e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    if (setPlayStateToPaused) {
4177265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate        ap->mPlay.mState = SL_PLAYSTATE_PAUSED;
4187265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate    }
4197265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate    if (needToLock) {
4207265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate        interface_unlock_exclusive(&ap->mPlay);
4217265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate    }
4227265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate    // enqueue callback with no lock held
4237265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate    if (NULL != playCallback) {
4247265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
4257265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate        (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
4267265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate#else
4277265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate        SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
4287265abe77a76f848a316640b5da106e882bdbc8aChristopher Tate                SL_PLAYEVENT_HEADATEND);
4295ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        if (SL_RESULT_SUCCESS != result) {
4305ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root            ALOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback,
43136c67c236ed188a034fdf13977fbc8d4fe0023e2rich cannings                    &ap->mPlay.mItf, playContext);
4325ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
4335ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root#endif
4345ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    }
4355ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root
4365ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root}
437aa8513e171e4714809235e08a75aff3814d9a02brich cannings
4385ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root
439a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings//-----------------------------------------------------------------------------
440a6cfe52eb83995b124efec5f73bcb179caadf888rich canningsSLresult audioPlayer_setStreamType(CAudioPlayer* ap, SLint32 type) {
441a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    SLresult result = SL_RESULT_SUCCESS;
442a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    SL_LOGV("type %d", type);
443a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings
444a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    audio_stream_type_t newStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
445a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    switch(type) {
446a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    case SL_ANDROID_STREAM_VOICE:
4473d92f4ea37e6785605a8d62f1971f2dfe4569638Svet Ganov        newStreamType = AUDIO_STREAM_VOICE_CALL;
4483d92f4ea37e6785605a8d62f1971f2dfe4569638Svet Ganov        break;
449111285763204cabff682b381928fd5447a5c6a90Kenny Root    case SL_ANDROID_STREAM_SYSTEM:
450111285763204cabff682b381928fd5447a5c6a90Kenny Root        newStreamType = AUDIO_STREAM_SYSTEM;
451e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        break;
452111285763204cabff682b381928fd5447a5c6a90Kenny Root    case SL_ANDROID_STREAM_RING:
453e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        newStreamType = AUDIO_STREAM_RING;
454c78a8079740bfcad2e4439ccd74da52f6dc7fae2Kenny Root        break;
455c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    case SL_ANDROID_STREAM_MEDIA:
456c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        newStreamType = AUDIO_STREAM_MUSIC;
457c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        break;
458c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    case SL_ANDROID_STREAM_ALARM:
459c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        newStreamType = AUDIO_STREAM_ALARM;
460c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        break;
46105ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    case SL_ANDROID_STREAM_NOTIFICATION:
46205ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        newStreamType = AUDIO_STREAM_NOTIFICATION;
46348d22323ce39f9aab003dce74456889b6414af55MÃ¥rten Kongstad        break;
46448d22323ce39f9aab003dce74456889b6414af55MÃ¥rten Kongstad    default:
465c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        SL_LOGE(ERROR_PLAYERSTREAMTYPE_SET_UNKNOWN_TYPE);
466c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        result = SL_RESULT_PARAMETER_INVALID;
467c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        break;
468c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
469c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav
470c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    // stream type needs to be set before the object is realized
47178027f3b72ad0cad4c39c3947985526ac31a6d3eSvet Ganov    // (ap->mAudioTrack is supposed to be NULL until then)
4729c165d76010d9f79f5cd71978742a335b6b8d1b4Svet Ganov    if (SL_OBJECT_STATE_UNREALIZED != ap->mObject.mState) {
473c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        SL_LOGE(ERROR_PLAYERSTREAMTYPE_REALIZED);
474c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        result = SL_RESULT_PRECONDITIONS_VIOLATED;
4759c165d76010d9f79f5cd71978742a335b6b8d1b4Svet Ganov    } else {
476c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav        ap->mStreamType = newStreamType;
4777841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate    }
4787841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate
4797841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate    return result;
4807841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate}
4817841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate
4827841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate
4837841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate//-----------------------------------------------------------------------------
4847841eb899561af3b122a5143cdcfe64c0766a5f5Christopher TateSLresult audioPlayer_getStreamType(CAudioPlayer* ap, SLint32 *pType) {
4857841eb899561af3b122a5143cdcfe64c0766a5f5Christopher Tate    SLresult result = SL_RESULT_SUCCESS;
4865585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy
4875585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    switch(ap->mStreamType) {
4885585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    case AUDIO_STREAM_VOICE_CALL:
4895585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        *pType = SL_ANDROID_STREAM_VOICE;
4905585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        break;
4915585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    case AUDIO_STREAM_SYSTEM:
4925585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        *pType = SL_ANDROID_STREAM_SYSTEM;
4935585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        break;
4945585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    case AUDIO_STREAM_RING:
4955585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        *pType = SL_ANDROID_STREAM_RING;
4965585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        break;
4975585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    case AUDIO_STREAM_DEFAULT:
49843fc2447df2354fcb7b843a86b1c266946ca5702Andreas Gampe    case AUDIO_STREAM_MUSIC:
4996823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        *pType = SL_ANDROID_STREAM_MEDIA;
5006823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        break;
5016823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe    case AUDIO_STREAM_ALARM:
5026823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        *pType = SL_ANDROID_STREAM_ALARM;
5036823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        break;
5046823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe    case AUDIO_STREAM_NOTIFICATION:
5056823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        *pType = SL_ANDROID_STREAM_NOTIFICATION;
5066823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe        break;
507258aa3e56b02b95e8e855ef949a29babe178b4a5Narayan Kamath    default:
50843fc2447df2354fcb7b843a86b1c266946ca5702Andreas Gampe        result = SL_RESULT_INTERNAL_ERROR;
509258aa3e56b02b95e8e855ef949a29babe178b4a5Narayan Kamath        *pType = SL_ANDROID_STREAM_MEDIA;
51043fc2447df2354fcb7b843a86b1c266946ca5702Andreas Gampe        break;
511bd784e961c560a2069e2df75fb17282013c198d2Jeff Hao    }
512bd784e961c560a2069e2df75fb17282013c198d2Jeff Hao
513c7b9482b0c4bb2d378e63541b96be45c50094e05Jeff Hao    return result;
5146f357d3284a833cc50a990e14b39f389b8972254Jeff Brown}
515dd3d95f182a634acdcc1b1e8e4954234d048eb54Nick Kralevich
5160214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//-----------------------------------------------------------------------------
518b52a461851f322b0edf3cb9383da5f449b533311Michal Karpinskivoid audioPlayer_auxEffectUpdate(CAudioPlayer* ap) {
519b52a461851f322b0edf3cb9383da5f449b533311Michal Karpinski    if ((ap->mAudioTrack != 0) && (ap->mAuxEffect != 0)) {
520ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey        android_fxSend_attach(ap, true, ap->mAuxEffect, ap->mVolume.mLevel + ap->mAuxSendLevel);
521ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey    }
522ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey}
523ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey
524ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey
525ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey//-----------------------------------------------------------------------------
526851a54143c15a1c33361efae2db3f7f45059b472Dianne Hackborn/*
527ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker * returns true if the given data sink is supported by AudioPlayer that doesn't
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   play to an OutputMix object, false otherwise
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
530d2509fd83597595914ef0627685e917380863eb6Dianne Hackborn * pre-condition: the locator of the audio sink is not SL_DATALOCATOR_OUTPUTMIX
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool audioPlayer_isSupportedNonOutputMixSink(const SLDataSink* pAudioSink) {
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool result = true;
5349f60c08a446e38f9e2d5271546ef69ca5941eba9Jeff Hao    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSink->pLocator;
5356823f6d038c296cadda20e0b8d75ae08cbf677c3Andreas Gampe    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSink->pFormat;
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53751a573c76737733638c475f52e441c814e6645ccKenny Root    switch (sinkLocatorType) {
53851a573c76737733638c475f52e441c814e6645ccKenny Root
53951a573c76737733638c475f52e441c814e6645ccKenny Root    case SL_DATALOCATOR_BUFFERQUEUE:
540ddbe50df2ca70700a46e5849347989b520d1113eKenny Root    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (SL_DATAFORMAT_PCM != sinkFormatType) {
5426dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey            SL_LOGE("Unsupported sink format 0x%x, expected SL_DATAFORMAT_PCM",
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (unsigned)sinkFormatType);
544ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker            result = false;
54557dcf5b177b56195421535938544f32d8b591b42Jeff Sharkey        }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // it's no use checking the PCM format fields because additional characteristics
5472699f065558ba78066887210b0c7346105959860Todd Kennedy        // such as the number of channels, or sample size are unknown to the player at this stage
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
549ddbe50df2ca70700a46e5849347989b520d1113eKenny Root
550ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath    default:
551ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath        SL_LOGE("Unsupported sink locator type 0x%x", (unsigned)sinkLocatorType);
552ddbe50df2ca70700a46e5849347989b520d1113eKenny Root        result = false;
553ff110bd61a69f7ed8602ae14b27f7befec76b2e7Narayan Kamath        break;
554ddbe50df2ca70700a46e5849347989b520d1113eKenny Root    }
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
558ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
560ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker//-----------------------------------------------------------------------------
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns the Android object type if the locator type combinations for the source and sinks
563f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate *   are supported by this implementation, INVALID_TYPE otherwise
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
565ab5c49c7e7f5f61040650109a76f38a443fb852dDoug ZongkerAndroidObjectType audioPlayer_getAndroidObjectTypeForSourceSink(CAudioPlayer *ap) {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
567ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker    const SLDataSource *pAudioSrc = &ap->mDataSource.u.mSource;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SLDataSink *pAudioSnk = &ap->mDataSink.u.mSink;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
5716dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    AndroidObjectType type = INVALID_TYPE;
5729f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey
5739f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    //--------------------------------------
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Sink / source matching check:
57539bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    // the following source / sink combinations are supported
57639bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    //     SL_DATALOCATOR_BUFFERQUEUE                / SL_DATALOCATOR_OUTPUTMIX
57739bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    //     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE   / SL_DATALOCATOR_OUTPUTMIX
57848d22323ce39f9aab003dce74456889b6414af55MÃ¥rten Kongstad    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_OUTPUTMIX
5799f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_OUTPUTMIX
5809f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_OUTPUTMIX
58148d22323ce39f9aab003dce74456889b6414af55MÃ¥rten Kongstad    //     SL_DATALOCATOR_ANDROIDBUFFERQUEUE         / SL_DATALOCATOR_BUFFERQUEUE
582056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_BUFFERQUEUE
5838b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_BUFFERQUEUE
584056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy    //     SL_DATALOCATOR_URI                        / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
585056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy    //     SL_DATALOCATOR_ANDROIDFD                  / SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
586056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy    switch (sinkLocatorType) {
587056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy
5885585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy    case SL_DATALOCATOR_OUTPUTMIX: {
5895585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        switch (sourceLocatorType) {
5905585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy
5915585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        //   Buffer Queue to AudioTrack
5925585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        case SL_DATALOCATOR_BUFFERQUEUE:
5935585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
5945585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy            type = AUDIOPLAYER_FROM_PCM_BUFFERQUEUE;
5955585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy            break;
5965585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy
5975585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        //   URI or FD to MediaPlayer
5985585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        case SL_DATALOCATOR_URI:
5995585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy        case SL_DATALOCATOR_ANDROIDFD:
6005585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy            type = AUDIOPLAYER_FROM_URIFD;
6015585dd971e265cbb3a515bb759710646c5bc6f63Todd Kennedy            break;
602056d6b0069561af5dc16b1c38fc8d18bd876b54bTodd Kennedy
6038b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy        //   Android BufferQueue to MediaPlayer (shared memory streaming)
6048b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
6058b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy            type = AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE;
6068b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy            break;
6078b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy
6088b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy        default:
6098b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_OUTPUTMIX sink",
6108b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy                    (unsigned)sourceLocatorType);
6118b3e6b0df102901f938cd0687f9994a3ff767fcfTodd Kennedy            break;
612d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
614d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        break;
615d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey
616d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    case SL_DATALOCATOR_BUFFERQUEUE:
617d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
618d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        switch (sourceLocatorType) {
619d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey
620d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        //   URI or FD decoded to PCM in a buffer queue
621d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        case SL_DATALOCATOR_URI:
622d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey        case SL_DATALOCATOR_ANDROIDFD:
623d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            type = AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE;
624d4041db120d7500e73e0132b03dfeffb84d402f5Jeff Sharkey            break;
625c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki
626c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki        //   AAC ADTS Android buffer queue decoded to PCM in a buffer queue
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            type = AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE;
629be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn            break;
630be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn
6319f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        default:
6329f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey            SL_LOGE("Source data locator 0x%x not supported with SL_DATALOCATOR_BUFFERQUEUE sink",
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (unsigned)sourceLocatorType);
634be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn            break;
635be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn        }
636be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn        break;
6372acf063da08dfff69f184c9a6a90a7a5fe60d818Svet Ganov
6382acf063da08dfff69f184c9a6a90a7a5fe60d818Svet Ganov    default:
639be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn        SL_LOGE("Sink data locator 0x%x not supported", (unsigned)sinkLocatorType);
640be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn        break;
641be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn    }
642c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn
643c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn    return type;
644c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn}
645c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn
646c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn
647c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn//-----------------------------------------------------------------------------
648c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn/*
649be7c50e0a14e91330ce13161bc14a33d34ff6acaDianne Hackborn * Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
6509f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey * from a URI or FD, for prepare, prefetch, and play events
6519f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey */
652172d38bcda8d05793db13eb763a280ac2ee36fabRobert Craigstatic void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // FIXME see similar code and comment in player_handleMediaPlayerEventNotifications
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == user) {
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CAudioPlayer *ap = (CAudioPlayer *)user;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // it is not safe to enter the callback (the track is about to go away)
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
66485f5f8132015d8a5043ea4413702420d0d157c9fJeff Sharkey    }
66585f5f8132015d8a5043ea4413702420d0d157c9fJeff Sharkey    union {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char c[sizeof(int)];
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } u;
6699f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    u.i = event;
6709f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    SL_LOGV("sfplayer_handlePrefetchEvent(event='%c%c%c%c' (%d), data1=%d, data2=%d, user=%p) from "
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "SfAudioPlayer", u.c[3], u.c[2], u.c[1], u.c[0], event, data1, data2, user);
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch(event) {
6739f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey
6749f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    case android::GenericPlayer::kEventPrepared: {
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SL_LOGV("Received GenericPlayer::kEventPrepared for CAudioPlayer %p", ap);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6779f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        // assume no callback
6789f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        slPrefetchCallback callback = NULL;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void* callbackPContext;
680b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn        SLuint32 events;
681b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn
6829f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        object_lock_exclusive(&ap->mObject);
6832a880312086147577e1e814bda6985fa97fb343bJeff Davidson
684854060af30f928c0a65591e9c8314ae17056e6b8Dianne Hackborn        // mark object as prepared; same state is used for successful or unsuccessful prepare
6859f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        assert(ap->mAndroidObjState == ANDROID_PREPARING);
686ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker        ap->mAndroidObjState = ANDROID_READY;
6875ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root
68805ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        if (PLAYER_SUCCESS == data1) {
68905ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root            // Most of successful prepare completion for ap->mAPlayer
6905ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root            // is handled by GenericPlayer and its subclasses.
69133f5ddd1bea21296938f2cba196f95d223aa247cDianne Hackborn        } else {
69233f5ddd1bea21296938f2cba196f95d223aa247cDianne Hackborn            // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to
69333f5ddd1bea21296938f2cba196f95d223aa247cDianne Hackborn            //  indicate a prefetch error, so we signal it by sending simultaneously two events:
6943a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            //  - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0
6953a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            //  - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW
696eeea67b8c3678d882d3774edc41242c63daa60faFyodor Kupolov            SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1);
697620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
698620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey                ap->mPrefetchStatus.mLevel = 0;
699620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
700620b32b316fd4f1bab4eef55ec8802d14a55e7ddJeff Sharkey                if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
701f7c06eb03ab4479b9d0656a23a4733d17e995183Svetoslav                        (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
702f7c06eb03ab4479b9d0656a23a4733d17e995183Svetoslav                    callback = ap->mPrefetchStatus.mCallback;
7037f7b0c759e2970178ef68805b21f06a26e24eb76Nicolas Prevot                    callbackPContext = ap->mPrefetchStatus.mContext;
7047f7b0c759e2970178ef68805b21f06a26e24eb76Nicolas Prevot                    events = SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE;
7057f7b0c759e2970178ef68805b21f06a26e24eb76Nicolas Prevot                }
7065ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root            }
7075ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
7085ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root
709ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey        object_unlock_exclusive(&ap->mObject);
710ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey
711ca27d452c14f8a275cf2b7d0e59080690e0dc5c1Jeff Sharkey        // callback with no lock held
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL != callback) {
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, events);
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    break;
718bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima
719bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima    case android::GenericPlayer::kEventPrefetchFillLevelUpdate : {
720bb9682e12009aaad696f0b162085efc4b94f5048Jose Lima        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
722e46fbfaf2e5759b54091dd62e2e9cf14a8545fcfJeff Sharkey        }
723e46fbfaf2e5759b54091dd62e2e9cf14a8545fcfJeff Sharkey        slPrefetchCallback callback = NULL;
724e46fbfaf2e5759b54091dd62e2e9cf14a8545fcfJeff Sharkey        void* callbackPContext = NULL;
7251c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7261c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        // SLPrefetchStatusItf callback or no callback?
727b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        interface_lock_exclusive(&ap->mPrefetchStatus);
728b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
729b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy            callback = ap->mPrefetchStatus.mCallback;
730b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy            callbackPContext = ap->mPrefetchStatus.mContext;
731b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        }
732b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        ap->mPrefetchStatus.mLevel = (SLpermille)data1;
733b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        interface_unlock_exclusive(&ap->mPrefetchStatus);
734b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy
735b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        // callback with no lock held
736b8a279ee838c309a64211a3caa5e5e204250163dTodd Kennedy        if (NULL != callback) {
7371c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
7381c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
7391c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
740adc1cf46045ae756d3a9ccbccf6b0f894e4c1eddSvet Ganov    }
741adc1cf46045ae756d3a9ccbccf6b0f894e4c1eddSvet Ganov    break;
742adc1cf46045ae756d3a9ccbccf6b0f894e4c1eddSvet Ganov
743cb6fd80721253ffa9dcab5cf8c2f4e9b9cd17cccFyodor Kupolov    case android::GenericPlayer::kEventPrefetchStatusChange: {
744cb6fd80721253ffa9dcab5cf8c2f4e9b9cd17cccFyodor Kupolov        if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
745cb6fd80721253ffa9dcab5cf8c2f4e9b9cd17cccFyodor Kupolov            break;
7466c915ead38db0a2a6393c40d4fbac959399439c5Fyodor Kupolov        }
7476c915ead38db0a2a6393c40d4fbac959399439c5Fyodor Kupolov        slPrefetchCallback callback = NULL;
7486038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        void* callbackPContext = NULL;
7496038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate
7506038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        // SLPrefetchStatusItf callback or no callback?
7516038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        object_lock_exclusive(&ap->mObject);
7526038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        if (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE) {
7536038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate            callback = ap->mPrefetchStatus.mCallback;
7546038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate            callbackPContext = ap->mPrefetchStatus.mContext;
7556038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        }
7566038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        if (data1 >= android::kStatusIntermediate) {
7576038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
7586038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        } else if (data1 < android::kStatusIntermediate) {
7596038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
7606038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        }
7616038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        object_unlock_exclusive(&ap->mObject);
7626038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate
7636038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        // callback with no lock held
7641c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if (NULL != callback) {
7651c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, SL_PREFETCHEVENT_STATUSCHANGE);
7661c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7671c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7681c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
7691c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7701c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case android::GenericPlayer::kEventEndOfStream: {
7711c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        audioPlayer_dispatch_headAtEnd_lockPlay(ap, true /*set state to paused?*/, true);
7721c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if ((ap->mAudioTrack != 0) && (!ap->mSeek.mLoopEnabled)) {
7731c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            ap->mAudioTrack->stop();
7741c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7751c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7761c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
7771c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7781c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case android::GenericPlayer::kEventChannelCount: {
7791c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        object_lock_exclusive(&ap->mObject);
7801c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if (UNKNOWN_NUMCHANNELS == ap->mNumChannels && UNKNOWN_NUMCHANNELS != data1) {
7811c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            ap->mNumChannels = data1;
7823c458636494f28685146060e1252f52fe43ed38aChristopher Tate            android_audioPlayer_volumeUpdate(ap);
7831c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7841c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        object_unlock_exclusive(&ap->mObject);
7851c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
7861c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
7871c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7881c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case android::GenericPlayer::kEventPlay: {
7891c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        slPlayCallback callback = NULL;
7901c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        void* callbackPContext = NULL;
7911c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7921c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        interface_lock_shared(&ap->mPlay);
7931c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        callback = ap->mPlay.mCallback;
7941c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        callbackPContext = ap->mPlay.mContext;
7951c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        interface_unlock_shared(&ap->mPlay);
7961c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
7971c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if (NULL != callback) {
7980788595e0c9bc5e8c1907c63db595010006ef5b4Fabrice Di Meglio            SLuint32 event = (SLuint32) data1;  // SL_PLAYEVENT_HEAD*
7991c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio#ifndef USE_ASYNCHRONOUS_PLAY_CALLBACK
8001c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            // synchronous callback requires a synchronous GetPosition implementation
8010788595e0c9bc5e8c1907c63db595010006ef5b4Fabrice Di Meglio            (*callback)(&ap->mPlay.mItf, callbackPContext, event);
8021c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio#else
8030788595e0c9bc5e8c1907c63db595010006ef5b4Fabrice Di Meglio            // asynchronous callback works with any GetPosition implementation
8041c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            SLresult result = EnqueueAsyncCallback_ppi(ap, callback, &ap->mPlay.mItf,
8057d014cec63939f7aca2a8014f45cd4c9a3e1aa0cFabrice Di Meglio                    callbackPContext, event);
8067d014cec63939f7aca2a8014f45cd4c9a3e1aa0cFabrice Di Meglio            if (SL_RESULT_SUCCESS != result) {
8071c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                ALOGW("Callback %p(%p, %p, 0x%x) dropped", callback,
8081c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                        &ap->mPlay.mItf, callbackPContext, event);
8091c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
8101c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio#endif
8111c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
8121c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
8131c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
8141c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8151c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio      case android::GenericPlayer::kEventErrorAfterPrepare: {
8160788595e0c9bc5e8c1907c63db595010006ef5b4Fabrice Di Meglio        SL_LOGV("kEventErrorAfterPrepare");
8171c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8181c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        // assume no callback
8191c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        slPrefetchCallback callback = NULL;
8201c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        void* callbackPContext = NULL;
8211c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8221c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        object_lock_exclusive(&ap->mObject);
8231c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
8241c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            ap->mPrefetchStatus.mLevel = 0;
8251c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
8261c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
8271c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
8281c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                callback = ap->mPrefetchStatus.mCallback;
8291c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                callbackPContext = ap->mPrefetchStatus.mContext;
8301c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
8311c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
8321c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        object_unlock_exclusive(&ap->mObject);
8331c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8341c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        // FIXME there's interesting information in data1, but no API to convey it to client
8351c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        SL_LOGE("Error after prepare: %d", data1);
836ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn
8376038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        // callback with no lock held
8381c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        if (NULL != callback) {
8391c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
8401c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
8411c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
8421c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8431c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio      }
8441c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio      break;
8451c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8461c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case android::GenericPlayer::kEventHasVideoSize:
8476038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        //SL_LOGW("Unexpected kEventHasVideoSize");
8486038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        break;
8496038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate
8506038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate    default:
8511c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
8521c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    }
8531c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8541c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    ap->mCallbackProtector->exitCb();
855ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn}
856ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn
857ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn
8581c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//-----------------------------------------------------------------------------
8591c1b47125da018b44240739db75f8898e064a948Fabrice Di MeglioSLresult android_audioPlayer_checkSourceSink(CAudioPlayer *pAudioPlayer)
8601c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio{
8611c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    // verify that the locator types for the source / sink combination is supported
8621c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    pAudioPlayer->mAndroidObjType = audioPlayer_getAndroidObjectTypeForSourceSink(pAudioPlayer);
8631c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    if (INVALID_TYPE == pAudioPlayer->mAndroidObjType) {
8641c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        return SL_RESULT_PARAMETER_INVALID;
8651c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    }
8661c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8671c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    const SLDataSource *pAudioSrc = &pAudioPlayer->mDataSource.u.mSource;
8681c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    const SLDataSink *pAudioSnk = &pAudioPlayer->mDataSink.u.mSink;
8691c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8701c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    // format check:
8711c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
8721c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
873ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn    const SLuint32 sourceFormatType = *(SLuint32 *)pAudioSrc->pFormat;
87401e186437f7c41b5cf8a97becb22d2f369c374daChristopher Tate    const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat;
87501e186437f7c41b5cf8a97becb22d2f369c374daChristopher Tate
8761c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    switch (sourceLocatorType) {
8771c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    //------------------
8781c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    //   Buffer Queues
8791c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case SL_DATALOCATOR_BUFFERQUEUE:
8801c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
8811c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        {
8821c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *) pAudioSrc->pLocator;
8831c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
8841c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        // Buffer format
8851c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        switch (sourceFormatType) {
8861c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        //     currently only PCM buffer queues are supported,
8871c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        case SL_DATAFORMAT_PCM: {
8881c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *) pAudioSrc->pFormat;
8891c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            switch (df_pcm->numChannels) {
8901c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case 1:
8911c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case 2:
8921c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                break;
8931c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            default:
8941c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                // this should have already been rejected by checkDataFormat
8951c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                SL_LOGE("Cannot create audio player: unsupported " \
8961c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    "PCM data source with %u channels", (unsigned) df_pcm->numChannels);
8971c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                return SL_RESULT_CONTENT_UNSUPPORTED;
8981c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
8991c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            switch (df_pcm->samplesPerSec) {
9001c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_8:
9011c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_11_025:
9021c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_12:
9031c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_16:
9041c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_22_05:
9051c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_24:
9061c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_32:
9071c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_44_1:
9081c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_48:
9091c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                break;
9101c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_64:
9111c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_88_2:
9121c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_96:
9131c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_SAMPLINGRATE_192:
9141c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            default:
9151c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                SL_LOGE("Cannot create audio player: unsupported sample rate %u milliHz",
9161c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    (unsigned) df_pcm->samplesPerSec);
9171c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                return SL_RESULT_CONTENT_UNSUPPORTED;
9181c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
9191c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            switch (df_pcm->bitsPerSample) {
9201c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_PCMSAMPLEFORMAT_FIXED_8:
9211c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_PCMSAMPLEFORMAT_FIXED_16:
9221c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                break;
9231c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                // others
9241c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            default:
9251c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                // this should have already been rejected by checkDataFormat
9266038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate                SL_LOGE("Cannot create audio player: unsupported sample bit depth %u",
9271c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                        (SLuint32)df_pcm->bitsPerSample);
9286038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate                return SL_RESULT_CONTENT_UNSUPPORTED;
9291c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
9301c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            switch (df_pcm->containerSize) {
9311c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case 8:
9321c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case 16:
9336038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate                break;
9341c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                // others
9351c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            default:
9366038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate                SL_LOGE("Cannot create audio player: unsupported container size %u",
937e06b4d1d9f718b9fe02980fea794a36831a16db2Jeff Sharkey                    (unsigned) df_pcm->containerSize);
9381c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                return SL_RESULT_CONTENT_UNSUPPORTED;
9391c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
9401c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            // df_pcm->channelMask: the earlier platform-independent check and the
9411c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            //     upcoming check by sles_to_android_channelMaskOut are sufficient
9421c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            switch (df_pcm->endianness) {
9436038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate            case SL_BYTEORDER_LITTLEENDIAN:
9441c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                break;
9451c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            case SL_BYTEORDER_BIGENDIAN:
9466038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate                SL_LOGE("Cannot create audio player: unsupported big-endian byte order");
9471c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                return SL_RESULT_CONTENT_UNSUPPORTED;
9481c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                // native is proposed but not yet in spec
9491c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            default:
9501c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                SL_LOGE("Cannot create audio player: unsupported byte order %u",
9511c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    (unsigned) df_pcm->endianness);
9521c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                return SL_RESULT_CONTENT_UNSUPPORTED;
9531c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
9540788595e0c9bc5e8c1907c63db595010006ef5b4Fabrice Di Meglio            } //case SL_DATAFORMAT_PCM
9551c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            break;
9567d014cec63939f7aca2a8014f45cd4c9a3e1aa0cFabrice Di Meglio        case SL_DATAFORMAT_MIME:
957ac15b1b0c05c79f5939aa6f88e973d4d479946cbChristopher Tate        case XA_DATAFORMAT_RAWIMAGE:
958ac15b1b0c05c79f5939aa6f88e973d4d479946cbChristopher Tate            SL_LOGE("Cannot create audio player with buffer queue data source "
959ac15b1b0c05c79f5939aa6f88e973d4d479946cbChristopher Tate                "without SL_DATAFORMAT_PCM format");
9601c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            return SL_RESULT_CONTENT_UNSUPPORTED;
9611c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        default:
9620214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu            // invalid data format is detected earlier
9631e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            assert(false);
9641e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_INTERNAL_ERROR;
9659f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        } // switch (sourceFormatType)
9661e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        } // case SL_DATALOCATOR_BUFFERQUEUE or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
9671e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        break;
9689f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    //------------------
9691e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    //   URI
9701e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    case SL_DATALOCATOR_URI:
9711e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        {
9729f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
9731e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        if (NULL == dl_uri->URI) {
9741e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_PARAMETER_INVALID;
9751e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        }
9761e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        // URI format
9779f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        switch (sourceFormatType) {
9781e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATAFORMAT_MIME:
9791e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            break;
9801e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATAFORMAT_PCM:
9811e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case XA_DATAFORMAT_RAWIMAGE:
9829f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_URI data source without "
9831e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                "SL_DATAFORMAT_MIME format");
9841e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_CONTENT_UNSUPPORTED;
9851e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        } // switch (sourceFormatType)
9861e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        // decoding format check
9871e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
9881e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
9891e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_CONTENT_UNSUPPORTED;
9901e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        }
9911e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        } // case SL_DATALOCATOR_URI
9921e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        break;
9931e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    //------------------
9941e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    //   File Descriptor
9951e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    case SL_DATALOCATOR_ANDROIDFD:
9961e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        {
9971e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        // fd is already non null
9981e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        switch (sourceFormatType) {
9991e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATAFORMAT_MIME:
10009f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey            break;
10011e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATAFORMAT_PCM:
10021e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            // FIXME implement
10031e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            SL_LOGD("[ FIXME implement PCM FD data sources ]");
10041e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            break;
10051e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case XA_DATAFORMAT_RAWIMAGE:
10061e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            SL_LOGE("Cannot create audio player with SL_DATALOCATOR_ANDROIDFD data source "
10071e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                "without SL_DATAFORMAT_MIME or SL_DATAFORMAT_PCM format");
10081e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_CONTENT_UNSUPPORTED;
10091e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        default:
10101e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            // invalid data format is detected earlier
10111e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            assert(false);
10121e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_INTERNAL_ERROR;
10131e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        } // switch (sourceFormatType)
10141e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        if ((sinkLocatorType != SL_DATALOCATOR_OUTPUTMIX) &&
10151e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                !audioPlayer_isSupportedNonOutputMixSink(pAudioSnk)) {
10161e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            return SL_RESULT_CONTENT_UNSUPPORTED;
10179f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        }
10189f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey        } // case SL_DATALOCATOR_ANDROIDFD
10191e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        break;
10209f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey    //------------------
10211e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    //   Stream
10221e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
10231e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    {
10241e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        switch (sourceFormatType) {
10251e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATAFORMAT_MIME:
10261e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        {
10271e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pAudioSrc->pFormat;
10289b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            if (NULL == df_mime) {
10299b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                SL_LOGE("MIME type null invalid");
10309b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                return SL_RESULT_CONTENT_UNSUPPORTED;
10319b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            }
10329b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            SL_LOGD("source MIME is %s", (char*)df_mime->mimeType);
10330214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu            switch(df_mime->containerType) {
1034c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu            case SL_CONTAINERTYPE_MPEG_TS:
1035c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                if (strcasecmp((char*)df_mime->mimeType, (const char *)XA_ANDROID_MIME_MP2TS)) {
1036c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                    SL_LOGE("Invalid MIME (%s) for container SL_CONTAINERTYPE_MPEG_TS, expects %s",
1037c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                            (char*)df_mime->mimeType, XA_ANDROID_MIME_MP2TS);
1038e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    return SL_RESULT_CONTENT_UNSUPPORTED;
10395b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu                }
10401bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate                break;
10419b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            case SL_CONTAINERTYPE_RAW:
10429b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            case SL_CONTAINERTYPE_AAC:
1043e99bb5f10b90736d10cee9729b56cba156fc0921Suchi Amalapurapu                if (strcasecmp((char*)df_mime->mimeType, (const char *)SL_ANDROID_MIME_AACADTS) &&
1044d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn                        strcasecmp((char*)df_mime->mimeType,
1045483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                                ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK)) {
10465ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                    SL_LOGE("Invalid MIME (%s) for container type %d, expects %s",
10475ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                            (char*)df_mime->mimeType, df_mime->containerType,
10481c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                            SL_ANDROID_MIME_AACADTS);
10491c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    return SL_RESULT_CONTENT_UNSUPPORTED;
1050c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov                }
1051d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn                break;
1052d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn            default:
10539b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
10540214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu                                        "that is not fed MPEG-2 TS data or AAC ADTS data");
10550214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu                return SL_RESULT_CONTENT_UNSUPPORTED;
10569718cf5e5837d20983cab695d0f54834ffa3b2f4Kenny Root            }
1057258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani        }
10580b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani        break;
1059483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani        default:
10609f837a99d48c5bb8ad7fbc133943e5bf622ce065Jeff Sharkey            SL_LOGE("Cannot create player with SL_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
1061483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani                    "without SL_DATAFORMAT_MIME format");
10629b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            return SL_RESULT_CONTENT_UNSUPPORTED;
10639b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        }
10649b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    }
1065c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    break; // case SL_DATALOCATOR_ANDROIDBUFFERQUEUE
10669b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    //------------------
1067c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    //   Address
1068c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    case SL_DATALOCATOR_ADDRESS:
10699b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    case SL_DATALOCATOR_IODEVICE:
1070c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    case SL_DATALOCATOR_OUTPUTMIX:
1071c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    case XA_DATALOCATOR_NATIVEDISPLAY:
1072c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
10739b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        SL_LOGE("Cannot create audio player with data locator type 0x%x",
1074c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                (unsigned) sourceLocatorType);
1075161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        return SL_RESULT_CONTENT_UNSUPPORTED;
10760214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    default:
10771bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate        SL_LOGE("Cannot create audio player with invalid data locator type 0x%x",
10781bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate                (unsigned) sourceLocatorType);
1079cbeb114881c2bd3408ce302b0d48cb2449f1dcb0Andreas Gampe        return SL_RESULT_PARAMETER_INVALID;
10801bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    }// switch (locatorType)
10811bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate
10821bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    return SL_RESULT_SUCCESS;
10831bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate}
10841bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate
10851bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate
10861bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate//-----------------------------------------------------------------------------
1087161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian// Callback associated with an AudioTrack of an SL ES AudioPlayer that gets its data
1088161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian// from a buffer queue. This will not be called once the AudioTrack has been destroyed.
10891bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tatestatic void audioTrack_callBack_pullFromBuffQueue(int event, void* user, void *info) {
10901bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    CAudioPlayer *ap = (CAudioPlayer *)user;
10911bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate
10926038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate    if (!android::CallbackProtector::enterCbIfOk(ap->mCallbackProtector)) {
1093e012a235569fe307d165dfd0784ae847d0b13739Christopher Tate        // it is not safe to enter the callback (the track is about to go away)
10946038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        return;
10956038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate    }
1096e012a235569fe307d165dfd0784ae847d0b13739Christopher Tate
1097e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate    void * callbackPContext = NULL;
1098e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate    switch(event) {
1099e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate
1100e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate    case android::AudioTrack::EVENT_MORE_DATA: {
1101e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        //SL_LOGV("received event EVENT_MORE_DATA from AudioTrack TID=%d", gettid());
1102e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        slBufferQueueCallback callback = NULL;
1103e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        slPrefetchCallback prefetchCallback = NULL;
1104e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        void *prefetchContext = NULL;
1105e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
1106e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        android::AudioTrack::Buffer* pBuff = (android::AudioTrack::Buffer*)info;
1107e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate
1108e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        // retrieve data from the buffer queue
1109e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        interface_lock_exclusive(&ap->mBufferQueue);
1110e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate
1111e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate        if (ap->mBufferQueue.mState.count != 0) {
1112e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            //SL_LOGV("nbBuffers in queue = %u",ap->mBufferQueue.mState.count);
1113e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            assert(ap->mBufferQueue.mFront != ap->mBufferQueue.mRear);
1114e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate
1115e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            BufferHeader *oldFront = ap->mBufferQueue.mFront;
1116e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            BufferHeader *newFront = &oldFront[1];
1117e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate
1118e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            // declared as void * because this code supports both 8-bit and 16-bit PCM data
1119e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            void *pSrc = (char *)oldFront->mBuffer + ap->mBufferQueue.mSizeConsumed;
1120e9fd1fa31ad6f62d1eb6f32cdcdab50349f246ebChristopher Tate            if (ap->mBufferQueue.mSizeConsumed + pBuff->size < oldFront->mSize) {
1121e46fbfaf2e5759b54091dd62e2e9cf14a8545fcfJeff Sharkey                // can't consume the whole or rest of the buffer in one shot
1122828166bca4b21c38e59c1d6d651555095dee33a3Svetoslav Ganov                ap->mBufferQueue.mSizeConsumed += pBuff->size;
1123b23346639b66783c1662fd8ffa5345ef5cef336cRussell Brenner                // leave pBuff->size untouched
1124828166bca4b21c38e59c1d6d651555095dee33a3Svetoslav Ganov                // consume data
1125a9c2500a6863dabdd786f17a25ce0bf3683109a2Svetoslav Ganov                // FIXME can we avoid holding the lock during the copy?
112605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root                memcpy (pBuff->raw, pSrc, pBuff->size);
1127ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            } else {
1128ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // finish consuming the buffer or consume the buffer in one shot
1129ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                pBuff->size = oldFront->mSize - ap->mBufferQueue.mSizeConsumed;
1130ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                ap->mBufferQueue.mSizeConsumed = 0;
1131ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1132ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                if (newFront ==
1133ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                        &ap->mBufferQueue.mArray
1134ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                            [ap->mBufferQueue.mNumBuffers + 1])
1135ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                {
1136ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                    newFront = ap->mBufferQueue.mArray;
11370547ce55ebb2754c69cabe2b8c4687139b87cd5eBrian Carlstrom                }
11387c5c864c8a6690243e1cea13c5ff37add16b1744Brian Carlstrom                ap->mBufferQueue.mFront = newFront;
11390547ce55ebb2754c69cabe2b8c4687139b87cd5eBrian Carlstrom
11400547ce55ebb2754c69cabe2b8c4687139b87cd5eBrian Carlstrom                ap->mBufferQueue.mState.count--;
11417c5c864c8a6690243e1cea13c5ff37add16b1744Brian Carlstrom                ap->mBufferQueue.mState.playIndex++;
11427c5c864c8a6690243e1cea13c5ff37add16b1744Brian Carlstrom
1143ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // consume data
1144ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // FIXME can we avoid holding the lock during the copy?
1145112a72063846bb3bb18963c861acbe1efd8bd754Brian Carlstrom                memcpy (pBuff->raw, pSrc, pBuff->size);
1146ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1147ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // data has been consumed, and the buffer queue state has been updated
1148ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // we will notify the client if applicable
1149ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                callback = ap->mBufferQueue.mCallback;
1150ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // save callback data
1151ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                callbackPContext = ap->mBufferQueue.mContext;
1152ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            }
1153ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        } else { // empty queue
11547395a8ab8a7c6b03c32500c934694dde80b9ade1Brian Carlstrom            // signal no data available
1155ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            pBuff->size = 0;
1156ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1157112a72063846bb3bb18963c861acbe1efd8bd754Brian Carlstrom            // signal we're at the end of the content, but don't pause (see note in function)
1158ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            audioPlayer_dispatch_headAtEnd_lockPlay(ap, false /*set state to paused?*/, false);
1159ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1160ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            // signal underflow to prefetch status itf
1161ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
1162ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
1163ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                ap->mPrefetchStatus.mLevel = 0;
1164ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                // callback or no callback?
1165ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
1166112a72063846bb3bb18963c861acbe1efd8bd754Brian Carlstrom                        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
1167ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
1168ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                    prefetchCallback = ap->mPrefetchStatus.mCallback;
1169ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                    prefetchContext  = ap->mPrefetchStatus.mContext;
1170ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                }
1171ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            }
1172ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1173ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            // stop the track so it restarts playing faster when new data is enqueued
1174ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            ap->mAudioTrack->stop();
1175ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        }
1176ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        interface_unlock_exclusive(&ap->mBufferQueue);
1177ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1178ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        // notify client
1179ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        if (NULL != prefetchCallback) {
1180ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            assert(SL_PREFETCHEVENT_NONE != prefetchEvents);
1181ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            // spec requires separate callbacks for each event
1182ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            if (prefetchEvents & SL_PREFETCHEVENT_STATUSCHANGE) {
1183ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1184ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                        SL_PREFETCHEVENT_STATUSCHANGE);
1185ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            }
1186ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            if (prefetchEvents & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
1187ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom                (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
1188ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom                        SL_PREFETCHEVENT_FILLLEVELCHANGE);
1189ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            }
1190ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        }
1191ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        if (NULL != callback) {
1192ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            (*callback)(&ap->mBufferQueue.mItf, callbackPContext);
1193ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        }
1194ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    }
1195ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    break;
1196ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1197ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    case android::AudioTrack::EVENT_MARKER:
1198ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        //SL_LOGI("received event EVENT_MARKER from AudioTrack");
1199ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        audioTrack_handleMarker_lockPlay(ap);
1200ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        break;
1201ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1202ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    case android::AudioTrack::EVENT_NEW_POS:
1203ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        //SL_LOGI("received event EVENT_NEW_POS from AudioTrack");
1204ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        audioTrack_handleNewPos_lockPlay(ap);
1205ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        break;
1206ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1207ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    case android::AudioTrack::EVENT_UNDERRUN:
1208ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        //SL_LOGI("received event EVENT_UNDERRUN from AudioTrack");
1209ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        audioTrack_handleUnderrun_lockPlay(ap);
1210ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        break;
1211ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1212ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    case android::AudioTrack::EVENT_BUFFER_END:
1213ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    case android::AudioTrack::EVENT_LOOP_END:
1214ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        // These are unexpected so fall through
1215ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    default:
1216ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        // FIXME where does the notification of SL_PLAYEVENT_HEADMOVING fit?
121783dce3642abb44fb83384a2e95ce2b89bfd80e20David Brazdil        SL_LOGE("Encountered unknown AudioTrack event %d for CAudioPlayer %p", event,
121883dce3642abb44fb83384a2e95ce2b89bfd80e20David Brazdil                (CAudioPlayer *)user);
121983dce3642abb44fb83384a2e95ce2b89bfd80e20David Brazdil        break;
1220ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    }
1221ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1222ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    ap->mCallbackProtector->exitCb();
1223ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom}
1224ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
12250547ce55ebb2754c69cabe2b8c4687139b87cd5eBrian Carlstrom
1226ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom//-----------------------------------------------------------------------------
1227ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstromvoid android_audioPlayer_create(CAudioPlayer *pAudioPlayer) {
1228ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1229ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    // pAudioPlayer->mAndroidObjType has been set in android_audioPlayer_checkSourceSink()
1230ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    // and if it was == INVALID_TYPE, then IEngine_CreateAudioPlayer would never call us
1231ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    assert(INVALID_TYPE != pAudioPlayer->mAndroidObjType);
1232ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1233ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    // These initializations are in the same order as the field declarations in classes.h
1234ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1235ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // FIXME Consolidate initializations (many of these already in IEngine_CreateAudioPlayer)
1236ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // mAndroidObjType: see above comment
1237ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
1238ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
1239ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
124014e7acd58c8b4f9f2fd517cded5c4e3099fd5989David Brazdil    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
1241ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // android::AudioSystem::acquireAudioSessionId(pAudioPlayer->mSessionId);
1242ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1243ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
1244ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1245ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // mAudioTrack
1246ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mCallbackProtector = new android::CallbackProtector();
1247ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // mAPLayer
1248ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // mAuxEffect
1249ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1250ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mAuxSendLevel = 0;
1251ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
1252ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    pAudioPlayer->mDeferredStart = false;
1253ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1254ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // This section re-initializes interface-specific fields that
1255ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // can be set or used regardless of whether the interface is
1256ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    // exposed on the AudioPlayer or not
1257ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1258ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    switch (pAudioPlayer->mAndroidObjType) {
1259ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1260ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        pAudioPlayer->mPlaybackRate.mMinRate = AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE;
1261ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        pAudioPlayer->mPlaybackRate.mMaxRate = AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE;
1262ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        break;
1263ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    case AUDIOPLAYER_FROM_URIFD:
1264ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        pAudioPlayer->mPlaybackRate.mMinRate = MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE;
1265ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        pAudioPlayer->mPlaybackRate.mMaxRate = MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE;
1266ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        break;
1267ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    default:
1268ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        // use the default range
1269ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        break;
1270ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    }
1271ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1272ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom}
1273ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1274ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1275ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom//-----------------------------------------------------------------------------
1276ca82e616d3131570bf2ee29778f4796f343720d5Brian CarlstromSLresult android_audioPlayer_setConfig(CAudioPlayer *ap, const SLchar *configKey,
1277ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        const void *pConfigValue, SLuint32 valueSize) {
1278ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1279ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    SLresult result;
1280ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1281ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    assert(NULL != ap && NULL != configKey && NULL != pConfigValue);
1282ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1283ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1284ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        // stream type
1285ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        if (KEY_STREAM_TYPE_PARAMSIZE > valueSize) {
1286ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1287ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            result = SL_RESULT_BUFFER_INSUFFICIENT;
1288ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        } else {
1289ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom            result = audioPlayer_setStreamType(ap, *(SLuint32*)pConfigValue);
1290ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        }
1291ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1292ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    } else {
1293ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1294ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        result = SL_RESULT_PARAMETER_INVALID;
1295ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    }
1296ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom
1297ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    return result;
1298ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom}
1299ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1300ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1301ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom//-----------------------------------------------------------------------------
1302ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian CarlstromSLresult android_audioPlayer_getConfig(CAudioPlayer* ap, const SLchar *configKey,
1303ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        SLuint32* pValueSize, void *pConfigValue) {
1304ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1305ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    SLresult result;
1306ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1307ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    assert(NULL != ap && NULL != configKey && NULL != pValueSize);
1308ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_STREAM_TYPE) == 0) {
1309ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1310ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        // stream type
1311ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        if (NULL == pConfigValue) {
1312ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            result = SL_RESULT_SUCCESS;
1313ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        } else if (KEY_STREAM_TYPE_PARAMSIZE > *pValueSize) {
1314ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
1315ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            result = SL_RESULT_BUFFER_INSUFFICIENT;
1316ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        } else {
1317ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom            result = audioPlayer_getStreamType(ap, (SLint32*)pConfigValue);
1318ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        }
1319ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom        *pValueSize = KEY_STREAM_TYPE_PARAMSIZE;
1320ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1321ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    } else {
1322ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
1323ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom        result = SL_RESULT_PARAMETER_INVALID;
1324ca82e616d3131570bf2ee29778f4796f343720d5Brian Carlstrom    }
1325ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom
1326ff1ec4d9e7b7eb1b6303d147c796f8767ee6715bBrian Carlstrom    return result;
13270214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu}
13289b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu
13298946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu
13308946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu// Called from android_audioPlayer_realize for a PCM buffer queue player
13319b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu// to determine if it can use a fast track.
13329b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapustatic bool canUseFastTrack(CAudioPlayer *pAudioPlayer)
13339b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu{
13349b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    assert(pAudioPlayer->mAndroidObjType == AUDIOPLAYER_FROM_PCM_BUFFERQUEUE);
13359b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    if (pAudioPlayer->mBufferQueue.mNumBuffers < 2) {
1336d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        return false;
133727b89e6658a0d233a53f5d7ca20dc57fec82d955Amith Yamasani    }
133847f0795d171a25d30ee5b48a6ff1828fb5c92c19Xiaohui Chen
1339d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    // Check a blacklist of interfaces that are incompatible with fast tracks.
13409b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // The alternative, to check a whitelist of compatible interfaces, is
13419b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // more maintainable but is too slow.  As a compromise, in a debug build
13429b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // we use both methods and warn if they produce different results.
1343d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    // In release builds, we only use the blacklist method.
13449b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // If a blacklisted interface is added after realization using
13459b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // DynamicInterfaceManagement::AddInterface,
13469b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    // then this won't be detected but the interface will be ineffective.
13479b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    bool blacklistResult = true;
13489b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    static const unsigned blacklist[] = {
13499b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_BASSBOOST,
1350d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        MPH_EFFECTSEND,
13519b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_ENVIRONMENTALREVERB,
1352d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        MPH_EQUALIZER,
13539b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_PLAYBACKRATE,
1354c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu        MPH_PRESETREVERB,
13550214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        MPH_VIRTUALIZER,
13560214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        MPH_ANDROIDEFFECT,
13570214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        MPH_ANDROIDEFFECTSEND,
13587d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        // FIXME The problem with a blacklist is remembering to add new interfaces here
13590214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    };
1360d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    for (unsigned i = 0; i < sizeof(blacklist)/sizeof(blacklist[0]); ++i) {
1361d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        if (IsInterfaceInitialized(&pAudioPlayer->mObject, blacklist[i])) {
1362d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn            blacklistResult = false;
1363d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn            break;
1364d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        }
1365d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    }
13662a880312086147577e1e814bda6985fa97fb343bJeff Davidson#if LOG_NDEBUG == 0
1367d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    bool whitelistResult = true;
13680214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    static const unsigned whitelist[] = {
1369c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu        MPH_BUFFERQUEUE,
13708946dd3355fc1dcbad872c0546e356474d4cc5deSuchi Amalapurapu        MPH_DYNAMICINTERFACEMANAGEMENT,
13719b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_METADATAEXTRACTION,
1372c895be7bc68b6f5b37fbb9881f464dd5ea0eb017Dianne Hackborn        MPH_MUTESOLO,
13739b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_OBJECT,
13749b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_PLAY,
13759b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_PREFETCHSTATUS,
13769b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        MPH_VOLUME,
13771a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        MPH_ANDROIDCONFIGURATION,
13781a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        MPH_ANDROIDSIMPLEBUFFERQUEUE,
13791a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        MPH_ANDROIDBUFFERQUEUESOURCE,
13801a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    };
13811a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
13821a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        for (unsigned i = 0; i < sizeof(whitelist)/sizeof(whitelist[0]); ++i) {
13831a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy            if (mph == whitelist[i]) {
13841a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                goto compatible;
13851a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy            }
13861a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        }
13871a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        if (IsInterfaceInitialized(&pAudioPlayer->mObject, mph)) {
13881a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy            whitelistResult = false;
1389c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy            break;
13901a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        }
13911a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedycompatible: ;
13921a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    }
13931a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    if (whitelistResult != blacklistResult) {
13941a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        ALOGW("whitelistResult != blacklistResult");
13959b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        // and use blacklistResult below
13969b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    }
13979b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu#endif
13989b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    return blacklistResult;
13999b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu}
14009b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu
14019b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu
1402c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu//-----------------------------------------------------------------------------
1403c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
1404c028be4f3b8c7476b46859f66c3f33d528adf181Suchi AmalapurapuSLresult android_audioPlayer_realize(CAudioPlayer *pAudioPlayer, SLboolean async) {
1405c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu
1406c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    SLresult result = SL_RESULT_SUCCESS;
14075ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    SL_LOGV("Realize pAudioPlayer=%p", pAudioPlayer);
1408c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu
1409c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    AudioPlayback_Parameters app;
14101a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    app.sessionId = pAudioPlayer->mSessionId;
14111a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    app.streamType = pAudioPlayer->mStreamType;
1412c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu
14139b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu    switch (pAudioPlayer->mAndroidObjType) {
1414161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian
1415161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian    //-----------------------------------
1416161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian    // AudioTrack
1417161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1418161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        {
1419161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        // initialize platform-specific CAudioPlayer fields
1420161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian
1421c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy        SLDataLocator_BufferQueue *dl_bq = (SLDataLocator_BufferQueue *)
1422c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                pAudioPlayer->mDynamicSource.mDataSource;
14231a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        SLDataFormat_PCM *df_pcm = (SLDataFormat_PCM *)
14241a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                pAudioPlayer->mDynamicSource.mDataSource->pFormat;
14251a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy
14261a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
14271a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy
1428161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        audio_output_flags_t policy;
1429161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        if (canUseFastTrack(pAudioPlayer)) {
1430161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian            policy = AUDIO_OUTPUT_FLAG_FAST;
1431161bd9aae46088cb62e78af428ef9f2b1172c0dcoleksii stepanian        } else {
14329b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            policy = AUDIO_OUTPUT_FLAG_NONE;
14339b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        }
14349b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu
14355b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu        pAudioPlayer->mAudioTrack = new android::AudioTrack(
14361a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                pAudioPlayer->mStreamType,                           // streamType
14371a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                sampleRate,                                          // sampleRate
14381a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                sles_to_android_sampleFormat(df_pcm->bitsPerSample), // format
14397d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                sles_to_android_channelMaskOut(df_pcm->numChannels, df_pcm->channelMask),
14407d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                                                                     // channel mask
14417d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                0,                                                   // frameCount
14427d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                policy,                                              // flags
14437d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                audioTrack_callBack_pullFromBuffQueue,               // callback
14447d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                (void *) pAudioPlayer,                               // user
14457d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                0,     // FIXME find appropriate frame count         // notificationFrame
14467d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                pAudioPlayer->mSessionId);
14477d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        android::status_t status = pAudioPlayer->mAudioTrack->initCheck();
14487d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        if (status != android::NO_ERROR) {
14497d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn            SL_LOGE("AudioTrack::initCheck status %u", status);
14507d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn            result = SL_RESULT_CONTENT_UNSUPPORTED;
14517d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn            pAudioPlayer->mAudioTrack.clear();
14527d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn            return result;
14537d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        }
14547d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn
14557d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        // initialize platform-independent CAudioPlayer fields
14567d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn
14577d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        pAudioPlayer->mNumChannels = df_pcm->numChannels;
14587d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        pAudioPlayer->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
14597d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn
14607d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        // This use case does not have a separate "prepare" step
14617d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        pAudioPlayer->mAndroidObjState = ANDROID_READY;
14627d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn        }
1463f74aa094b413f113f7dd8cef0ce28fb933a27a5dChristopher Tate        break;
14647d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn
14657d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn    //-----------------------------------
14667d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn    // MediaPlayer
14671a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    case AUDIOPLAYER_FROM_URIFD: {
14689b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        pAudioPlayer->mAPlayer = new android::LocAVPlayer(&app, false /*hasVideo*/);
14699b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent,
14709b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                        (void*)pAudioPlayer /*notifUSer*/);
1471a2fd9d1786fec65dc4199e29c78dd43e1e31bb58Dianne Hackborn
14729b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
14739b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            case SL_DATALOCATOR_URI: {
14749b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // The legacy implementation ran Stagefright within the application process, and
14755ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                // so allowed local pathnames specified by URI that were openable by
14765ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                // the application but were not openable by mediaserver.
14779b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // The current implementation runs Stagefright (mostly) within mediaserver,
14789b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // which runs as a different UID and likely a different current working directory.
14799b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // For backwards compatibility with any applications which may have relied on the
14809b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // previous behavior, we convert an openable file URI into an FD.
14819b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // Note that unlike SL_DATALOCATOR_ANDROIDFD, this FD is owned by us
1482a2fd9d1786fec65dc4199e29c78dd43e1e31bb58Dianne Hackborn                // and so we close it as soon as we've passed it (via Binder dup) to mediaserver.
14839b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                const char *uri = (const char *)pAudioPlayer->mDataSource.mLocator.mURI.URI;
14849b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                if (!isDistantProtocol(uri)) {
14859b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                    // don't touch the original uri, we may need it later
1486c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                    const char *pathname = uri;
1487c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                    // skip over an optional leading file:// prefix
14889b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                    if (!strncasecmp(pathname, "file://", 7)) {
14899b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                        pathname += 7;
1490af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu                    }
1491af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu                    // attempt to open it as a file using the application's credentials
1492af8e9f4805643f90a9dc0ecfa119e0a860c12f8aSuchi Amalapurapu                    int fd = ::open(pathname, O_RDONLY);
1493c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                    if (fd >= 0) {
14945ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                        // if open is successful, then check to see if it's a regular file
14957d608423b721e0153f37bfd5eba78fcd2489562dDianne Hackborn                        struct stat statbuf;
14965ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                        if (!::fstat(fd, &statbuf) && S_ISREG(statbuf.st_mode)) {
14975ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                            // treat similarly to an FD data locator, but
14985ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                            // let setDataSource take responsibility for closing fd
14999b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                            pAudioPlayer->mAPlayer->setDataSource(fd, 0, statbuf.st_size, true);
15005ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                            break;
15015ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                        }
15029b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                        // we were able to open it, but it's not a file, so let mediaserver try
15039b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                        (void) ::close(fd);
15045ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                    }
15059b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                }
15069b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                // if either the URI didn't look like a file, or open failed, or not a file
15079b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                pAudioPlayer->mAPlayer->setDataSource(uri);
15089b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                } break;
1509c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu            case SL_DATALOCATOR_ANDROIDFD: {
15105ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
1511c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                pAudioPlayer->mAPlayer->setDataSource(
1512c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu                        (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
15139b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                        offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
15145ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                                (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
1515c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                        (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
1516c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                }
1517c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy                break;
15189b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu            default:
15199b10ef5fe85e9d29721ff0cd15161f960d38a8dbSuchi Amalapurapu                SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
15205ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root                break;
152186a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn        }
152260f7ad8a8bfbc8f98510a0af94371e3a1caacdc2Kenny Root
15230214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        }
15240214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        break;
1525d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
15260214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    //-----------------------------------
152786a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn    // StreamPlayer
152886a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: {
152986a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn        android::StreamPlayer* splr = new android::StreamPlayer(&app, false /*hasVideo*/,
15300214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu                &pAudioPlayer->mAndroidBufferQueue, pAudioPlayer->mCallbackProtector);
15310214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        pAudioPlayer->mAPlayer = splr;
15320214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        splr->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
15330214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        }
15340214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        break;
153586a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn
153686a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn    //-----------------------------------
15370214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    // AudioToCbRenderer
15381e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
15391e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        android::AudioToCbRenderer* decoder = new android::AudioToCbRenderer(&app);
15401e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        pAudioPlayer->mAPlayer = decoder;
15411e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        // configures the callback for the sink buffer queue
15421e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        decoder->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
15431e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        // configures the callback for the notifications coming from the SF code
15441e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        decoder->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
15451e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate
15461e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        switch (pAudioPlayer->mDataSource.mLocator.mLocatorType) {
15471e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATALOCATOR_URI:
15481e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            decoder->setDataSource(
15491e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                    (const char*)pAudioPlayer->mDataSource.mLocator.mURI.URI);
15501e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            break;
15511e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate        case SL_DATALOCATOR_ANDROIDFD: {
15521e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            int64_t offset = (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.offset;
15531e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate            decoder->setDataSource(
15541e08f5c3b358b75792a1839f758bc61409f71a58Christopher Tate                    (int)pAudioPlayer->mDataSource.mLocator.mFD.fd,
15550214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
155686a72dacbea3331cd5423c1f2f6ecbfae535e57cDianne Hackborn                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
15570214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu                            (int64_t)pAudioPlayer->mDataSource.mLocator.mFD.length);
15580214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu            }
15590214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu            break;
15600214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        default:
156160f7ad8a8bfbc8f98510a0af94371e3a1caacdc2Kenny Root            SL_LOGE(ERROR_PLAYERREALIZE_UNKNOWN_DATASOURCE_LOCATOR);
15620214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu            break;
1563d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        }
15640214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu
15650214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        }
1566e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        break;
1567d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
1568752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey    //-----------------------------------
1569752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey    // AacBqToPcmCbRenderer
1570752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
1571e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        android::AacBqToPcmCbRenderer* bqtobq = new android::AacBqToPcmCbRenderer(&app,
1572752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey                &pAudioPlayer->mAndroidBufferQueue);
15737767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn        // configures the callback for the sink buffer queue
15747767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn        bqtobq->setDataPushListener(adecoder_writeToBufferQueue, pAudioPlayer);
1575752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey        pAudioPlayer->mAPlayer = bqtobq;
1576752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey        // configures the callback for the notifications coming from the SF code,
15777767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn        // but also implicitly configures the AndroidBufferQueue from which ADTS data is read
15787767eac3232ba2fb9828766813cdb481d6a97584Dianne Hackborn        pAudioPlayer->mAPlayer->init(sfplayer_handlePrefetchEvent, (void*)pAudioPlayer);
1579752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey        }
1580752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey        break;
1581e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn
1582e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    //-----------------------------------
1583d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    default:
1584752cd922f7091dfd5401faf70dc248934a9dbb6dJeff Sharkey        SL_LOGE(ERROR_PLAYERREALIZE_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1585e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        result = SL_RESULT_INTERNAL_ERROR;
15861bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate        break;
15871bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    }
15882699f065558ba78066887210b0c7346105959860Todd Kennedy
15891bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    // proceed with effect initialization
15905cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate    // initialize EQ
15911bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    // FIXME use a table of effect descriptors when adding support for more effects
15921bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    if (memcmp(SL_IID_EQUALIZER, &pAudioPlayer->mEqualizer.mEqDescriptor.type,
15931bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate            sizeof(effect_uuid_t)) == 0) {
15941bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate        SL_LOGV("Need to initialize EQ for AudioPlayer=%p", pAudioPlayer);
1595f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        android_eq_init(pAudioPlayer->mSessionId, &pAudioPlayer->mEqualizer);
1596f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1597f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    // initialize BassBoost
1598f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (memcmp(SL_IID_BASSBOOST, &pAudioPlayer->mBassBoost.mBassBoostDescriptor.type,
159939bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy            sizeof(effect_uuid_t)) == 0) {
160039bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy        SL_LOGV("Need to initialize BassBoost for AudioPlayer=%p", pAudioPlayer);
1601f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        android_bb_init(pAudioPlayer->mSessionId, &pAudioPlayer->mBassBoost);
1602f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1603f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    // initialize Virtualizer
160439bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    if (memcmp(SL_IID_VIRTUALIZER, &pAudioPlayer->mVirtualizer.mVirtualizerDescriptor.type,
16055cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate               sizeof(effect_uuid_t)) == 0) {
16065cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate        SL_LOGV("Need to initialize Virtualizer for AudioPlayer=%p", pAudioPlayer);
1607f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        android_virt_init(pAudioPlayer->mSessionId, &pAudioPlayer->mVirtualizer);
1608f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1609f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1610f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    // initialize EffectSend
1611f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    // FIXME initialize EffectSend
1612f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
161339bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    return result;
16145cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate}
16155cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate
1616f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate
1617f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//-----------------------------------------------------------------------------
1618f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov/**
16191a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy * Called with a lock on AudioPlayer, and blocks until safe to destroy
16201a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy */
16211a350157198bd8700f1e81b8ce3f7c656f91dba9Todd KennedySLresult android_audioPlayer_preDestroy(CAudioPlayer *pAudioPlayer) {
16221a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy    SL_LOGD("android_audioPlayer_preDestroy(%p)", pAudioPlayer);
16231bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    SLresult result = SL_RESULT_SUCCESS;
1624a2fd9d1786fec65dc4199e29c78dd43e1e31bb58Dianne Hackborn
16251bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    bool disableCallbacksBeforePreDestroy;
1626c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy    switch (pAudioPlayer->mAndroidObjType) {
1627c8a465c4d3827970f61555e604c43ef3b3f6d4d6Todd Kennedy    // Not yet clear why this order is important, but it reduces detected deadlocks
16281bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1629e99bb5f10b90736d10cee9729b56cba156fc0921Suchi Amalapurapu        disableCallbacksBeforePreDestroy = true;
16303d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        break;
16313d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    // Use the old behavior for all other use cases until proven
16323d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    // case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
16333d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    default:
16343d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        disableCallbacksBeforePreDestroy = false;
16353d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        break;
16363d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    }
16373d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu
16383d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    if (disableCallbacksBeforePreDestroy) {
1639ba24e4d8bbeb60e96d74f05e21691dad61ce497eDianne Hackborn        object_unlock_exclusive(&pAudioPlayer->mObject);
16406dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root        if (pAudioPlayer->mCallbackProtector != 0) {
16413d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu            pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
16423d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        }
16433d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        object_lock_exclusive(&pAudioPlayer->mObject);
16443d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    }
16453d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu
16463d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    if (pAudioPlayer->mAPlayer != 0) {
16473d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu        pAudioPlayer->mAPlayer->preDestroy();
16483d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    }
16493d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    SL_LOGD("android_audioPlayer_preDestroy(%p) after mAPlayer->preDestroy()", pAudioPlayer);
16503d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu
16513d24425165aabfd2a8d5e5f973f085c6e6446341Suchi Amalapurapu    if (!disableCallbacksBeforePreDestroy) {
1652e99bb5f10b90736d10cee9729b56cba156fc0921Suchi Amalapurapu        object_unlock_exclusive(&pAudioPlayer->mObject);
1653e99bb5f10b90736d10cee9729b56cba156fc0921Suchi Amalapurapu        if (pAudioPlayer->mCallbackProtector != 0) {
1654d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn            pAudioPlayer->mCallbackProtector->requestCbExitAndWait();
1655d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        }
1656d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn        object_lock_exclusive(&pAudioPlayer->mObject);
1657d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    }
1658483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani
1659447106fc839520d18dcb367ba17fc8ec345bb9e8Kenny Root    return result;
1660483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani}
1661d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
1662d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
1663d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn//-----------------------------------------------------------------------------
1664483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith YamasaniSLresult android_audioPlayer_destroy(CAudioPlayer *pAudioPlayer) {
1665e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    SLresult result = SL_RESULT_SUCCESS;
1666e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    SL_LOGV("android_audioPlayer_destroy(%p)", pAudioPlayer);
1667483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    switch (pAudioPlayer->mAndroidObjType) {
1668483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani
1669483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1670483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani        // We own the audio track for PCM buffer queue players
1671483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani        if (pAudioPlayer->mAudioTrack != 0) {
1672e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            pAudioPlayer->mAudioTrack->stop();
1673e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            // Note that there may still be another reference in post-unlock phase of SetPlayState
1674e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn            pAudioPlayer->mAudioTrack.clear();
1675c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        }
1676c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        break;
1677c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov
1678c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    case AUDIOPLAYER_FROM_URIFD:     // intended fall-through
1679c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
1680c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: // intended fall-through
1681c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1682c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        pAudioPlayer->mAPlayer.clear();
16835ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        break;
16845ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    //-----------------------------------
168505ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    default:
16865ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        SL_LOGE(ERROR_PLAYERDESTROY_UNEXPECTED_OBJECT_TYPE_D, pAudioPlayer->mAndroidObjType);
1687d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings        result = SL_RESULT_INTERNAL_ERROR;
168805ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        break;
1689941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    }
169057dcf5b177b56195421535938544f32d8b591b42Jeff Sharkey
1691be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey    // placeholder: not necessary yet as session ID lifetime doesn't extend beyond player
16925ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    // android::AudioSystem::releaseAudioSessionId(pAudioPlayer->mSessionId);
16935ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root
1694a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    pAudioPlayer->mCallbackProtector.clear();
1695a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings
1696a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    // explicit destructor
1697be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey    pAudioPlayer->mAudioTrack.~sp();
1698d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings    // note that SetPlayState(PLAYING) may still hold a reference
1699d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings    pAudioPlayer->mCallbackProtector.~sp();
1700be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey    pAudioPlayer->mAuxEffect.~sp();
1701d55deb0a7163a40fe9772ce659f0a3e3ed340de3rich cannings    pAudioPlayer->mAPlayer.~sp();
1702d55deb0a7163a40fe9772ce659f0a3e3ed340de3rich cannings
1703d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings    return result;
1704d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings}
1705d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings
1706d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings
1707d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0crich cannings//-----------------------------------------------------------------------------
1708d1b5cfc94ae940f42be352e7ed98c21c973471b2rich canningsSLresult android_audioPlayer_setPlaybackRateAndConstraints(CAudioPlayer *ap, SLpermille rate,
1709be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey        SLuint32 constraints) {
1710d55deb0a7163a40fe9772ce659f0a3e3ed340de3rich cannings    SLresult result = SL_RESULT_SUCCESS;
1711d55deb0a7163a40fe9772ce659f0a3e3ed340de3rich cannings    switch(ap->mAndroidObjType) {
1712a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE: {
1713a6cfe52eb83995b124efec5f73bcb179caadf888rich cannings        // these asserts were already checked by the platform-independent layer
17141a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        assert((AUDIOTRACK_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
17151a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy                (rate <= AUDIOTRACK_MAX_PLAYBACKRATE_PERMILLE));
17161a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
17175ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        // get the content sample rate
17185ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        uint32_t contentRate = sles_to_android_sampleRate(ap->mSampleRateMilliHz);
17195ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        // apply the SL ES playback rate on the AudioTrack as a factor of its content sample rate
17205ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        if (ap->mAudioTrack != 0) {
17215ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root            ap->mAudioTrack->setSampleRate(contentRate * (rate/1000.0f));
17225ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
17235ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
17245ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        break;
172505ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    case AUDIOPLAYER_FROM_URIFD: {
172605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        assert((MEDIAPLAYER_MIN_PLAYBACKRATE_PERMILLE <= rate) &&
1727a503a0f5d407fd10528e26b6eaed0e4e1d3badc1Kenny Root                        (rate <= MEDIAPLAYER_MAX_PLAYBACKRATE_PERMILLE));
17285ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        assert(constraints & SL_RATEPROP_NOPITCHCORAUDIO);
17295ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        // apply the SL ES playback rate on the GenericPlayer
17305ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        if (ap->mAPlayer != 0) {
173105ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root            ap->mAPlayer->setPlaybackRate((int16_t)rate);
17325ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
173305ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        }
173405ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        break;
173505ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root
173605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    default:
173705ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        SL_LOGE("Unexpected object type %d", ap->mAndroidObjType);
173805ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        result = SL_RESULT_FEATURE_UNSUPPORTED;
1739941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey        break;
174005ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    }
174105ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    return result;
174205ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root}
174305ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root
1744be520fba1e45c77ca20eb66005a0cf19e10939a1Jeff Sharkey
1745d55deb0a7163a40fe9772ce659f0a3e3ed340de3rich cannings//-----------------------------------------------------------------------------
174605ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root// precondition
174705ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root//  called with no lock held
174805ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root//  ap != NULL
174905ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root//  pItemCount != NULL
175005ca4c90644921df9193d92b2abdc81ef77e4a62Kenny RootSLresult android_audioPlayer_metadata_getItemCount(CAudioPlayer *ap, SLuint32 *pItemCount) {
175105ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root    if (ap->mAPlayer == 0) {
175205ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root        return SL_RESULT_PARAMETER_INVALID;
17535ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    }
17545ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root    switch(ap->mAndroidObjType) {
17551a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
17561a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
17575ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        {
17581a350157198bd8700f1e81b8ce3f7c656f91dba9Todd Kennedy            android::AudioSfDecoder* decoder =
175905ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
176005ca4c90644921df9193d92b2abdc81ef77e4a62Kenny Root            *pItemCount = decoder->getPcmFormatKeyCount();
17615ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        }
17625ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root        break;
17635ab2157bf1f105b02d3e2913cd3a33f9765b74caKenny Root      default:
17641c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        *pItemCount = 0;
17656038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate        break;
17666038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate    }
17676038d15cbc7f4648ceaadf5f15d1928c4899f98eChristopher Tate    return SL_RESULT_SUCCESS;
17681c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio}
17691c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
17701c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
17711c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//-----------------------------------------------------------------------------
17721c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio// precondition
17731c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  called with no lock held
17741c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  ap != NULL
17751c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  pKeySize != NULL
17761c1b47125da018b44240739db75f8898e064a948Fabrice Di MeglioSLresult android_audioPlayer_metadata_getKeySize(CAudioPlayer *ap,
17771c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        SLuint32 index, SLuint32 *pKeySize) {
17781c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    if (ap->mAPlayer == 0) {
17791c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        return SL_RESULT_PARAMETER_INVALID;
17801c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    }
17811c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    SLresult res = SL_RESULT_SUCCESS;
17821c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    switch(ap->mAndroidObjType) {
1783ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1784ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
17851c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        {
17861c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            android::AudioSfDecoder* decoder =
17871c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
17881c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            SLuint32 keyNameSize = 0;
17891c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            if (!decoder->getPcmFormatKeySize(index, &keyNameSize)) {
17901c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                res = SL_RESULT_PARAMETER_INVALID;
17911c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            } else {
1792ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn                // *pKeySize is the size of the region used to store the key name AND
1793ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn                //   the information about the key (size, lang, encoding)
17941c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio                *pKeySize = keyNameSize + sizeof(SLMetadataInfo);
17951c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio            }
17961c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        }
17971c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
17981c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio      default:
1799ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn        *pKeySize = 0;
18001c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        res = SL_RESULT_PARAMETER_INVALID;
18011c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio        break;
18021c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    }
18031c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio    return res;
18041c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio}
18051c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio
1806ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn
1807ab4bb9d1fec685dab0fce9232c9a3477fab356b3Dianne Hackborn//-----------------------------------------------------------------------------
18081c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio// precondition
18091c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  called with no lock held
18101c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  ap != NULL
18111c1b47125da018b44240739db75f8898e064a948Fabrice Di Meglio//  pKey != NULL
18121c1b47125da018b44240739db75f8898e064a948Fabrice Di MeglioSLresult android_audioPlayer_metadata_getKey(CAudioPlayer *ap,
18130214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        SLuint32 index, SLuint32 size, SLMetadataInfo *pKey) {
18140214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu    if (ap->mAPlayer == 0) {
18150214e9475fa3b9aa00a784b5152bf4f1939c941eSuchi Amalapurapu        return SL_RESULT_PARAMETER_INVALID;
1816c028be4f3b8c7476b46859f66c3f33d528adf181Suchi Amalapurapu    }
1817f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    SLresult res = SL_RESULT_SUCCESS;
181839bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy    switch(ap->mAndroidObjType) {
18195cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
182039bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1821f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        {
1822f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            android::AudioSfDecoder* decoder =
1823f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
182439bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy            if ((size < sizeof(SLMetadataInfo) ||
1825f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    (!decoder->getPcmFormatKeyName(index, size - sizeof(SLMetadataInfo),
1826f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                            (char*)pKey->data)))) {
1827f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                res = SL_RESULT_PARAMETER_INVALID;
1828f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            } else {
1829f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                // successfully retrieved the key value, update the other fields
1830f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                pKey->encoding = SL_CHARACTERENCODING_UTF8;
1831f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                memcpy((char *) pKey->langCountry, "en", 3);
1832f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                pKey->size = strlen((char*)pKey->data) + 1;
1833f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            }
1834f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        }
1835f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1836f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      default:
1837f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        res = SL_RESULT_PARAMETER_INVALID;
1838f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1839f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1840f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    return res;
1841f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov}
1842f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1843f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1844f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//-----------------------------------------------------------------------------
1845f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov// precondition
1846f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  called with no lock held
1847f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  ap != NULL
1848f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  pValueSize != NULL
1849f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet GanovSLresult android_audioPlayer_metadata_getValueSize(CAudioPlayer *ap,
1850f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        SLuint32 index, SLuint32 *pValueSize) {
1851f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (ap->mAPlayer == 0) {
1852f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        return SL_RESULT_PARAMETER_INVALID;
1853f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1854f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    SLresult res = SL_RESULT_SUCCESS;
1855f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    switch(ap->mAndroidObjType) {
1856f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1857f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1858f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        {
1859f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            android::AudioSfDecoder* decoder =
1860f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1861f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            SLuint32 valueSize = 0;
1862f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            if (!decoder->getPcmFormatValueSize(index, &valueSize)) {
1863f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                res = SL_RESULT_PARAMETER_INVALID;
1864f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            } else {
1865f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                // *pValueSize is the size of the region used to store the key value AND
1866f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                //   the information about the value (size, lang, encoding)
1867f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                *pValueSize = valueSize + sizeof(SLMetadataInfo);
1868f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            }
1869f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        }
1870f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1871f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      default:
1872f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov          *pValueSize = 0;
1873f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov          res = SL_RESULT_PARAMETER_INVALID;
1874f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov          break;
1875f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1876f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    return res;
1877f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov}
1878f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1879b52a461851f322b0edf3cb9383da5f449b533311Michal Karpinski
1880b52a461851f322b0edf3cb9383da5f449b533311Michal Karpinski//-----------------------------------------------------------------------------
1881f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov// precondition
1882f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  called with no lock held
1883f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  ap != NULL
1884f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  pValue != NULL
1885f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet GanovSLresult android_audioPlayer_metadata_getValue(CAudioPlayer *ap,
1886f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        SLuint32 index, SLuint32 size, SLMetadataInfo *pValue) {
1887f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (ap->mAPlayer == 0) {
1888f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        return SL_RESULT_PARAMETER_INVALID;
1889f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1890f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    SLresult res = SL_RESULT_SUCCESS;
1891f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    switch(ap->mAndroidObjType) {
1892f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
1893f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1894f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        {
1895f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            android::AudioSfDecoder* decoder =
1896f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    static_cast<android::AudioSfDecoder*>(ap->mAPlayer.get());
1897f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            pValue->encoding = SL_CHARACTERENCODING_BINARY;
1898f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            memcpy((char *) pValue->langCountry, "en", 3); // applicable here?
1899f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            SLuint32 valueSize = 0;
1900f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            if ((size < sizeof(SLMetadataInfo)
1901f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    || (!decoder->getPcmFormatValueSize(index, &valueSize))
1902f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                    || (!decoder->getPcmFormatKeyValue(index, size - sizeof(SLMetadataInfo),
1903f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                            (SLuint32*)pValue->data)))) {
19045cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate                res = SL_RESULT_PARAMETER_INVALID;
19055cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate            } else {
19065cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate                pValue->size = valueSize;
19075cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate            }
19085cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate        }
19095cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate        break;
19105cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate      default:
19115cf5578a457e448dda9fd47943e91f0f3b67690fChristopher Tate        res = SL_RESULT_PARAMETER_INVALID;
1912f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1913f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1914f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    return res;
1915f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov}
1916f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1917f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//-----------------------------------------------------------------------------
1918f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov// preconditions
1919f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  ap != NULL
1920f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  mutex is locked
1921f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//  play state has changed
1922f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganovvoid android_audioPlayer_setPlayState(CAudioPlayer *ap) {
1923f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1924f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    SLuint32 playState = ap->mPlay.mState;
1925f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    AndroidObjectState objState = ap->mAndroidObjState;
1926f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1927f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    switch(ap->mAndroidObjType) {
1928f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
1929f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        switch (playState) {
1930f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        case SL_PLAYSTATE_STOPPED:
1931f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_STOPPED");
1932f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            if (ap->mAudioTrack != 0) {
1933f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                ap->mAudioTrack->stop();
1934f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            }
1935f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            break;
1936f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        case SL_PLAYSTATE_PAUSED:
1937f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PAUSED");
1938f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            if (ap->mAudioTrack != 0) {
1939f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                ap->mAudioTrack->pause();
1940f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            }
1941f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            break;
1942f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        case SL_PLAYSTATE_PLAYING:
1943f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            SL_LOGV("setting AudioPlayer to SL_PLAYSTATE_PLAYING");
1944f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            if (ap->mAudioTrack != 0) {
1945f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                // instead of ap->mAudioTrack->start();
1946f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                ap->mDeferredStart = true;
1947f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            }
1948f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            break;
1949f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        default:
1950f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            // checked by caller, should not happen
1951f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov            break;
1952f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        }
1953f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1954f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1955f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_URIFD:      // intended fall-through
1956f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:     // intended fall-through
1957f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:  // intended fall-through
1958f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
1959f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        // FIXME report and use the return code to the lock mechanism, which is where play state
1960f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        //   changes are updated (see object_unlock_exclusive_attributes())
1961f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        aplayer_setPlayState(ap->mAPlayer, playState, &(ap->mAndroidObjState));
1962f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1963f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    default:
1964f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        SL_LOGE(ERROR_PLAYERSETPLAYSTATE_UNEXPECTED_OBJECT_TYPE_D, ap->mAndroidObjType);
1965f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
1966f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1967f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov}
1968f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1969f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1970f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov//-----------------------------------------------------------------------------
1971f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov// call when either player event flags, marker position, or position update period changes
1972f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganovvoid android_audioPlayer_usePlayEventMask(CAudioPlayer *ap) {
1973f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    IPlay *pPlayItf = &ap->mPlay;
1974f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    SLuint32 eventFlags = pPlayItf->mEventFlags;
1975f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    /*switch(ap->mAndroidObjType) {
1976f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:*/
1977f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1978f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (ap->mAPlayer != 0) {
1979f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        assert(ap->mAudioTrack == 0);
1980f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        ap->mAPlayer->setPlayEvents((int32_t) eventFlags, (int32_t) pPlayItf->mMarkerPosition,
1981f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                (int32_t) pPlayItf->mPositionUpdatePeriod);
1982f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        return;
1983f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1984f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1985f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (ap->mAudioTrack == 0) {
1986f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        return;
1987f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1988f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1989f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (eventFlags & SL_PLAYEVENT_HEADATMARKER) {
1990f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        ap->mAudioTrack->setMarkerPosition((uint32_t)((((int64_t)pPlayItf->mMarkerPosition
1991f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
1992f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    } else {
1993f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        // clear marker
1994f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        ap->mAudioTrack->setMarkerPosition(0);
1995f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
1996f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
1997f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (eventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
1998f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov         ap->mAudioTrack->setPositionUpdatePeriod(
1999f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                (uint32_t)((((int64_t)pPlayItf->mPositionUpdatePeriod
2000f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov                * sles_to_android_sampleRate(ap->mSampleRateMilliHz)))/1000));
2001f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    } else {
2002f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        // clear periodic update
2003f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        ap->mAudioTrack->setPositionUpdatePeriod(0);
2004f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    }
2005f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov
2006f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov    if (eventFlags & SL_PLAYEVENT_HEADATEND) {
2007f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        // nothing to do for SL_PLAYEVENT_HEADATEND, callback event will be checked against mask
20087151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey    }
20097151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey
20107151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey    if (eventFlags & SL_PLAYEVENT_HEADMOVING) {
2011b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        // FIXME support SL_PLAYEVENT_HEADMOVING
2012b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        SL_LOGD("[ FIXME: IPlay_SetCallbackEventsMask(SL_PLAYEVENT_HEADMOVING) on an "
20136dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey            "SL_OBJECTID_AUDIOPLAYER to be implemented ]");
20146dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    }
20156dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    if (eventFlags & SL_PLAYEVENT_HEADSTALLED) {
20166dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey        // nothing to do for SL_PLAYEVENT_HEADSTALLED, callback event will be checked against mask
20176dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    }
20186dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey
20196dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey}
20206dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey
20216dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey
20226dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey//-----------------------------------------------------------------------------
20236dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff SharkeySLresult android_audioPlayer_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec) {
2024b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
20256dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    switch(ap->mAndroidObjType) {
20267e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey
2027b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey      case AUDIOPLAYER_FROM_URIFD:  // intended fall-through
2028b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE: {
2029b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        int32_t durationMsec = ANDROID_UNKNOWN_TIME;
20307151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey        if (ap->mAPlayer != 0) {
20317e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey            ap->mAPlayer->getDurationMsec(&durationMsec);
20327151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey        }
20337151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey        *pDurMsec = durationMsec == ANDROID_UNKNOWN_TIME ? SL_TIME_UNKNOWN : durationMsec;
20347e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey        break;
20357151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey      }
20367151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey
20377151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE: // intended fall-through
20387151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
203950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
204050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey      default: {
204150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey        *pDurMsec = SL_TIME_UNKNOWN;
2042f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey      }
20430e62384ccbd00e9f78851929ca88b919679ee32eJeff Sharkey    }
2044f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey    return SL_RESULT_SUCCESS;
2045f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey}
2046f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey
20476dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey
20486dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey//-----------------------------------------------------------------------------
20496dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkeyvoid android_audioPlayer_getPosition(IPlay *pPlayItf, SLmillisecond *pPosMsec) {
20506dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    CAudioPlayer *ap = (CAudioPlayer *)pPlayItf->mThis;
20516dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey    switch(ap->mAndroidObjType) {
20526dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey
205347f0795d171a25d30ee5b48a6ff1828fb5c92c19Xiaohui Chen      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
20546dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey        if ((ap->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) || (ap->mAudioTrack == 0)) {
20556dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey            *pPosMsec = 0;
2056f80b52b08aff0fe4c5a5fdc710aa5976c7b25699Jeff Sharkey        } else {
20576dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey            uint32_t positionInFrames;
20586dce4964b4d1a13d276d95730b8fb09d6a5a8d04Jeff Sharkey            ap->mAudioTrack->getPosition(&positionInFrames);
205950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey            *pPosMsec = ((int64_t)positionInFrames * 1000) /
20607151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey                    sles_to_android_sampleRate(ap->mSampleRateMilliHz);
20617151a9a887051542c6da9f380376f3b306184e5cJeff Sharkey        }
2062f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov        break;
20637121e18595d4c559044e26bfe6035406a862f466Svet Ganov
2064f4ff39c92be840d5f53c42cb02cef6b03a1ca70fSvet Ganov      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:    // intended fall-through
20657121e18595d4c559044e26bfe6035406a862f466Svet Ganov      case AUDIOPLAYER_FROM_URIFD:
206695c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2067b43ec54c23cdb1af88812c5221b62b6218a35b09Jeff Sharkey      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE: {
2068b43ec54c23cdb1af88812c5221b62b6218a35b09Jeff Sharkey        int32_t posMsec = ANDROID_UNKNOWN_TIME;
2069b43ec54c23cdb1af88812c5221b62b6218a35b09Jeff Sharkey        if (ap->mAPlayer != 0) {
2070b43ec54c23cdb1af88812c5221b62b6218a35b09Jeff Sharkey            ap->mAPlayer->getPositionMsec(&posMsec);
2071b43ec54c23cdb1af88812c5221b62b6218a35b09Jeff Sharkey        }
207295c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov        *pPosMsec = posMsec == ANDROID_UNKNOWN_TIME ? 0 : posMsec;
207395c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov        break;
20747121e18595d4c559044e26bfe6035406a862f466Svet Ganov      }
20757121e18595d4c559044e26bfe6035406a862f466Svet Ganov
207695c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov      default:
207795c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov        *pPosMsec = 0;
207895c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov    }
207995c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov}
208095c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov
208195c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov
208295c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov//-----------------------------------------------------------------------------
2083a7473a671c717d77fd32e6155e16635dbe7c173eSvetoslavSLresult android_audioPlayer_seek(CAudioPlayer *ap, SLmillisecond posMsec) {
2084a7473a671c717d77fd32e6155e16635dbe7c173eSvetoslav    SLresult result = SL_RESULT_SUCCESS;
2085a7473a671c717d77fd32e6155e16635dbe7c173eSvetoslav
2086d5e295f9192522176796271cb29558a53d37c875Todd Kennedy    switch(ap->mAndroidObjType) {
2087d5e295f9192522176796271cb29558a53d37c875Todd Kennedy
2088d5e295f9192522176796271cb29558a53d37c875Todd Kennedy      case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:      // intended fall-through
2089d5e295f9192522176796271cb29558a53d37c875Todd Kennedy      case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2090d5e295f9192522176796271cb29558a53d37c875Todd Kennedy      case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2091d5e295f9192522176796271cb29558a53d37c875Todd Kennedy        result = SL_RESULT_FEATURE_UNSUPPORTED;
2092d5e295f9192522176796271cb29558a53d37c875Todd Kennedy        break;
2093d5e295f9192522176796271cb29558a53d37c875Todd Kennedy
2094d5e295f9192522176796271cb29558a53d37c875Todd Kennedy      case AUDIOPLAYER_FROM_URIFD:                   // intended fall-through
2095d5e295f9192522176796271cb29558a53d37c875Todd Kennedy      case AUDIOPLAYER_FROM_URIFD_TO_PCM_BUFFERQUEUE:
2096d5e295f9192522176796271cb29558a53d37c875Todd Kennedy        if (ap->mAPlayer != 0) {
2097d5e295f9192522176796271cb29558a53d37c875Todd Kennedy            ap->mAPlayer->seek(posMsec);
2098a7473a671c717d77fd32e6155e16635dbe7c173eSvetoslav        }
209995c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov        break;
210095c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov
210195c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov      default:
210295c1adea0c5fe10ceba217a327163757f4589d3dSvet Ganov        break;
2103f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    }
2104f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    return result;
2105f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate}
2106f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate
2107f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate
2108f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate//-----------------------------------------------------------------------------
2109f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher TateSLresult android_audioPlayer_loop(CAudioPlayer *ap, SLboolean loopEnable) {
2110f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    SLresult result = SL_RESULT_SUCCESS;
2111f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate
2112f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    switch (ap->mAndroidObjType) {
2113f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    case AUDIOPLAYER_FROM_URIFD:
21142e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz    // case AUDIOPLAY_FROM_URIFD_TO_PCM_BUFFERQUEUE:
21152e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz    //      would actually work, but what's the point?
21162e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz      if (ap->mAPlayer != 0) {
21172e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz        ap->mAPlayer->loop((bool)loopEnable);
21182e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz      }
21192e3e943ccd419dd10d3e4df5ae7640e8b020cc76Benjamin Franz      break;
2120f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    default:
2121f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate      result = SL_RESULT_FEATURE_UNSUPPORTED;
2122f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate      break;
2123f1977b4500e82b72ea6aa5c46d97406a20017cafChristopher Tate    }
2124d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn    return result;
2125d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn}
2126d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
2127d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn
2128d7c096845dee7616095eda0fe9e7aa08f0ba9c20Dianne Hackborn//-----------------------------------------------------------------------------
2129483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith YamasaniSLresult android_audioPlayer_setBufferingUpdateThresholdPerMille(CAudioPlayer *ap,
2130c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        SLpermille threshold) {
2131c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    SLresult result = SL_RESULT_SUCCESS;
2132c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov
2133c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov    switch (ap->mAndroidObjType) {
2134c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov      case AUDIOPLAYER_FROM_URIFD:
2135c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        if (ap->mAPlayer != 0) {
2136c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov            ap->mAPlayer->setBufferingUpdateThreshold(threshold / 10);
2137c30808b413deff60fafa047d9cc15c275feb3c63Fyodor Kupolov        }
2138354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov        break;
2139354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov
2140354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov      default: {}
2141354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov    }
2142354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov
2143483f3b06ea84440a082e21b68ec2c2e54046f5a6Amith Yamasani    return result;
2144354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov}
2145354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov
2146354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov
2147354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov//-----------------------------------------------------------------------------
2148354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganovvoid android_audioPlayer_bufferQueue_onRefilled_l(CAudioPlayer *ap) {
2149354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov    // the AudioTrack associated with the AudioPlayer receiving audio from a PCM buffer
2150354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov    // queue was stopped when the queue become empty, we restart as soon as a new buffer
2151354cd3ce2213a1032d9138ea6fa1420f055ab08cSvet Ganov    // has been enqueued since we're in playing state
2152e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn    if (ap->mAudioTrack != 0) {
2153e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        // instead of ap->mAudioTrack->start();
2154e7f972122db87dc54e41ed1a6e417534d43bca3aDianne Hackborn        ap->mDeferredStart = true;
2155c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav    }
2156f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brown
2157bdd30d86ef98456161069d11481b2ccd25a11b4eAndreas Gampe    // when the queue became empty, an underflow on the prefetch status itf was sent. Now the queue
2158bdd30d86ef98456161069d11481b2ccd25a11b4eAndreas Gampe    // has received new data, signal it has sufficient data
2159bdd30d86ef98456161069d11481b2ccd25a11b4eAndreas Gampe    if (IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) {
2160f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brown        // we wouldn't have been called unless we were previously in the underflow state
2161f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brown        assert(SL_PREFETCHSTATUS_UNDERFLOW == ap->mPrefetchStatus.mStatus);
2162bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        assert(0 == ap->mPrefetchStatus.mLevel);
2163e68b127525c23e8e0cbe1e9dee75534d99e2833dJeff Davidson        ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_SUFFICIENTDATA;
2164e68b127525c23e8e0cbe1e9dee75534d99e2833dJeff Davidson        ap->mPrefetchStatus.mLevel = 1000;
2165e68b127525c23e8e0cbe1e9dee75534d99e2833dJeff Davidson        // callback or no callback?
2166e68b127525c23e8e0cbe1e9dee75534d99e2833dJeff Davidson        SLuint32 prefetchEvents = ap->mPrefetchStatus.mCallbackEventsMask &
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (SL_PREFETCHEVENT_NONE != prefetchEvents) {
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ap->mPrefetchStatus.mDeferredPrefetchCallback = ap->mPrefetchStatus.mCallback;
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ap->mPrefetchStatus.mDeferredPrefetchContext  = ap->mPrefetchStatus.mContext;
2171bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov            ap->mPrefetchStatus.mDeferredPrefetchEvents   = prefetchEvents;
21721682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        }
21731682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    }
21741682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov}
21751682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
21761682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
21771682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov//-----------------------------------------------------------------------------
21781682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov/*
21791682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov * BufferQueue::Clear
21801682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov */
21811682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor KupolovSLresult android_audioPlayer_bufferQueue_onClear(CAudioPlayer *ap) {
21821682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    SLresult result = SL_RESULT_SUCCESS;
21831682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
21841682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    switch (ap->mAndroidObjType) {
21851682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    //-----------------------------------
21861682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    // AudioTrack
21871682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
2188bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        if (ap->mAudioTrack != 0) {
2189bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov            ap->mAudioTrack->flush();
21901682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        }
21911682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        break;
2192bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    default:
2193bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        result = SL_RESULT_INTERNAL_ERROR;
21941682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        break;
2195bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    }
21961682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
2197bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    return result;
2198bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov}
21991682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
22001682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
22011682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov//-----------------------------------------------------------------------------
22021682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolovvoid android_audioPlayer_androidBufferQueue_clear_l(CAudioPlayer *ap) {
22031682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    switch (ap->mAndroidObjType) {
2204bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2205bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov      if (ap->mAPlayer != 0) {
2206bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2207bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        splr->appClear_l();
2208bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov      } break;
2209bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
22101682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov      // nothing to do here, fall through
22111682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    default:
22121682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov      break;
22131682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    }
2214ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski}
2215ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski
2216ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinskivoid android_audioPlayer_androidBufferQueue_onRefilled_l(CAudioPlayer *ap) {
2217ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski    switch (ap->mAndroidObjType) {
2218ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski    case AUDIOPLAYER_FROM_TS_ANDROIDBUFFERQUEUE:
2219ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski      if (ap->mAPlayer != 0) {
2220f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brown        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(ap->mAPlayer.get());
2221f69c812f49cb2dea296cd319984e58af026f4c3aJeff Brown        splr->queueRefilled();
2222ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker      } break;
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case AUDIOPLAYER_FROM_ADTS_ABQ_TO_PCM_BUFFERQUEUE:
2224ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker      // FIXME this may require waking up the decoder if it is currently starved and isn't polling
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    default:
2226a2fd9d1786fec65dc4199e29c78dd43e1e31bb58Dianne Hackborn      break;
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2228ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker}
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project