android_StreamPlayer.cpp revision 4ee246c55533bdab8ab5fa0f0581744fe58e7c91
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
17e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi//#define USE_LOG SLAndroidLogLevel_Verbose
18fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
19fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include "sles_allinclusive.h"
204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "android_StreamPlayer.h"
214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
2263c002ab68761be0eace98f28320d8eb2f3f7695Jean-Michel Trivi#include <media/IStreamSource.h>
2326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi#include <media/IMediaPlayerService.h>
244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include <media/stagefright/foundation/ADebug.h>
25fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
26eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
27eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
28581a0f550f15f6fc22199cb85775a220f668b480Jean-Michel Trivi
2913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivivoid android_StreamPlayer_realize_l(CAudioPlayer *ap, const notif_cbf_t cbf, void* notifUser) {
30cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi    SL_LOGI("android_StreamPlayer_realize_l(%p)", ap);
31fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
3216ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    AudioPlayback_Parameters ap_params;
33fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    ap_params.sessionId = ap->mSessionId;
34fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi    ap_params.streamType = ap->mStreamType;
3516ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    ap_params.trackcb = NULL;
3616ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi    ap_params.trackcbUser = NULL;
37d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    android::StreamPlayer* splr = new android::StreamPlayer(&ap_params, false /*hasVideo*/);
38d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    ap->mAPlayer = splr;
39d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    splr->init(cbf, notifUser);
4026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
4126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
4226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
43eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
44fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivinamespace android {
45fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
46be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel TriviStreamSourceAppProxy::StreamSourceAppProxy(
47d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const void* user, bool userIsAudioPlayer,
48d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        void *context, const void *caller) :
49d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    mUser(user),
50d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    mUserIsAudioPlayer(userIsAudioPlayer),
5170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    mAndroidBufferQueue(NULL),
52be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mAppContext(context),
53be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mCaller(caller)
5426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi{
55eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    SL_LOGI("StreamSourceAppProxy::StreamSourceAppProxy()");
5670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
5770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mUserIsAudioPlayer) {
5870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAndroidBufferQueue = &((CAudioPlayer*)mUser)->mAndroidBufferQueue;
5970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
6070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAndroidBufferQueue = &((CMediaPlayer*)mUser)->mAndroidBufferQueue;
6170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
6226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
6326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
6426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel TriviStreamSourceAppProxy::~StreamSourceAppProxy() {
65e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamSourceAppProxy::~StreamSourceAppProxy()");
66be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mListener.clear();
67be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    mBuffers.clear();
6826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
6926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
701c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Triviconst SLuint32 StreamSourceAppProxy::kItemProcessed[NB_BUFFEREVENT_ITEM_FIELDS] = {
711c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        SL_ANDROID_ITEMKEY_BUFFERQUEUEEVENT, // item key
721c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        sizeof(SLuint32),                    // item size
731c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED // item data
741c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi};
751c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
7626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//--------------------------------------------------
7726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi// IStreamSource implementation
7826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setListener(const sp<IStreamListener> &listener) {
7970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    Mutex::Autolock _l(mLock);
8026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mListener = listener;
8126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
8226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
8326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setBuffers(const Vector<sp<IMemory> > &buffers) {
8426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mBuffers = buffers;
8526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
8626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
8726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::onBufferAvailable(size_t index) {
8870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    //SL_LOGD("StreamSourceAppProxy::onBufferAvailable(%d)", index);
8926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
9026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    CHECK_LT(index, mBuffers.size());
9126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    sp<IMemory> mem = mBuffers.itemAt(index);
9226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    SLAint64 length = (SLAint64) mem->size();
9326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
9470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    {
9570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        Mutex::Autolock _l(mLock);
9670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAvailableBuffers.push_back(index);
9770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
9870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi//SL_LOGD("onBufferAvailable() now %d buffers available in queue", mAvailableBuffers.size());
9970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
10070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // a new shared mem buffer is available: let's try to fill immediately
10170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    pullFromBuffQueue();
10270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
10370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
10470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedCmd_l(IStreamListener::Command cmd, const sp<AMessage> &msg) {
105be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    if (mListener != 0) {
10670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mListener->issueCommand(cmd, false /* synchronous */, msg);
10726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    }
10826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
10926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
11070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedBuffer_l(size_t buffIndex, size_t buffLength) {
111be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    if (mListener != 0) {
112be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi        mListener->queueBuffer(buffIndex, buffLength);
113be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    }
114be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
115be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
11670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi//--------------------------------------------------
11770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi// consumption from ABQ
11870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::pullFromBuffQueue() {
11970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    size_t bufferId;
12170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    void* bufferLoc;
12270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    size_t buffSize;
12370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    slAndroidBufferQueueCallback callback = NULL;
12570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    void* callbackPContext = NULL;
12670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    AdvancedBufferHeader *oldFront = NULL;
12770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
12870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // retrieve data from the buffer queue
12970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    interface_lock_exclusive(mAndroidBufferQueue);
13070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
13170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mAndroidBufferQueue->mState.count != 0) {
13270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // SL_LOGD("nbBuffers in ABQ = %lu, buffSize=%lu",abq->mState.count, buffSize);
13370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        assert(mAndroidBufferQueue->mFront != mAndroidBufferQueue->mRear);
13470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
13570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        oldFront = mAndroidBufferQueue->mFront;
13670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        AdvancedBufferHeader *newFront = &oldFront[1];
13770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
13870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // consume events when starting to read data from a buffer for the first time
13970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        if (oldFront->mDataSizeConsumed == 0) {
14070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_EOS) {
14170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::EOS);
14270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCONTINUITY) {
14370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::DISCONTINUITY);
14470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCON_NEWPTS) {
14570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                sp<AMessage> msg = new AMessage();
14670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                msg->setInt64(IStreamListener::kKeyResumeAtPTS,
14770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        (int64_t)oldFront->mItems.mTsCmdData.mPts);
14870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/);
14970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
15070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            oldFront->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
15170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
15270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
15370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        {
15470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // we're going to change the shared mem buffer queue, so lock it
15570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            Mutex::Autolock _l(mLock);
15670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (!mAvailableBuffers.empty()) {
15770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                bufferId = *mAvailableBuffers.begin();
15870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                CHECK_LT(bufferId, mBuffers.size());
15970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                sp<IMemory> mem = mBuffers.itemAt(bufferId);
16070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                bufferLoc = mem->pointer();
16170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                buffSize = mem->size();
16270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
16370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                char *pSrc = ((char*)oldFront->mDataBuffer) + oldFront->mDataSizeConsumed;
16470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                if (oldFront->mDataSizeConsumed + buffSize < oldFront->mDataSize) {
16570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // more available than requested, copy as much as requested
16670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // consume data: 1/ copy to given destination
16770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    memcpy(bufferLoc, pSrc, buffSize);
16870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //               2/ keep track of how much has been consumed
16970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    oldFront->mDataSizeConsumed += buffSize;
17070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //               3/ notify shared mem listener that new data is available
17170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    receivedBuffer_l(bufferId, buffSize);
17270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAvailableBuffers.erase(mAvailableBuffers.begin());
17370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                } else {
17470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // requested as much available or more: consume the whole of the current
17570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //   buffer and move to the next
17670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    size_t consumed = oldFront->mDataSize - oldFront->mDataSizeConsumed;
17770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //SL_LOGD("consuming rest of buffer: enqueueing=%ld", consumed);
17870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    oldFront->mDataSizeConsumed = oldFront->mDataSize;
17970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
18070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // move queue to next
18170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    if (newFront == &mAndroidBufferQueue->
18270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                            mBufferArray[mAndroidBufferQueue->mNumBuffers + 1]) {
18370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // reached the end, circle back
18470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        newFront = mAndroidBufferQueue->mBufferArray;
18570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    }
18670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mFront = newFront;
18770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mState.count--;
18870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    mAndroidBufferQueue->mState.index++;
18970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
19070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    if (consumed > 0) {
19170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // consume data: 1/ copy to given destination
19270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        memcpy(bufferLoc, pSrc, consumed);
19370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        //               2/ keep track of how much has been consumed
19470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        // here nothing to do because we are done with this buffer
19570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        //               3/ notify StreamPlayer that new data is available
19670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        receivedBuffer_l(bufferId, consumed);
19770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        mAvailableBuffers.erase(mAvailableBuffers.begin());
19870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    }
19970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
20070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // data has been consumed, and the buffer queue state has been updated
20170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    // we will notify the client if applicable
2021c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                    if (mAndroidBufferQueue->mCallbackEventsMask &
2031c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                            SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED) {
2041c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                        callback = mAndroidBufferQueue->mCallback;
2051c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                        // save callback data
2061c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                        callbackPContext = mAndroidBufferQueue->mContext;
2071c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                    }
20870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                }
20970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                //SL_LOGD("onBufferAvailable() %d buffers available after enqueue",
21070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                //     mAvailableBuffers.size());
21170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
21270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
21370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
21470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
21570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else { // empty queue
21670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        SL_LOGD("ABQ empty, starving!");
21770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // signal we're at the end of the content, but don't pause (see note in function)
21870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        if (mUserIsAudioPlayer) {
21970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // FIXME declare this external
22070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            //audioPlayer_dispatch_headAtEnd_lockPlay((CAudioPlayer*)user,
22170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            //        false /*set state to paused?*/, false);
22270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        } else {
22370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // FIXME implement headAtEnd dispatch for CMediaPlayer
22470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
22570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
22670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
22770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    interface_unlock_exclusive(mAndroidBufferQueue);
22870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
22970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // notify client
23070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (NULL != callback) {
23170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        (*callback)(&mAndroidBufferQueue->mItf, callbackPContext,
2321c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                // oldFront was only initialized in the code path where callback is initialized
2331c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                //    so no need to check if it's valid
23437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi                (void *)oldFront->mBufferContext, /* pBufferContext */
23570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                (void *)oldFront->mDataBuffer,/* pBufferData  */
23670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                oldFront->mDataSize, /* dataSize  */
23770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                // here a buffer is only dequeued when fully consumed
23870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                oldFront->mDataSize, /* dataUsed  */
2391c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                // no messages during playback other than marking the buffer as processed
2401c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                (SLAndroidBufferItem*)(&kItemProcessed) /* pItems */,
2411c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi                3*sizeof(SLuint32) /* itemsLength */ );
24270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
24370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
24470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
245be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
24626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
24768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviStreamPlayer::StreamPlayer(AudioPlayback_Parameters* params, bool hasVideo) :
24868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        GenericMediaPlayer(params, hasVideo),
24968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mAppProxy(0)
250fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{
251e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamPlayer::StreamPlayer()");
252fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
25326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mPlaybackParams = *params;
25426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
255fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
256fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
257fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel TriviStreamPlayer::~StreamPlayer() {
258e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamPlayer::~StreamPlayer()");
259cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
26026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi    mAppProxy.clear();
261fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi}
262fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
263fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi
26470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::onMessageReceived(const sp<AMessage> &msg) {
26570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    switch (msg->what()) {
26670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        case kWhatQueueRefilled:
26770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            onQueueRefilled();
26870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
26970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
27070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        default:
27170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            GenericMediaPlayer::onMessageReceived(msg);
27270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
27370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
27470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
27570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
27670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
277d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid StreamPlayer::registerQueueCallback(
278d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const void* user, bool userIsAudioPlayer,
279d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        void *context,
28094a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten        const void *caller) {
281e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamPlayer::registerQueueCallback");
28268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
28326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
28470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    mAppProxy = new StreamSourceAppProxy(
28570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            user, userIsAudioPlayer,
286d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            context, caller);
28716ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi
288be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi    CHECK(mAppProxy != 0);
289e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamPlayer::registerQueueCallback end");
290be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
291be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
29270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
29370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/**
29470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * Called with a lock on ABQ
29570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi */
29670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::queueRefilled_l() {
29770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // async notification that the ABQ was refilled
29870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    (new AMessage(kWhatQueueRefilled, id()))->post();
299be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi}
300be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi
301e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
302e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivivoid StreamPlayer::appClear_l() {
30337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    // the user of StreamPlayer has cleared its AndroidBufferQueue:
30437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    // there's no clear() for the shared memory queue, so this is a no-op
30526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi}
30626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi
307cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
308cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi//--------------------------------------------------
309cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi// Event handlers
310cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivivoid StreamPlayer::onPrepare() {
311e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("StreamPlayer::onPrepare()");
31268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
313eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    if (mAppProxy != 0) {
314eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/,
315eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi                mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId);
316eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        // blocks until mPlayer is prepared
31768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        GenericMediaPlayer::onPrepare();
318e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi        SL_LOGD("StreamPlayer::onPrepare() done");
319eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    } else {
320eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        SL_LOGE("Nothing to do here because there is no registered callback");
321eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    }
322cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi}
323cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
324cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
32570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::onQueueRefilled() {
32670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    //SL_LOGD("StreamPlayer::onQueueRefilled()");
32770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    Mutex::Autolock _l(mAppProxyLock);
32870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (mAppProxy != 0) {
32970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        mAppProxy->pullFromBuffQueue();
33070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
33170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
332cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi
333fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} // namespace android
334