IAndroidBufferQueue.c revision 70c49ae2867094072a4365423417ea452bf82231
1fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi/*
2fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi *
4fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * you may not use this file except in compliance with the License.
6fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * You may obtain a copy of the License at
7fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi *
8fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi *
10fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * See the License for the specific language governing permissions and
14fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi * limitations under the License.
15fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi */
16fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
17fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi/* AndroidBufferQueue implementation */
18fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
19fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi#include "sles_allinclusive.h"
20fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
21d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
2270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/**
2370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * Determine the state of the audio player or audio recorder associated with a buffer queue.
24d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi *  Note that PLAYSTATE and RECORDSTATE values are equivalent (where PLAYING == RECORDING).
25d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi */
26d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
27d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivistatic SLuint32 getAssociatedState(IAndroidBufferQueue *thiz)
28d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi{
29d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    SLuint32 state;
30d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    switch (InterfaceToObjectID(thiz)) {
3170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      case XA_OBJECTID_MEDIAPLAYER:
32d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = ((CMediaPlayer *) thiz->mThis)->mPlay.mState;
33d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        break;
3470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      case SL_OBJECTID_AUDIOPLAYER:
35d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = ((CAudioPlayer *) thiz->mThis)->mPlay.mState;
36d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        break;
3770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      case SL_OBJECTID_AUDIORECORDER:
38d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = ((CAudioRecorder *) thiz->mThis)->mRecord.mState;
39d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        break;
4070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      default:
41d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // unreachable, but just in case we will assume it is stopped
42d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        assert(SL_BOOLEAN_FALSE);
43d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = SL_PLAYSTATE_STOPPED;
44d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        break;
45d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
46d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    return state;
47d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi}
48d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
49d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
5070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/**
5170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * parse and set the items associated with the given buffer, based on the buffer type,
5270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * which determines the set of authorized items and format
5370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi */
5470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivistatic void setItems(const SLAndroidBufferItem *pItems, SLuint32 itemsLength,
5570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        SLuint16 bufferType, AdvancedBufferHeader *pBuff)
5670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi{
5770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if ((NULL == pItems) || (0 == itemsLength)) {
5870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // no item data, reset item structure based on type
5970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (bufferType) {
6070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts:
6170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            pBuff->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
6270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            pBuff->mItems.mTsCmdData.mPts = 0;
6370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
6470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeInvalid:
6570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
6670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            return;
6770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
6870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
6970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // parse item data based on type
7070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (bufferType) {
7170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
7270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts: {
7370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            SLuint32 index = 0;
7470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // supported Mpeg2Ts commands are mutually exclusive
7570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (SL_ANDROID_ITEMKEY_EOS == pItems->itemKey) {
7670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_EOS;
7770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                //SL_LOGD("Found EOS event=%ld", pBuff->mItems.mTsCmdData.mTsCmdCode);
7870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else if (SL_ANDROID_ITEMKEY_DISCONTINUITY == pItems->itemKey) {
7970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                if (pItems->itemSize == 0) {
8070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCONTINUITY;
8170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //SL_LOGD("Found DISCONTINUITYevent=%ld", pBuff->mItems.mTsCmdData.mTsCmdCode);
8270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                } else if (pItems->itemSize == sizeof(SLAint64)) {
8370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCON_NEWPTS;
8470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mPts = *((SLAint64*)pItems->itemData);
8570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //SL_LOGD("Found PTS=%lld", pBuff->mItems.mTsCmdData.mPts);
8670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                } else {
8770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    SL_LOGE("Invalid size for MPEG-2 PTS, ignoring value");
8870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCONTINUITY;
8970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                }
9070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            } else {
9170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                pBuff->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
9270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
9370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            break;
9470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          }
9570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
9670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
9770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            return;
9870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
9970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
10070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
10170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
10270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
103fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult IAndroidBufferQueue_RegisterCallback(SLAndroidBufferQueueItf self,
104fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi        slAndroidBufferQueueCallback callback, void *pContext)
105fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
106fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
107fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
108bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
109fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
110bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_lock_exclusive(thiz);
111fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
112fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    // verify pre-condition that media object is in the SL_PLAYSTATE_STOPPED state
11370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (SL_PLAYSTATE_STOPPED == getAssociatedState(thiz)) {
114bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mCallback = callback;
115bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mContext = pContext;
116eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi
117bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        switch (InterfaceToObjectID(thiz)) {
11870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case SL_OBJECTID_AUDIOPLAYER:
119eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
120bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            android_audioPlayer_androidBufferQueue_registerCallback_l((CAudioPlayer*) thiz->mThis);
121eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            break;
12270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case XA_OBJECTID_MEDIAPLAYER:
123eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            SL_LOGI("IAndroidBufferQueue_RegisterCallback()");
124eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
125bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            android_Player_androidBufferQueue_registerCallback_l((CMediaPlayer*) thiz->mThis);
126bdb08965172949ae07fefc8f3d46cbcffb77b0bdJean-Michel Trivi            break;
12770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
128eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
129eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi            break;
130eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi        }
131eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi
13270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
13370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        result = SL_RESULT_PRECONDITIONS_VIOLATED;
13470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
135fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
136bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
137fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
138fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
139fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
140fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
141fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
142fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
143fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
144fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
145fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
146bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
147fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
148bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_lock_exclusive(thiz);
149fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
15070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    // TODO return value?
15194a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten    result = SL_RESULT_SUCCESS;
152bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
153fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
154bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
155fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
156fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
157fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
158fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
159fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
160fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult IAndroidBufferQueue_Enqueue(SLAndroidBufferQueueItf self,
161d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const void *pData,
162d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 dataLength,
163d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const SLAndroidBufferItem *pItems,
164d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 itemsLength)
165fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
166fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
167fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
168d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if ( ((NULL == pData) || (0 == dataLength))
169d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            && ((NULL == pItems) || (0 == itemsLength))) {
170d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // no data and no msg
171d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SL_LOGE("Enqueue failure: trying to enqueue buffer with no data and no items.");
172d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
173d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    } else {
174d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
175fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
17670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // buffer size check, can be done outside of lock because buffer type can't change
17770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (thiz->mBufferType) {
17870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts:
17970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (dataLength % MPEG2_TS_BLOCK_SIZE == 0) {
18070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                break;
18170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
18270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // intended fall-through if test failed
18370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            SL_LOGE("Error enqueueing MPEG-2 TS data: size needs to be a multiple of %d",
18470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    MPEG2_TS_BLOCK_SIZE);
18570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeInvalid:
18670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
18770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
18870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            SL_LEAVE_INTERFACE
18970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
19070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
191d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_lock_exclusive(thiz);
192fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
193d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        AdvancedBufferHeader *oldRear = thiz->mRear, *newRear;
194d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if ((newRear = oldRear + 1) == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
195d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            newRear = thiz->mBufferArray;
196d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
197d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if (newRear == thiz->mFront) {
198d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            result = SL_RESULT_BUFFER_INSUFFICIENT;
199d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        } else {
200d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataBuffer = pData;
201d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataSize = dataLength;
202d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataSizeConsumed = 0;
203d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            thiz->mRear = newRear;
204d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            ++thiz->mState.count;
20570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            setItems(pItems, itemsLength, thiz->mBufferType, oldRear);
206d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
208d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // set enqueue attribute if state is PLAYING and the first buffer is enqueued
209d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_unlock_exclusive_attributes(thiz, ((SL_RESULT_SUCCESS == result) &&
210d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                (1 == thiz->mState.count) && (SL_PLAYSTATE_PLAYING == getAssociatedState(thiz))) ?
21170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        ATTR_ABQ_ENQUEUE : ATTR_NONE);
212eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    }
213fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
214fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
215fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
216fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
217fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
218fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivistatic const struct SLAndroidBufferQueueItf_ IAndroidBufferQueue_Itf = {
219fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_RegisterCallback,
220fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_Clear,
221fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_Enqueue
222fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi};
223fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
224d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
225fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivivoid IAndroidBufferQueue_init(void *self)
226fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
227bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
228bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mItf = &IAndroidBufferQueue_Itf;
229fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
230d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.count = 0;
231d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.index = 0;
232d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
233bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mCallback = NULL;
234bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mContext = NULL;
235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
23670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    thiz->mBufferType = kAndroidBufferTypeInvalid;
237d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mBufferArray = NULL;
238d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mFront = NULL;
239d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mRear = NULL;
240d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi}
241d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
242d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
243d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid IAndroidBufferQueue_deinit(void *self)
244d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi{
245d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
246d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if (NULL != thiz->mBufferArray) {
247d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        free(thiz->mBufferArray);
248d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        thiz->mBufferArray = NULL;
249d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
250fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
251