IAndroidBufferQueue.c revision 37dc2fccf3f122b79ebd554de209d0a3c94ae161
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        }
130eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi
13170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
13270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        result = SL_RESULT_PRECONDITIONS_VIOLATED;
13370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
134fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
135bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
136fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
137fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
138fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
139fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
140fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
141fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
142fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
143fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
144e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    result = SL_RESULT_SUCCESS;
145fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
146bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
147fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
148bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_lock_exclusive(thiz);
149fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
150e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // reset the queue pointers
151e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mFront = &thiz->mBufferArray[0];
152e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mRear = &thiz->mBufferArray[0];
153e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // reset the queue state
154e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mState.count = 0;
155e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mState.index = 0;
156e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // reset the individual buffers
157e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    for (XAuint16 i=0 ; i<(thiz->mNumBuffers + 1) ; i++) {
158e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        thiz->mBufferArray[i].mDataBuffer = NULL;
159e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        thiz->mBufferArray[i].mDataSize = 0;
160e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        thiz->mBufferArray[i].mDataSizeConsumed = 0;
16137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        thiz->mBufferArray[i].mBufferContext = NULL;
162e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        switch (thiz->mBufferType) {
163e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts:
164e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            thiz->mBufferArray[i].mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
165e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            thiz->mBufferArray[i].mItems.mTsCmdData.mPts = 0;
166e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            break;
167e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi          default:
168e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            result = SL_RESULT_CONTENT_UNSUPPORTED;
169e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        }
170e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    }
171e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
172e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    if (SL_RESULT_SUCCESS == result) {
173e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        // object-specific behavior for a clear
174e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        switch (InterfaceToObjectID(thiz)) {
175e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        case SL_OBJECTID_AUDIOPLAYER:
176e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
177e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
178e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            break;
179e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        case XA_OBJECTID_MEDIAPLAYER:
180e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
181e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            android_Player_androidBufferQueue_clear_l((CMediaPlayer*) thiz->mThis);
182e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            break;
183e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        default:
184e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
185e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        }
186e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    }
187fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
188bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
189fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
190fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
191fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
192fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
193fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
194fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult IAndroidBufferQueue_Enqueue(SLAndroidBufferQueueItf self,
19537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        void *pBufferContext,
19637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        void *pData,
197d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 dataLength,
198d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const SLAndroidBufferItem *pItems,
199d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 itemsLength)
200fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
201fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
202fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
203d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if ( ((NULL == pData) || (0 == dataLength))
204d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            && ((NULL == pItems) || (0 == itemsLength))) {
205d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // no data and no msg
206d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SL_LOGE("Enqueue failure: trying to enqueue buffer with no data and no items.");
207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
208d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    } else {
209d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
210fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
21170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // buffer size check, can be done outside of lock because buffer type can't change
21270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (thiz->mBufferType) {
21370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts:
21470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            if (dataLength % MPEG2_TS_BLOCK_SIZE == 0) {
21570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                break;
21670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
21770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            // intended fall-through if test failed
218e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi            SL_LOGE("Error enqueueing MPEG-2 TS data: size must be a multiple of %d (block size)",
21970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    MPEG2_TS_BLOCK_SIZE);
22070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeInvalid:
22170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
22270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
22370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            SL_LEAVE_INTERFACE
22470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
22570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
226d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_lock_exclusive(thiz);
227fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
228d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        AdvancedBufferHeader *oldRear = thiz->mRear, *newRear;
229d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if ((newRear = oldRear + 1) == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
230d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            newRear = thiz->mBufferArray;
231d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
232d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if (newRear == thiz->mFront) {
233d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            result = SL_RESULT_BUFFER_INSUFFICIENT;
234d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        } else {
235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataBuffer = pData;
236d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataSize = dataLength;
237d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            oldRear->mDataSizeConsumed = 0;
23837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi            oldRear->mBufferContext = pBufferContext;
239d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            thiz->mRear = newRear;
240d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            ++thiz->mState.count;
24170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            setItems(pItems, itemsLength, thiz->mBufferType, oldRear);
242d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
243d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
244d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // set enqueue attribute if state is PLAYING and the first buffer is enqueued
245d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_unlock_exclusive_attributes(thiz, ((SL_RESULT_SUCCESS == result) &&
246d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                (1 == thiz->mState.count) && (SL_PLAYSTATE_PLAYING == getAssociatedState(thiz))) ?
24770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        ATTR_ABQ_ENQUEUE : ATTR_NONE);
248eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    }
249fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
250fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
251fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
252fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
253fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
254e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel TriviSLresult IAndroidBufferQueue_GetState(SLAndroidBufferQueueItf self,
255e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        SLAndroidBufferQueueState *pState)
256e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi{
257e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    SL_ENTER_INTERFACE
258e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
259e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // Note that GetState while a Clear is pending is equivalent to GetState before the Clear
260e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
261e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    if (NULL == pState) {
262e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
263e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    } else {
264e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
265e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
266e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        interface_lock_shared(thiz);
267e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
268e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        pState->count = thiz->mState.count;
269e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        pState->index = thiz->mState.index;
270e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
271e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        interface_unlock_shared(thiz);
272e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
273e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        result = SL_RESULT_SUCCESS;
274e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    }
275e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
276e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    SL_LEAVE_INTERFACE
277e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi}
278e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
279e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
280fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivistatic const struct SLAndroidBufferQueueItf_ IAndroidBufferQueue_Itf = {
281fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_RegisterCallback,
282fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_Clear,
283e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    IAndroidBufferQueue_Enqueue,
284e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    IAndroidBufferQueue_GetState
285fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi};
286fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
287d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
288fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivivoid IAndroidBufferQueue_init(void *self)
289fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
290bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
291bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mItf = &IAndroidBufferQueue_Itf;
292fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
293d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.count = 0;
294d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.index = 0;
295d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
296bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mCallback = NULL;
297bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mContext = NULL;
298d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
29970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    thiz->mBufferType = kAndroidBufferTypeInvalid;
300d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mBufferArray = NULL;
301d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mFront = NULL;
302d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mRear = NULL;
303d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi}
304d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
305d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
306d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid IAndroidBufferQueue_deinit(void *self)
307d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi{
308d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
309d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if (NULL != thiz->mBufferArray) {
310d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        free(thiz->mBufferArray);
311d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        thiz->mBufferArray = NULL;
312d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
313fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
314