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
99bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi        if (offset + 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