BufferQueueSource.cpp revision bb832e853d4afb11b0a3287b2eb0cad87696d631
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 22bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <media/stagefright/MediaDebug.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 39bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel TriviBufferQueueSource::BufferQueueSource(const void* user, void *context, const void *caller) : 40bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource(NULL), 41bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mStreamToBqOffset(0) 42bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi{ 43bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (NULL != user) { 44bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource = &((CAudioPlayer*)user)->mAndroidBufferQueue; 45bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } else { 46bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGE("Can't create BufferQueueSource with NULL user"); 47bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 48bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 49bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 50bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 51bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 52bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel TriviBufferQueueSource::~BufferQueueSource() { 53bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::~BufferQueueSource"); 54bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 55bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 56bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 57bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi//-------------------------------------------------------------------------- 58bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivistatus_t BufferQueueSource::initCheck() const { 59bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return mAndroidBufferQueueSource != NULL ? OK : NO_INIT; 60bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 61bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 62bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivissize_t BufferQueueSource::readAt(off64_t offset, void *data, size_t size) { 63bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::readAt(offset=%lld, data=%p, size=%d)", offset, data, size); 64bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 65bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi ssize_t readSize = 0; 66bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi slAndroidBufferQueueCallback callback = NULL; 67bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi void* pBufferContext, *pBufferData, *callbackPContext = NULL; 68bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi AdvancedBufferHeader *oldFront = NULL; 69bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi uint32_t dataSize, dataUsed = 0; 70bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 71bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi interface_lock_exclusive(mAndroidBufferQueueSource); 72bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 73bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (mAndroidBufferQueueSource->mState.count == 0) { 74bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = 0; 75bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } else { 76bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi assert(mAndroidBufferQueueSource->mFront != mAndroidBufferQueueSource->mRear); 77bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 78bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi oldFront = mAndroidBufferQueueSource->mFront; 79bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi AdvancedBufferHeader *newFront = &oldFront[1]; 80bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 81bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consume events when starting to read data from a buffer for the first time 82bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (oldFront->mDataSizeConsumed == 0) { 83bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (oldFront->mItems.mAdtsCmdData.mAdtsCmdCode & ANDROID_ADTSEVENT_EOS) { 84bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // FIXME handle EOS 85bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGE("---> FIXME: handle ANDROID_ADTSEVENT_EOS <---"); 86bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 87bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi oldFront->mItems.mAdtsCmdData.mAdtsCmdCode = ANDROID_ADTSEVENT_NONE; 88bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 89bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 90bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // where to read from 91bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi char *pSrc = NULL; 92bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // can this read operation cause us to call the buffer queue callback 93bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi bool queueCallbackCandidate = false; 94bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 95bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi //assert(mStreamToBqOffset <= offset); 96bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi CHECK(mStreamToBqOffset <= offset); 97bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 98bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (offset + size <= mStreamToBqOffset + oldFront->mDataSize) { 99bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pSrc = ((char*)oldFront->mDataBuffer) + (offset - mStreamToBqOffset); 100bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 101bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (offset - mStreamToBqOffset + size == oldFront->mDataSize) { 102bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consumed buffer entirely 103bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi oldFront->mDataSizeConsumed = oldFront->mDataSize; 104bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mStreamToBqOffset += oldFront->mDataSize; 105bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi queueCallbackCandidate = true; 106bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 107bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // move queue to next buffer 108bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (newFront == &mAndroidBufferQueueSource-> 109bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mBufferArray[mAndroidBufferQueueSource->mNumBuffers + 1]) { 110bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // reached the end, circle back 111bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi newFront = mAndroidBufferQueueSource->mBufferArray; 112bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 113bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mFront = newFront; 114bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // update the queue state 115bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mState.count--; 116bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi mAndroidBufferQueueSource->mState.index++; 117bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGV("BufferQueueSource moving to next buffer"); 118bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 119bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 120bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 121bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // consume data: copy to given destination 122bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (NULL != pSrc) { 123bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi memcpy(data, pSrc, size); 124bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = size; 125bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } else { 126bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi readSize = 0; 127bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 128bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 129bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (queueCallbackCandidate) { 130bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // data has been consumed, and the buffer queue state has been updated 131bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // we will notify the client if applicable 132bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (mAndroidBufferQueueSource->mCallbackEventsMask & 133bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED) { 134bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi callback = mAndroidBufferQueueSource->mCallback; 135bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // save callback data while under lock 136bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi callbackPContext = mAndroidBufferQueueSource->mContext; 137bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferContext = (void *)oldFront->mBufferContext; 138bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferData = (void *)oldFront->mDataBuffer; 139bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi dataSize = oldFront->mDataSize; 140bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi dataUsed = oldFront->mDataSizeConsumed; 141bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 142bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 143bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 144bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 145bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi interface_unlock_exclusive(mAndroidBufferQueueSource); 146bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 147bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // notify client 148bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi if (NULL != callback) { 149bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi (*callback)(&mAndroidBufferQueueSource->mItf, callbackPContext, 150bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi pBufferContext, pBufferData, dataSize, dataUsed, 151bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // no messages during playback other than marking the buffer as processed 152bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi (const SLAndroidBufferItem*)(&kItemProcessed) /* pItems */, 153bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi NB_BUFFEREVENT_ITEM_FIELDS * sizeof(SLuint32) /* itemsLength */ ); 154bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi } 155bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 156bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return readSize; 157bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 158bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 159bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 160bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivistatus_t BufferQueueSource::getSize(off64_t *size) { 161bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi SL_LOGD("BufferQueueSource::getSize()"); 162bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi // we're streaming, we don't know how much there is 163bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi *size = 0; 164bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi return OK; 165bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} 166bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi 167bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi} // namespace android 168