android_StreamPlayer.cpp revision e7bfcdc183454ec959ff51342f0973cabba219b2
1fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi/*
2fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
4fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * you may not use this file except in compliance with the License.
6fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * You may obtain a copy of the License at
7fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
8fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi *
10fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * See the License for the specific language governing permissions and
14fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * limitations under the License.
15fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi */
16fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
1768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#define USE_LOG SLAndroidLogLevel_Verbose
18fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
19fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include "sles_allinclusive.h"
2026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi#include <media/IMediaPlayerService.h>
21fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
22eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
23eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
24581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi
2513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivivoid android_StreamPlayer_realize_l(CAudioPlayer *ap, const notif_cbf_t cbf, void* notifUser) {
26cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi    SL_LOGI("android_StreamPlayer_realize_l(%p)", ap);
27fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
2816ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    AudioPlayback_Parameters ap_params;
29fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    ap_params.sessionId = ap->mSessionId;
30fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    ap_params.streamType = ap->mStreamType;
3116ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    ap_params.trackcb = NULL;
3216ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    ap_params.trackcbUser = NULL;
33d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    android::StreamPlayer* splr = new android::StreamPlayer(&ap_params, false /*hasVideo*/);
34d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    ap->mAPlayer = splr;
35d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    splr->init(cbf, notifUser);
3626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
3726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
3826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
39eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
40fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivinamespace android {
41fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
42be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel TriviStreamSourceAppProxy::StreamSourceAppProxy(
43d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const void* user, bool userIsAudioPlayer,
44d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        void *context, const void *caller) :
45d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    mUser(user),
46d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    mUserIsAudioPlayer(userIsAudioPlayer),
4770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    mAndroidBufferQueue(NULL),
48be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mAppContext(context),
49be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mCaller(caller)
5026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi{
51eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamSourceAppProxy::StreamSourceAppProxy()");
5270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
5370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mUserIsAudioPlayer) {
5470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAndroidBufferQueue = &((CAudioPlayer*)mUser)->mAndroidBufferQueue;
5570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
5670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAndroidBufferQueue = &((CMediaPlayer*)mUser)->mAndroidBufferQueue;
5770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
5826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
5926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
6026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel TriviStreamSourceAppProxy::~StreamSourceAppProxy() {
61eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamSourceAppProxy::~StreamSourceAppProxy()");
62be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mListener.clear();
63be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mBuffers.clear();
6426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
6526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
6626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//--------------------------------------------------
6726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi// IStreamSource implementation
6826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setListener(const sp<IStreamListener> &listener) {
6970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    Mutex::Autolock _l(mLock);
7026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mListener = listener;
7126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
7226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
7326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setBuffers(const Vector<sp<IMemory> > &buffers) {
7426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mBuffers = buffers;
7526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
7626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
7726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::onBufferAvailable(size_t index) {
7870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    //SL_LOGD("StreamSourceAppProxy::onBufferAvailable(%d)", index);
7926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
8026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    CHECK_LT(index, mBuffers.size());
8126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    sp<IMemory> mem = mBuffers.itemAt(index);
8226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    SLAint64 length = (SLAint64) mem->size();
8326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
8470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    {
8570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        Mutex::Autolock _l(mLock);
8670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAvailableBuffers.push_back(index);
8770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
8870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi//SL_LOGD("onBufferAvailable() now %d buffers available in queue", mAvailableBuffers.size());
8970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
9070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // a new shared mem buffer is available: let's try to fill immediately
9170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    pullFromBuffQueue();
9270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
9370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
9470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedCmd_l(IStreamListener::Command cmd, const sp<AMessage> &msg) {
95be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    if (mListener != 0) {
9670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mListener->issueCommand(cmd, false /* synchronous */, msg);
9726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    }
9826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
9926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
10070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedBuffer_l(size_t buffIndex, size_t buffLength) {
101be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    if (mListener != 0) {
102be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi        mListener->queueBuffer(buffIndex, buffLength);
103be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
104be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
105be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
10670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi//--------------------------------------------------
10770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi// consumption from ABQ
10870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::pullFromBuffQueue() {
10970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
11070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    size_t bufferId;
11170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    void* bufferLoc;
11270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    size_t buffSize;
11370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
11470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    slAndroidBufferQueueCallback callback = NULL;
11570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    void* callbackPContext = NULL;
11670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    AdvancedBufferHeader *oldFront = NULL;
11770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
11870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // retrieve data from the buffer queue
11970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    interface_lock_exclusive(mAndroidBufferQueue);
12070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mAndroidBufferQueue->mState.count != 0) {
12270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // SL_LOGD("nbBuffers in ABQ = %lu, buffSize=%lu",abq->mState.count, buffSize);
12370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        assert(mAndroidBufferQueue->mFront != mAndroidBufferQueue->mRear);
12470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        oldFront = mAndroidBufferQueue->mFront;
12670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        AdvancedBufferHeader *newFront = &oldFront[1];
12770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // consume events when starting to read data from a buffer for the first time
12970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        if (oldFront->mDataSizeConsumed == 0) {
13070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_EOS) {
13170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::EOS);
13270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCONTINUITY) {
13370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::DISCONTINUITY);
13470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCON_NEWPTS) {
13570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                sp<AMessage> msg = new AMessage();
13670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                msg->setInt64(IStreamListener::kKeyResumeAtPTS,
13770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        (int64_t)oldFront->mItems.mTsCmdData.mPts);
13870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/);
13970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
14070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            oldFront->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
14170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
14270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
14370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        {
14470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // we're going to change the shared mem buffer queue, so lock it
14570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            Mutex::Autolock _l(mLock);
14670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (!mAvailableBuffers.empty()) {
14770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                bufferId = *mAvailableBuffers.begin();
14870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                CHECK_LT(bufferId, mBuffers.size());
14970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                sp<IMemory> mem = mBuffers.itemAt(bufferId);
15070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                bufferLoc = mem->pointer();
15170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                buffSize = mem->size();
15270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
15370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                char *pSrc = ((char*)oldFront->mDataBuffer) + oldFront->mDataSizeConsumed;
15470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                if (oldFront->mDataSizeConsumed + buffSize < oldFront->mDataSize) {
15570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // more available than requested, copy as much as requested
15670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // consume data: 1/ copy to given destination
15770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    memcpy(bufferLoc, pSrc, buffSize);
15870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //               2/ keep track of how much has been consumed
15970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    oldFront->mDataSizeConsumed += buffSize;
16070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //               3/ notify shared mem listener that new data is available
16170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    receivedBuffer_l(bufferId, buffSize);
16270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAvailableBuffers.erase(mAvailableBuffers.begin());
16370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                } else {
16470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // requested as much available or more: consume the whole of the current
16570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //   buffer and move to the next
16670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    size_t consumed = oldFront->mDataSize - oldFront->mDataSizeConsumed;
16770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //SL_LOGD("consuming rest of buffer: enqueueing=%ld", consumed);
16870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    oldFront->mDataSizeConsumed = oldFront->mDataSize;
16970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
17070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // move queue to next
17170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    if (newFront == &mAndroidBufferQueue->
17270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                            mBufferArray[mAndroidBufferQueue->mNumBuffers + 1]) {
17370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // reached the end, circle back
17470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        newFront = mAndroidBufferQueue->mBufferArray;
17570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    }
17670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mFront = newFront;
17770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mState.count--;
17870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mState.index++;
17970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
18070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    if (consumed > 0) {
18170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // consume data: 1/ copy to given destination
18270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        memcpy(bufferLoc, pSrc, consumed);
18370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        //               2/ keep track of how much has been consumed
18470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // here nothing to do because we are done with this buffer
18570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        //               3/ notify StreamPlayer that new data is available
18670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        receivedBuffer_l(bufferId, consumed);
18770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        mAvailableBuffers.erase(mAvailableBuffers.begin());
18870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    }
18970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
19070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // data has been consumed, and the buffer queue state has been updated
19170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // we will notify the client if applicable
19270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    callback = mAndroidBufferQueue->mCallback;
19370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // save callback data
19470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    callbackPContext = mAndroidBufferQueue->mContext;
19570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                }
19670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                //SL_LOGD("onBufferAvailable() %d buffers available after enqueue",
19770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                //     mAvailableBuffers.size());
19870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
19970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
20070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
20170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
20270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else { // empty queue
20370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        SL_LOGD("ABQ empty, starving!");
20470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // signal we're at the end of the content, but don't pause (see note in function)
20570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        if (mUserIsAudioPlayer) {
20670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // FIXME declare this external
20770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            //audioPlayer_dispatch_headAtEnd_lockPlay((CAudioPlayer*)user,
20870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            //        false /*set state to paused?*/, false);
20970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        } else {
21070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // FIXME implement headAtEnd dispatch for CMediaPlayer
21170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
21270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
21370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
21470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    interface_unlock_exclusive(mAndroidBufferQueue);
21570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
21670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // notify client
21770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (NULL != callback) {
21870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // oldFront was only initialized in the code path where callback is initialized
21970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        //    so no need to check if it's valid
22070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        (*callback)(&mAndroidBufferQueue->mItf, callbackPContext,
22170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                (void *)oldFront->mDataBuffer,/* pBufferData  */
22270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                oldFront->mDataSize, /* dataSize  */
22370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                // here a buffer is only dequeued when fully consumed
22470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                oldFront->mDataSize, /* dataUsed  */
22570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                // no messages during playback
22670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                0, /* itemsLength */
22770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                NULL /* pItems */);
22870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
22970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
23070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
231be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
23226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
23368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviStreamPlayer::StreamPlayer(AudioPlayback_Parameters* params, bool hasVideo) :
23468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        GenericMediaPlayer(params, hasVideo),
23568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mAppProxy(0)
236fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
237eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamPlayer::StreamPlayer()");
238fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
23926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mPlaybackParams = *params;
24026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
241fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
242fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
243fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel TriviStreamPlayer::~StreamPlayer() {
24416ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    SL_LOGI("StreamPlayer::~StreamPlayer()");
245cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
24626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mAppProxy.clear();
247fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
248fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
249fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
25070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::onMessageReceived(const sp<AMessage> &msg) {
25170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    switch (msg->what()) {
25270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        case kWhatQueueRefilled:
25370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            onQueueRefilled();
25470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
25570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
25670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        default:
25770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            GenericMediaPlayer::onMessageReceived(msg);
25870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
25970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
26070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
26170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
26270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
263d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid StreamPlayer::registerQueueCallback(
264d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const void* user, bool userIsAudioPlayer,
265d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        void *context,
26694a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        const void *caller) {
267eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamPlayer::registerQueueCallback");
26868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
26926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
27070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    mAppProxy = new StreamSourceAppProxy(
27170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            user, userIsAudioPlayer,
272d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            context, caller);
27316ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi
274be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    CHECK(mAppProxy != 0);
275eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamPlayer::registerQueueCallback end");
276be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
277be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
27870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
27970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/**
28070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * Called with a lock on ABQ
28170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi */
28270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::queueRefilled_l() {
28370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // async notification that the ABQ was refilled
28470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    (new AMessage(kWhatQueueRefilled, id()))->post();
285be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
286be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
287e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
288e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivivoid StreamPlayer::appClear_l() {
289e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // the user of StreamPlayer has cleared its AndroidBufferQueue: a discontinuity is expected
29068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
291be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    if (mAppProxy != 0) {
292e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        mAppProxy->receivedCmd_l(IStreamListener::DISCONTINUITY);
293be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
29426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
29526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
296cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
297cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi//--------------------------------------------------
298cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi// Event handlers
299cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivivoid StreamPlayer::onPrepare() {
300cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi    SL_LOGI("StreamPlayer::onPrepare()");
30168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
302eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    if (mAppProxy != 0) {
303eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/,
304eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi                mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId);
305eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        // blocks until mPlayer is prepared
30668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        GenericMediaPlayer::onPrepare();
307eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        SL_LOGI("StreamPlayer::onPrepare() done");
308eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    } else {
309eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        SL_LOGE("Nothing to do here because there is no registered callback");
310eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    }
311cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi}
312cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
313cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
31470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::onQueueRefilled() {
31570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    //SL_LOGD("StreamPlayer::onQueueRefilled()");
31670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
31770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mAppProxy != 0) {
31870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAppProxy->pullFromBuffQueue();
31970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
32070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
321cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
322fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} // namespace android
323