1bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi/* 2bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 3bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * 4bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * you may not use this file except in compliance with the License. 6bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * You may obtain a copy of the License at 7bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * 8bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * 10bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * See the License for the specific language governing permissions and 14bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi * limitations under the License. 15bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi */ 16bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 17bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi//#define USE_LOG SLAndroidLogLevel_Verbose 18bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 19bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "sles_allinclusive.h" 20bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "android/BufferQueueSource.h" 21bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 225f12770df2875b280acaf6a0de08ae0b57c930cfJames Dong#include <media/stagefright/foundation/ADebug.h> 23bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <sys/types.h> 24bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <unistd.h> 25bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <sys/types.h> 26bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <sys/stat.h> 27bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <fcntl.h> 28bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 29bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivinamespace android { 30bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 31bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 32bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Triviconst SLuint32 BufferQueueSource::kItemProcessed[NB_BUFFEREVENT_ITEM_FIELDS] = { 33bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_ANDROID_ITEMKEY_BUFFERQUEUEEVENT, // item key 34bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi sizeof(SLuint32), // item size 35bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED // item data 36bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi}; 37bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 38bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 3970e6a0238597223221a8bf5e506c92acf28aa35fGlenn KastenBufferQueueSource::BufferQueueSource(IAndroidBufferQueue *androidBufferQueue) : 4070e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten mAndroidBufferQueueSource(androidBufferQueue), 41113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi mStreamToBqOffset(0), 42113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi mEosReached(false) 43bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi{ 44bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 45bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 46bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 47bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel TriviBufferQueueSource::~BufferQueueSource() { 48bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::~BufferQueueSource"); 49bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 50bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 51bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 52bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi//-------------------------------------------------------------------------- 53bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivistatus_t BufferQueueSource::initCheck() const { 54bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return mAndroidBufferQueueSource != NULL ? OK : NO_INIT; 55bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 56bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 57bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivissize_t BufferQueueSource::readAt(off64_t offset, void *data, size_t size) { 58bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::readAt(offset=%lld, data=%p, size=%d)", offset, data, size); 59bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 60113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi if (mEosReached) { 61113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi // once EOS has been received from the buffer queue, you can't read anymore 62113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi return 0; 63113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi } 64113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi 65c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten ssize_t readSize; 66bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi slAndroidBufferQueueCallback callback = NULL; 67c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten void* pBufferContext, *pBufferData, *callbackPContext; 68c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten uint32_t dataSize, dataUsed; 69bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 70bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi interface_lock_exclusive(mAndroidBufferQueueSource); 71bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 72bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (mAndroidBufferQueueSource->mState.count == 0) { 73bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = 0; 74bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } else { 75bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi assert(mAndroidBufferQueueSource->mFront != mAndroidBufferQueueSource->mRear); 76bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 77c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten AdvancedBufferHeader *oldFront = mAndroidBufferQueueSource->mFront; 78bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi AdvancedBufferHeader *newFront = &oldFront[1]; 79bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 805760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi // where to read from 815760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi char *pSrc = NULL; 825760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi // can this read operation cause us to call the buffer queue callback 835760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi // (either because there was a command with no data, or all the data has been consumed) 845760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi bool queueCallbackCandidate = false; 855760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi 86bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consume events when starting to read data from a buffer for the first time 87bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (oldFront->mDataSizeConsumed == 0) { 88bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (oldFront->mItems.mAdtsCmdData.mAdtsCmdCode & ANDROID_ADTSEVENT_EOS) { 89113a9f14ea680a441540436b342f5008605aba27Jean-Michel Trivi mEosReached = true; 905760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi // EOS has no associated data 915760ef34bd7f50060fd8fbda10e359f8a830bfbcJean-Michel Trivi queueCallbackCandidate = true; 92bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 93bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi oldFront->mItems.mAdtsCmdData.mAdtsCmdCode = ANDROID_ADTSEVENT_NONE; 94bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 95bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 96bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi //assert(mStreamToBqOffset <= offset); 975f12770df2875b280acaf6a0de08ae0b57c930cfJames Dong CHECK_LE(mStreamToBqOffset, offset); 98bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 99b61bb82c208b2ef75f070199ca82269c4445663eAurimas Liutikas if (offset + (off64_t) size <= mStreamToBqOffset + oldFront->mDataSize) { 100bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pSrc = ((char*)oldFront->mDataBuffer) + (offset - mStreamToBqOffset); 101bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 102bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (offset - mStreamToBqOffset + size == oldFront->mDataSize) { 103bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consumed buffer entirely 104bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi oldFront->mDataSizeConsumed = oldFront->mDataSize; 105bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mStreamToBqOffset += oldFront->mDataSize; 106bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi queueCallbackCandidate = true; 107bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 108bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // move queue to next buffer 109bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (newFront == &mAndroidBufferQueueSource-> 110bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mBufferArray[mAndroidBufferQueueSource->mNumBuffers + 1]) { 111bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // reached the end, circle back 112bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi newFront = mAndroidBufferQueueSource->mBufferArray; 113bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 114bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mFront = newFront; 115bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // update the queue state 116bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mState.count--; 117bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mState.index++; 118bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGV("BufferQueueSource moving to next buffer"); 119bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 120bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 121bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 122bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consume data: copy to given destination 123bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (NULL != pSrc) { 124bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi memcpy(data, pSrc, size); 125bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = size; 126bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } else { 127bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = 0; 128bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 129bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 130bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (queueCallbackCandidate) { 131bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // data has been consumed, and the buffer queue state has been updated 132bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // we will notify the client if applicable 133bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (mAndroidBufferQueueSource->mCallbackEventsMask & 134bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED) { 135bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi callback = mAndroidBufferQueueSource->mCallback; 136bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // save callback data while under lock 137bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi callbackPContext = mAndroidBufferQueueSource->mContext; 138bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferContext = (void *)oldFront->mBufferContext; 139bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferData = (void *)oldFront->mDataBuffer; 140bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi dataSize = oldFront->mDataSize; 141bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi dataUsed = oldFront->mDataSizeConsumed; 142bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 143bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 144bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 145bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 146bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi interface_unlock_exclusive(mAndroidBufferQueueSource); 147bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 148bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // notify client 149bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (NULL != callback) { 15057ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten SLresult result = (*callback)(&mAndroidBufferQueueSource->mItf, callbackPContext, 151bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferContext, pBufferData, dataSize, dataUsed, 152bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // no messages during playback other than marking the buffer as processed 153bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi (const SLAndroidBufferItem*)(&kItemProcessed) /* pItems */, 154bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi NB_BUFFEREVENT_ITEM_FIELDS * sizeof(SLuint32) /* itemsLength */ ); 15557ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten if (SL_RESULT_SUCCESS != result) { 15657ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten // Reserved for future use 15757ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten SL_LOGW("Unsuccessful result %d returned from AndroidBufferQueueCallback", result); 15857ec2b5fbd0c7c08f068e1f7b9d7644b0932617bGlenn Kasten } 159bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 160bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 161bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return readSize; 162bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 163bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 164bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 165bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivistatus_t BufferQueueSource::getSize(off64_t *size) { 166bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::getSize()"); 167bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // we're streaming, we don't know how much there is 168bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi *size = 0; 1694efb2aa0d563b86b3c95d418d6d61d97f51c0bbbGlenn Kasten return ERROR_UNSUPPORTED; 170bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 171bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 172bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} // namespace android 173