android_StreamPlayer.cpp revision 6bc8af4e67051af7c86c311cb9c50e294e547500
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) { 30ecc4fe22e076c4e5c891d823b01db1a683ba6690Glenn Kasten SL_LOGV("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, 48bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi void *context, const void *caller, const sp<CallbackProtector> &callbackProtector, 49bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi const sp<StreamPlayer> &player) : 50d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi mUser(user), 51d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi mUserIsAudioPlayer(userIsAudioPlayer), 5270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue(NULL), 53be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi mAppContext(context), 54485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten mCaller(caller), 55bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi mCallbackProtector(callbackProtector), 56bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi mPlayer(player) 5726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi{ 58ecc4fe22e076c4e5c891d823b01db1a683ba6690Glenn Kasten SL_LOGV("StreamSourceAppProxy::StreamSourceAppProxy()"); 5970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 6070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (mUserIsAudioPlayer) { 6170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue = &((CAudioPlayer*)mUser)->mAndroidBufferQueue; 6270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { 6370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue = &((CMediaPlayer*)mUser)->mAndroidBufferQueue; 6470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 6526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 6626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 6726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel TriviStreamSourceAppProxy::~StreamSourceAppProxy() { 68e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamSourceAppProxy::~StreamSourceAppProxy()"); 69be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi mListener.clear(); 70be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi mBuffers.clear(); 7126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 7226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 731c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Triviconst SLuint32 StreamSourceAppProxy::kItemProcessed[NB_BUFFEREVENT_ITEM_FIELDS] = { 741c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi SL_ANDROID_ITEMKEY_BUFFERQUEUEEVENT, // item key 751c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi sizeof(SLuint32), // item size 761c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED // item data 771c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi}; 781c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi 7926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//-------------------------------------------------- 8026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi// IStreamSource implementation 8126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setListener(const sp<IStreamListener> &listener) { 8270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi Mutex::Autolock _l(mLock); 8326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi mListener = listener; 8426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 8526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 8626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::setBuffers(const Vector<sp<IMemory> > &buffers) { 8726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi mBuffers = buffers; 8826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 8926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 9026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivivoid StreamSourceAppProxy::onBufferAvailable(size_t index) { 9170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi //SL_LOGD("StreamSourceAppProxy::onBufferAvailable(%d)", index); 9226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 9326043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi CHECK_LT(index, mBuffers.size()); 9426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi sp<IMemory> mem = mBuffers.itemAt(index); 9526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi SLAint64 length = (SLAint64) mem->size(); 9626043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 9770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi { 9870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi Mutex::Autolock _l(mLock); 9970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAvailableBuffers.push_back(index); 10070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 101b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi //SL_LOGD("onBufferAvailable() now %d buffers available in queue", mAvailableBuffers.size()); 10270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 10370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // a new shared mem buffer is available: let's try to fill immediately 10470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi pullFromBuffQueue(); 10570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi} 10670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 10770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedCmd_l(IStreamListener::Command cmd, const sp<AMessage> &msg) { 108be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi if (mListener != 0) { 10970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mListener->issueCommand(cmd, false /* synchronous */, msg); 11026043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi } 11126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 11226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 11370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::receivedBuffer_l(size_t buffIndex, size_t buffLength) { 114be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi if (mListener != 0) { 115be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi mListener->queueBuffer(buffIndex, buffLength); 116be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi } 117be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi} 118be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 11970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi//-------------------------------------------------- 120bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi// consumption from ABQ: pull from the ABQ, and push to shared memory (media server) 12170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamSourceAppProxy::pullFromBuffQueue() { 12270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 123485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten if (android::CallbackProtector::enterCbIfOk(mCallbackProtector)) { 124485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten 12570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi size_t bufferId; 12670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi void* bufferLoc; 12770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi size_t buffSize; 12870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 12970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi slAndroidBufferQueueCallback callback = NULL; 130677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten void* pBufferContext, *pBufferData, *callbackPContext = NULL; 13170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi AdvancedBufferHeader *oldFront = NULL; 132677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten uint32_t dataSize /* , dataUsed */; 13370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 13470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // retrieve data from the buffer queue 13570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi interface_lock_exclusive(mAndroidBufferQueue); 13670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 1376bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // can this read operation cause us to call the buffer queue callback 1386bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // (either because there was a command with no data, or all the data has been consumed) 1396bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi bool queueCallbackCandidate = false; 1406bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi 14170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (mAndroidBufferQueue->mState.count != 0) { 142a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten // SL_LOGD("nbBuffers in ABQ = %u, buffSize=%u",abq->mState.count, buffSize); 14370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi assert(mAndroidBufferQueue->mFront != mAndroidBufferQueue->mRear); 14470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 14570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi oldFront = mAndroidBufferQueue->mFront; 14670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi AdvancedBufferHeader *newFront = &oldFront[1]; 14770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 14870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // consume events when starting to read data from a buffer for the first time 14970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (oldFront->mDataSizeConsumed == 0) { 150677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten // note this code assumes at most one event per buffer; see IAndroidBufferQueue_Enqueue 15170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_EOS) { 15270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi receivedCmd_l(IStreamListener::EOS); 1536bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // EOS has no associated data 1546bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi queueCallbackCandidate = true; 15570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCONTINUITY) { 15670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi receivedCmd_l(IStreamListener::DISCONTINUITY); 15770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_DISCON_NEWPTS) { 15870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi sp<AMessage> msg = new AMessage(); 15970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi msg->setInt64(IStreamListener::kKeyResumeAtPTS, 16070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi (int64_t)oldFront->mItems.mTsCmdData.mPts); 16170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/); 1626f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi } else if (oldFront->mItems.mTsCmdData.mTsCmdCode & ANDROID_MP2TSEVENT_FORMAT_CHANGE) { 1636f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi sp<AMessage> msg = new AMessage(); 1646f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi // positive value for format change key makes the discontinuity "hard", see key def 1656f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi msg->setInt32(IStreamListener::kKeyFormatChange, (int32_t) 1); 1666f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi receivedCmd_l(IStreamListener::DISCONTINUITY, msg /*msg*/); 16770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 16870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi oldFront->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE; 16970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 17070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 17170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi { 17270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // we're going to change the shared mem buffer queue, so lock it 17370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi Mutex::Autolock _l(mLock); 17470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (!mAvailableBuffers.empty()) { 17570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi bufferId = *mAvailableBuffers.begin(); 17670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi CHECK_LT(bufferId, mBuffers.size()); 17770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi sp<IMemory> mem = mBuffers.itemAt(bufferId); 17870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi bufferLoc = mem->pointer(); 17970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi buffSize = mem->size(); 18070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 18170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi char *pSrc = ((char*)oldFront->mDataBuffer) + oldFront->mDataSizeConsumed; 18270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (oldFront->mDataSizeConsumed + buffSize < oldFront->mDataSize) { 18370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // more available than requested, copy as much as requested 18470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // consume data: 1/ copy to given destination 18570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi memcpy(bufferLoc, pSrc, buffSize); 18670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // 2/ keep track of how much has been consumed 18770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi oldFront->mDataSizeConsumed += buffSize; 18870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // 3/ notify shared mem listener that new data is available 18970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi receivedBuffer_l(bufferId, buffSize); 19070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAvailableBuffers.erase(mAvailableBuffers.begin()); 19170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { 19270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // requested as much available or more: consume the whole of the current 19370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // buffer and move to the next 19470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi size_t consumed = oldFront->mDataSize - oldFront->mDataSizeConsumed; 195a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten //SL_LOGD("consuming rest of buffer: enqueueing=%u", consumed); 19670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi oldFront->mDataSizeConsumed = oldFront->mDataSize; 19770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 19870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // move queue to next 19970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (newFront == &mAndroidBufferQueue-> 20070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mBufferArray[mAndroidBufferQueue->mNumBuffers + 1]) { 20170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // reached the end, circle back 20270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi newFront = mAndroidBufferQueue->mBufferArray; 20370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 20470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue->mFront = newFront; 20570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue->mState.count--; 20670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAndroidBufferQueue->mState.index++; 20770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 20870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (consumed > 0) { 20970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // consume data: 1/ copy to given destination 21070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi memcpy(bufferLoc, pSrc, consumed); 21170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // 2/ keep track of how much has been consumed 21270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // here nothing to do because we are done with this buffer 21370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // 3/ notify StreamPlayer that new data is available 21470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi receivedBuffer_l(bufferId, consumed); 21570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAvailableBuffers.erase(mAvailableBuffers.begin()); 21670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 21770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 21870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // data has been consumed, and the buffer queue state has been updated 21970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // we will notify the client if applicable 2206bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi queueCallbackCandidate = true; 22170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 2226bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi } 2236bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi 2246bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi if (queueCallbackCandidate) { 2256bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi if (mAndroidBufferQueue->mCallbackEventsMask & 2266bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED) { 2276bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi callback = mAndroidBufferQueue->mCallback; 2286bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // save callback data while under lock 2296bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi callbackPContext = mAndroidBufferQueue->mContext; 2306bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi pBufferContext = (void *)oldFront->mBufferContext; 2316bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi pBufferData = (void *)oldFront->mDataBuffer; 2326bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi dataSize = oldFront->mDataSize; 2336bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // here a buffer is only dequeued when fully consumed 2346bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi //dataUsed = oldFront->mDataSizeConsumed; 235bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi } 23670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 2376bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi //SL_LOGD("%d buffers available after reading from queue", mAvailableBuffers.size()); 2386bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi if (!mAvailableBuffers.empty()) { 2396bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // there is still room in the shared memory, recheck later if we can pull 2406bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi // data from the buffer queue and write it to shared memory 2416bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi mPlayer->queueRefilled(); 2426bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi } 24370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 24470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 24570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { // empty queue 24670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi SL_LOGD("ABQ empty, starving!"); 2476bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi } 2486bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi#if 0 24970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // signal we're at the end of the content, but don't pause (see note in function) 25070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (mUserIsAudioPlayer) { 25170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // FIXME declare this external 25270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi //audioPlayer_dispatch_headAtEnd_lockPlay((CAudioPlayer*)user, 25370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // false /*set state to paused?*/, false); 25470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } else { 25570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // FIXME implement headAtEnd dispatch for CMediaPlayer 25670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 25770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 2586bc8af4e67051af7c86c311cb9c50e294e547500Jean-Michel Trivi#endif 25970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 26070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi interface_unlock_exclusive(mAndroidBufferQueue); 26170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 26270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi // notify client 26370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (NULL != callback) { 26457ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten SLresult result = (*callback)(&mAndroidBufferQueue->mItf, callbackPContext, 265677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten pBufferContext, pBufferData, dataSize, 266677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten dataSize, /* dataUsed */ 2671c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi // no messages during playback other than marking the buffer as processed 268677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten (const SLAndroidBufferItem*)(&kItemProcessed) /* pItems */, 269677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten NB_BUFFEREVENT_ITEM_FIELDS *sizeof(SLuint32) /* itemsLength */ ); 27057ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten if (SL_RESULT_SUCCESS != result) { 27157ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten // Reserved for future use 27257ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten SL_LOGW("Unsuccessful result %d returned from AndroidBufferQueueCallback", result); 27357ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten } 27470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 275485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten 276485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten mCallbackProtector->exitCb(); 277485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten } // enterCbIfOk 27870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi} 27970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 280be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 28126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi//-------------------------------------------------------------------------------------------------- 28268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviStreamPlayer::StreamPlayer(AudioPlayback_Parameters* params, bool hasVideo) : 28368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi GenericMediaPlayer(params, hasVideo), 28468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi mAppProxy(0) 285fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{ 286e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamPlayer::StreamPlayer()"); 287fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 28826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi mPlaybackParams = *params; 28926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 290fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 291fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 292fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel TriviStreamPlayer::~StreamPlayer() { 293e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamPlayer::~StreamPlayer()"); 294cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi 29526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi mAppProxy.clear(); 296fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 297fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 298fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 29970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivivoid StreamPlayer::onMessageReceived(const sp<AMessage> &msg) { 30070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi switch (msg->what()) { 301bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi case kWhatPullFromAbq: 302bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi onPullFromAndroidBufferQueue(); 30370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 30470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 30570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi default: 30670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi GenericMediaPlayer::onMessageReceived(msg); 30770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi break; 30870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 30970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi} 31070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 31170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 312d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid StreamPlayer::registerQueueCallback( 313d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi const void* user, bool userIsAudioPlayer, 314d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi void *context, 31594a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten const void *caller) { 316e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamPlayer::registerQueueCallback"); 31768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi Mutex::Autolock _l(mAppProxyLock); 31826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 31970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAppProxy = new StreamSourceAppProxy( 32070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi user, userIsAudioPlayer, 321bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi context, caller, mCallbackProtector, this); 32216ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi 323be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi CHECK(mAppProxy != 0); 324e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamPlayer::registerQueueCallback end"); 325be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi} 326be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 32770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi 32870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/** 329bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi * Asynchronously notify the player that the queue is ready to be pulled from. 33070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi */ 331bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivivoid StreamPlayer::queueRefilled() { 332bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi // async notification that the ABQ was refilled: the player should pull from the ABQ, and 333bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi // and push to shared memory (to the media server) 334bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi (new AMessage(kWhatPullFromAbq, id()))->post(); 335be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi} 336be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 337e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi 338e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivivoid StreamPlayer::appClear_l() { 33937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi // the user of StreamPlayer has cleared its AndroidBufferQueue: 34037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi // there's no clear() for the shared memory queue, so this is a no-op 34126043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi} 34226043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 343cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi 344cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi//-------------------------------------------------- 345cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi// Event handlers 346cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivivoid StreamPlayer::onPrepare() { 347e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SL_LOGD("StreamPlayer::onPrepare()"); 34868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi Mutex::Autolock _l(mAppProxyLock); 349eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi if (mAppProxy != 0) { 35085edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten sp<IMediaPlayerService> mediaPlayerService(getMediaPlayerService()); 35185edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten if (mediaPlayerService != NULL) { 35285edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten mPlayer = mediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/, 353e52e877354b1477d5cb34d24c70417820b013521Dave Burke mPlaybackParams.sessionId); 35485edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten if (mPlayer == NULL) { 35585edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten SL_LOGE("media player service failed to create player by app proxy"); 356e52e877354b1477d5cb34d24c70417820b013521Dave Burke } else if (mPlayer->setDataSource(mAppProxy /*IStreamSource*/) != NO_ERROR) { 357e52e877354b1477d5cb34d24c70417820b013521Dave Burke SL_LOGE("setDataSource failed"); 358e52e877354b1477d5cb34d24c70417820b013521Dave Burke mPlayer.clear(); 35985edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten } 36085edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten } 361eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi } else { 362eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi SL_LOGE("Nothing to do here because there is no registered callback"); 363eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi } 36485edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten if (mPlayer == NULL) { 36585edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten mStateFlags |= kFlagPreparedUnsuccessfully; 36685edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten } 36785edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten GenericMediaPlayer::onPrepare(); 36885edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten SL_LOGD("StreamPlayer::onPrepare() done"); 369cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi} 370cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi 371cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi 372b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivivoid StreamPlayer::onPlay() { 373b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi SL_LOGD("StreamPlayer::onPlay()"); 374b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi // enqueue a message that will cause StreamAppProxy to consume from the queue (again if the 375b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi // player had starved the shared memory) 376bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivi queueRefilled(); 377b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi 378b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi GenericMediaPlayer::onPlay(); 379b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi} 380b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi 381b712aebe63a6c50cc01f4493282fc77578242976Jean-Michel Trivi 382bc0e642e6c1a51b3ae3a02d490d94b03e718e6b5Jean-Michel Trivivoid StreamPlayer::onPullFromAndroidBufferQueue() { 38370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi //SL_LOGD("StreamPlayer::onQueueRefilled()"); 38470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi Mutex::Autolock _l(mAppProxyLock); 38570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (mAppProxy != 0) { 38670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi mAppProxy->pullFromBuffQueue(); 38770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 38870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi} 389cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi 390fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} // namespace android 391