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