IAndroidBufferQueue.c revision 682f9be91e641e80739c21d6ff124379a806182a
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
19bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi//#define USE_LOG SLAndroidLogLevel_Verbose
20fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
21bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "sles_allinclusive.h"
22bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi// for AAC ADTS verification on enqueue:
23bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "android/include/AacBqToPcmCbRenderer.h"
24d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
2570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/**
26682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten * Determine the state of the audio player or media player associated with a buffer queue.
27d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi *  Note that PLAYSTATE and RECORDSTATE values are equivalent (where PLAYING == RECORDING).
28d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi */
29d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
30d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivistatic SLuint32 getAssociatedState(IAndroidBufferQueue *thiz)
31d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi{
32d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    SLuint32 state;
33d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    switch (InterfaceToObjectID(thiz)) {
3470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      case XA_OBJECTID_MEDIAPLAYER:
35d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = ((CMediaPlayer *) thiz->mThis)->mPlay.mState;
36d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        break;
3770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi      case SL_OBJECTID_AUDIOPLAYER:
38d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        state = ((CAudioPlayer *) thiz->mThis)->mPlay.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 */
54682f9be91e641e80739c21d6ff124379a806182aGlenn Kastenstatic SLresult setItems(SLuint32 dataLength,
55682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        const SLAndroidBufferItem *pItems, SLuint32 itemsLength,
56682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        SLuint16 bufferType, AdvancedBufferHeader *pBuff, bool *pEOS)
5770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi{
58677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // reset item structure based on type
59677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    switch (bufferType) {
60677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeMpeg2Ts:
61677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        pBuff->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
62677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        pBuff->mItems.mTsCmdData.mPts = 0;
63677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        break;
64677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeAacadts:
65677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        pBuff->mItems.mAdtsCmdData.mAdtsCmdCode = ANDROID_ADTSEVENT_NONE;
66677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        break;
67677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeInvalid:
68677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      default:
69677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // shouldn't happen, but just in case clear out the item structure
70677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        memset(&pBuff->mItems, 0, sizeof(AdvancedBufferItems));
71682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        return SL_RESULT_INTERNAL_ERROR;
72677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    }
73677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
74677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // process all items in the array; if no items then we break out of loop immediately
75677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    while (itemsLength > 0) {
76677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
77677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // remaining length must be large enough for one full item without any associated data
78677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        if (itemsLength < sizeof(SLAndroidBufferItem)) {
79682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            SL_LOGE("Partial item at end of array");
80682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
8170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
82677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        itemsLength -= sizeof(SLAndroidBufferItem);
83677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
84677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // remaining length must be large enough for data with current item and alignment padding
85677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        SLuint32 itemDataSizeWithAlignmentPadding = (pItems->itemSize + 3) & ~3;
86677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        if (itemsLength < itemDataSizeWithAlignmentPadding) {
87682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            SL_LOGE("Partial item data at end of array");
88682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
89677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        }
90677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        itemsLength -= itemDataSizeWithAlignmentPadding;
91677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
9270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // parse item data based on type
9370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (bufferType) {
9470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
9570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts: {
966f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi            switch (pItems->itemKey) {
976f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi
986f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi              case SL_ANDROID_ITEMKEY_EOS:
9970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_EOS;
100a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten                //SL_LOGD("Found EOS event=%d", pBuff->mItems.mTsCmdData.mTsCmdCode);
101677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                if (pItems->itemSize != 0) {
102682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LOGE("Invalid item parameter size %u for EOS", pItems->itemSize);
103682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    return SL_RESULT_PARAMETER_INVALID;
104677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                }
1056f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                break;
1066f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi
1076f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi              case SL_ANDROID_ITEMKEY_DISCONTINUITY:
10870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                if (pItems->itemSize == 0) {
10970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCONTINUITY;
110a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten                    //SL_LOGD("Found DISCONTINUITYevent=%d", pBuff->mItems.mTsCmdData.mTsCmdCode);
111e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi                } else if (pItems->itemSize == sizeof(SLAuint64)) {
11270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCON_NEWPTS;
113e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi                    pBuff->mItems.mTsCmdData.mPts = *((SLAuint64*)pItems->itemData);
11470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                    //SL_LOGD("Found PTS=%lld", pBuff->mItems.mTsCmdData.mPts);
11570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                } else {
116682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LOGE("Invalid item parameter size %u for MPEG-2 PTS", pItems->itemSize);
117682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    return SL_RESULT_PARAMETER_INVALID;
11870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                }
1196f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                break;
1206f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi
1216f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi              case SL_ANDROID_ITEMKEY_FORMAT_CHANGE:
1226f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE;
1236f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                if (pItems->itemSize != 0) {
124682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LOGE("Invalid item parameter size %u for format change", pItems->itemSize);
125682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    return SL_RESULT_PARAMETER_INVALID;
126677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                }
127677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                break;
128677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
129677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten              default:
130677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                // unknown item key
131682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                SL_LOGE("Unknown item key %u with size %u", pItems->itemKey, pItems->itemSize);
132682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                return SL_RESULT_PARAMETER_INVALID;
133677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
134677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            }// switch (pItems->itemKey)
135677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          } break;
136677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
137677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case kAndroidBufferTypeAacadts: {
138677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            switch (pItems->itemKey) {
139677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
140677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten              case SL_ANDROID_ITEMKEY_EOS:
141677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                pBuff->mItems.mAdtsCmdData.mAdtsCmdCode |= ANDROID_ADTSEVENT_EOS;
142677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                if (pItems->itemSize != 0) {
143682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LOGE("Invalid item parameter size %u for EOS", pItems->itemSize);
144682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    return SL_RESULT_PARAMETER_INVALID;
1456f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                }
1466f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi                break;
1476f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi
1486f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi              default:
149677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                // unknown item key
150682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                SL_LOGE("Unknown item key %u with size %u", pItems->itemKey, pItems->itemSize);
151682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                return SL_RESULT_PARAMETER_INVALID;
152677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
1536f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi            }// switch (pItems->itemKey)
1546f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi          } break;
15570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
156677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case kAndroidBufferTypeInvalid:
15770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
158677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            // not reachable as we checked this earlier
159682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            return SL_RESULT_INTERNAL_ERROR;
160677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
1616f0f5640d190b0187c356eb53bd96d9f9e49da60Jean-Michel Trivi        }// switch (bufferType)
162677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
163677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // skip past this item, including data with alignment padding
164677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        pItems = (SLAndroidBufferItem *) ((char *) pItems +
165677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                sizeof(SLAndroidBufferItem) + itemDataSizeWithAlignmentPadding);
166677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    }
167677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
168677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // now check for invalid combinations of items
169677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    switch (bufferType) {
170677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
171677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeMpeg2Ts: {
172677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // supported Mpeg2Ts commands are mutually exclusive
173677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        switch (pBuff->mItems.mTsCmdData.mTsCmdCode) {
174677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          // single items are allowed
175677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case ANDROID_MP2TSEVENT_EOS:
176682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            if (dataLength > 0) {
177682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                SL_LOGE("Can't enqueue non-zero data with EOS");
178682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                return SL_RESULT_PRECONDITIONS_VIOLATED;
179682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            }
180682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            *pEOS = true;
181682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            break;
182682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten          case ANDROID_MP2TSEVENT_NONE:
183677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case ANDROID_MP2TSEVENT_DISCONTINUITY:
184677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case ANDROID_MP2TSEVENT_DISCON_NEWPTS:
185677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          case ANDROID_MP2TSEVENT_FORMAT_CHANGE:
186677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            break;
187677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          // no combinations are allowed
188677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten          default:
189682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            SL_LOGE("Invalid combination of items");
190682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
191677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        }
192677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      } break;
193677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
194677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeAacadts: {
195677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // only one item supported, and thus no combination check needed
196682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        if (pBuff->mItems.mAdtsCmdData.mAdtsCmdCode == ANDROID_ADTSEVENT_EOS) {
197682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            if (dataLength > 0) {
198682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                SL_LOGE("Can't enqueue non-zero data with EOS");
199682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                return SL_RESULT_PRECONDITIONS_VIOLATED;
200682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            }
201682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            *pEOS = true;
202682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        }
203677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      } break;
204677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
205677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      case kAndroidBufferTypeInvalid:
206677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten      default:
207677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        // not reachable as we checked this earlier
208682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        return SL_RESULT_INTERNAL_ERROR;
20970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
210677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten
211682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    return SL_RESULT_SUCCESS;
21270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi}
21370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
21470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
2151c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_RegisterCallback(SLAndroidBufferQueueItf self,
216fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi        slAndroidBufferQueueCallback callback, void *pContext)
217fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
218fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
219fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
220bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
221fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
222bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_lock_exclusive(thiz);
223fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
224fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    // verify pre-condition that media object is in the SL_PLAYSTATE_STOPPED state
22570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    if (SL_PLAYSTATE_STOPPED == getAssociatedState(thiz)) {
226bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mCallback = callback;
227bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mContext = pContext;
22870e6a0238597223221a8bf5e506c92acf28aa35fGlenn Kasten        result = SL_RESULT_SUCCESS;
229eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi
23070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    } else {
23170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        result = SL_RESULT_PRECONDITIONS_VIOLATED;
23270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    }
233fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
234bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
235fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
236fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
237fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
238fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
239fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
2401c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
241fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
242fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
243e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    result = SL_RESULT_SUCCESS;
244fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
245bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
246fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
247bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_lock_exclusive(thiz);
248fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
249e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // reset the queue pointers
250e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mFront = &thiz->mBufferArray[0];
251e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mRear = &thiz->mBufferArray[0];
252e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // reset the queue state
253e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mState.count = 0;
254e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    thiz->mState.index = 0;
255e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
256682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    // object-specific behavior for a clear
257682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    switch (InterfaceToObjectID(thiz)) {
258682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    case SL_OBJECTID_AUDIOPLAYER:
259682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
260682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
261682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    case XA_OBJECTID_MEDIAPLAYER:
262682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        android_Player_androidBufferQueue_clear_l((CMediaPlayer*) thiz->mThis);
263682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
264682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    default:
265682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
266e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    }
267fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
268bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    interface_unlock_exclusive(thiz);
269fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
270fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
271fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
272fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
273fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
2741c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_Enqueue(SLAndroidBufferQueueItf self,
27537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        void *pBufferContext,
27637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        void *pData,
277d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 dataLength,
278d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        const SLAndroidBufferItem *pItems,
279d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SLuint32 itemsLength)
280fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
281fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_ENTER_INTERFACE
282bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    SL_LOGD("IAndroidBufferQueue_Enqueue pData=%p dataLength=%d", pData, dataLength);
283fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
284677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    if ((dataLength > 0) && (NULL == pData)) {
285677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        SL_LOGE("Enqueue failure: non-zero data length %u but NULL data pointer", dataLength);
286677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
287677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    } else if ((itemsLength > 0) && (NULL == pItems)) {
288677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        SL_LOGE("Enqueue failure: non-zero items length %u but NULL items pointer", itemsLength);
289677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
290677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    } else if ((0 == dataLength) && (0 == itemsLength)) {
291d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // no data and no msg
292d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        SL_LOGE("Enqueue failure: trying to enqueue buffer with no data and no items.");
293d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
294677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // Note that a non-NULL data pointer with zero data length is allowed.
295677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // We track that data pointer as it moves through the queue
296677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // to assist the application in accounting for data buffers.
297677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten    // A non-NULL items pointer with zero items length is also allowed, but has no value.
298d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    } else {
299d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
300fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
30170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        // buffer size check, can be done outside of lock because buffer type can't change
30270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        switch (thiz->mBufferType) {
30370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeMpeg2Ts:
304682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            if (dataLength % MPEG2_TS_PACKET_SIZE == 0) {
305682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                // The downstream Stagefright MPEG-2 TS parser is sensitive to format errors,
306682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                // so do a quick sanity check beforehand on the first packet of the buffer.
307682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                // We don't check all the packets to avoid thrashing the data cache.
308682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                if ((dataLength > 0) && (*(SLuint8 *)pData != MPEG2_TS_PACKET_SYNC)) {
309682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LOGE("Error enqueueing MPEG-2 TS data: incorrect packet sync");
310682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    result = SL_RESULT_CONTENT_CORRUPTED;
311682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    SL_LEAVE_INTERFACE
312682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                }
31370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                break;
31470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            }
315682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            SL_LOGE("Error enqueueing MPEG-2 TS data: size must be a multiple of %d (packet size)",
316682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    MPEG2_TS_PACKET_SIZE);
317bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
318bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            SL_LEAVE_INTERFACE
319bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            break;
320bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi          case kAndroidBufferTypeAacadts:
321682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            // zero dataLength is permitted in case of EOS command only
322677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            if (dataLength > 0) {
323677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                result = android::AacBqToPcmCbRenderer::validateBufferStartEndOnFrameBoundaries(
324677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                    pData, dataLength);
325677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                if (SL_RESULT_SUCCESS != result) {
326677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                    SL_LOGE("Error enqueueing ADTS data: data must start and end on frame "
327677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                            "boundaries");
328677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                    SL_LEAVE_INTERFACE
329677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten                }
330bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            }
331bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi            break;
33270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          case kAndroidBufferTypeInvalid:
33370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi          default:
33470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
33570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi            SL_LEAVE_INTERFACE
33670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi        }
33770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
338d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_lock_exclusive(thiz);
339fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
340d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        AdvancedBufferHeader *oldRear = thiz->mRear, *newRear;
341d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        if ((newRear = oldRear + 1) == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
342d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            newRear = thiz->mBufferArray;
343d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
344682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        if (thiz->mEOS) {
345682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            SL_LOGE("Can't enqueue after EOS");
346682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            result = SL_RESULT_PRECONDITIONS_VIOLATED;
347682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        } else if (newRear == thiz->mFront) {
348d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi            result = SL_RESULT_BUFFER_INSUFFICIENT;
349d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        } else {
350677c76347d9aaca4cf3746b3dbfc8a741281066bGlenn Kasten            // set oldRear->mItems based on items
351682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            result = setItems(dataLength, pItems, itemsLength, thiz->mBufferType, oldRear,
352682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                    &thiz->mEOS);
353682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            if (SL_RESULT_SUCCESS == result) {
354682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                oldRear->mDataBuffer = pData;
355682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                oldRear->mDataSize = dataLength;
356682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                oldRear->mDataSizeConsumed = 0;
357682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                oldRear->mBufferContext = pBufferContext;
358682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                //oldRear->mBufferState = TBD;
359682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                thiz->mRear = newRear;
360682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                ++thiz->mState.count;
361682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            }
362d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        }
363d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        // set enqueue attribute if state is PLAYING and the first buffer is enqueued
364d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        interface_unlock_exclusive_attributes(thiz, ((SL_RESULT_SUCCESS == result) &&
365d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi                (1 == thiz->mState.count) && (SL_PLAYSTATE_PLAYING == getAssociatedState(thiz))) ?
36670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi                        ATTR_ABQ_ENQUEUE : ATTR_NONE);
367eae4df541ba1d46f65d37e959baf2127aa632c93Jean-Michel Trivi    }
368fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
369fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    SL_LEAVE_INTERFACE
370fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
371fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
372fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
3731c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_GetState(SLAndroidBufferQueueItf self,
374e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        SLAndroidBufferQueueState *pState)
375e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi{
376e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    SL_ENTER_INTERFACE
377e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
378e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    // Note that GetState while a Clear is pending is equivalent to GetState before the Clear
379e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
380e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    if (NULL == pState) {
381e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
382e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    } else {
383e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
384e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
385e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        interface_lock_shared(thiz);
386e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
387e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        pState->count = thiz->mState.count;
388e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        pState->index = thiz->mState.index;
389e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
390e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        interface_unlock_shared(thiz);
391e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
392e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi        result = SL_RESULT_SUCCESS;
393e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    }
394e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
395e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    SL_LEAVE_INTERFACE
396e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi}
397e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
398e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi
3991c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_SetCallbackEventsMask(SLAndroidBufferQueueItf self,
4001c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        SLuint32 eventFlags)
4011c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi{
4021c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    SL_ENTER_INTERFACE
4031c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4041c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
4051c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    interface_lock_exclusive(thiz);
4061c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    // FIXME only supporting SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED in this implementation
407682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    if (!(~(SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED /* | others TBD */ ) & eventFlags)) {
4081c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        thiz->mCallbackEventsMask = eventFlags;
4091c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        result = SL_RESULT_SUCCESS;
4101c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    } else {
4111c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        result = SL_RESULT_FEATURE_UNSUPPORTED;
4121c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    }
4131c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    interface_unlock_exclusive(thiz);
4141c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4151c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    SL_LEAVE_INTERFACE
4161c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi}
4171c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4181c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4191c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivistatic SLresult IAndroidBufferQueue_GetCallbackEventsMask(SLAndroidBufferQueueItf self,
4201c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        SLuint32 *pEventFlags)
4211c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi{
4221c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    SL_ENTER_INTERFACE
4231c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4241c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    if (NULL == pEventFlags) {
4251c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
4261c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    } else {
4271c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
428b566926611b2105a46c4ff98238ad06aca54104dGlenn Kasten        interface_lock_shared(thiz);
4291c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        SLuint32 callbackEventsMask = thiz->mCallbackEventsMask;
430b566926611b2105a46c4ff98238ad06aca54104dGlenn Kasten        interface_unlock_shared(thiz);
4311c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        *pEventFlags = callbackEventsMask;
4321c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi        result = SL_RESULT_SUCCESS;
4331c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    }
4341c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4351c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    SL_LEAVE_INTERFACE
4361c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi}
4371c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
4381c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi
439fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivistatic const struct SLAndroidBufferQueueItf_ IAndroidBufferQueue_Itf = {
440fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_RegisterCallback,
441fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi    IAndroidBufferQueue_Clear,
442e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi    IAndroidBufferQueue_Enqueue,
4431c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    IAndroidBufferQueue_GetState,
4441c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    IAndroidBufferQueue_SetCallbackEventsMask,
4451c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    IAndroidBufferQueue_GetCallbackEventsMask
446fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi};
447fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
448d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
449fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivivoid IAndroidBufferQueue_init(void *self)
450fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi{
451bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
452bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mItf = &IAndroidBufferQueue_Itf;
453fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi
454d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.count = 0;
455d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mState.index = 0;
456d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
457bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mCallback = NULL;
458bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mContext = NULL;
4591c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi    thiz->mCallbackEventsMask = SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED;
460d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
46170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi    thiz->mBufferType = kAndroidBufferTypeInvalid;
462d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mBufferArray = NULL;
463d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mFront = NULL;
464d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    thiz->mRear = NULL;
465682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    thiz->mEOS = false;
466d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi}
467d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
468d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi
469d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivivoid IAndroidBufferQueue_deinit(void *self)
470d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi{
471d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
472d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    if (NULL != thiz->mBufferArray) {
473d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        free(thiz->mBufferArray);
474d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi        thiz->mBufferArray = NULL;
475d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi    }
476fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi}
477682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten
478682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten
479682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten#if 0
480682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten// Dump the contents of an IAndroidBufferQueue to the log.  This is for debugging only,
481682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten// and is not a documented API.  The associated object is locked throughout for atomicity,
482682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten// but the log entries may be interspersed with unrelated logs.
483682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten
484682f9be91e641e80739c21d6ff124379a806182aGlenn Kastenvoid IAndroidBufferQueue_log(IAndroidBufferQueue *thiz)
485682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten{
486682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    interface_lock_shared(thiz);
487682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    SL_LOGI("IAndroidBufferQueue %p:", thiz);
488682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    SL_LOGI("  mState.count=%u mState.index=%u mCallback=%p mContext=%p",
489682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mState.count, thiz->mState.index, thiz->mCallback, thiz->mContext);
490682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    const char *bufferTypeString;
491682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    switch (thiz->mBufferType) {
492682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    case kAndroidBufferTypeInvalid:
493682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        bufferTypeString = "kAndroidBufferTypeInvalid";
494682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
495682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    case kAndroidBufferTypeMpeg2Ts:
496682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        bufferTypeString = "kAndroidBufferTypeMpeg2Ts";
497682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
498682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    case kAndroidBufferTypeAacadts:
499682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        bufferTypeString = "kAndroidBufferTypeAacadts";
500682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
501682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    default:
502682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        bufferTypeString = "unknown";
503682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        break;
504682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    }
505682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    SL_LOGI("  mCallbackEventsMask=0x%x, mBufferType=0x%x (%s), mEOS=%s",
506682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mCallbackEventsMask,
507682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mBufferType, bufferTypeString,
508682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mEOS ? "true" : "false");
509682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    SL_LOGI("  mBufferArray=%p, mFront=%p (%u), mRear=%p (%u)",
510682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mBufferArray,
511682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mFront, thiz->mFront - thiz->mBufferArray,
512682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            thiz->mRear, thiz->mRear - thiz->mBufferArray);
513682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    SL_LOGI("  index mDataBuffer mDataSize mDataSizeConsumed mBufferContext mItems");
514682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    const AdvancedBufferHeader *hdr;
515682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    for (hdr = thiz->mFront; hdr != thiz->mRear; ) {
516682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        SLuint32 i = hdr - thiz->mBufferArray;
517682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        char itemString[32];
518682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        switch (thiz->mBufferType) {
519682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        case kAndroidBufferTypeMpeg2Ts:
520682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            switch (hdr->mItems.mTsCmdData.mTsCmdCode) {
521682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_MP2TSEVENT_NONE:
522682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "NONE");
523682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
524682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_MP2TSEVENT_EOS:
525682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "EOS");
526682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
527682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_MP2TSEVENT_DISCONTINUITY:
528682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "DISCONTINUITY");
529682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
530682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_MP2TSEVENT_DISCON_NEWPTS:
531682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                snprintf(itemString, sizeof(itemString), "NEWPTS %llu",
532682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                        hdr->mItems.mTsCmdData.mPts);
533682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
534682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_MP2TSEVENT_FORMAT_CHANGE:
535682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "FORMAT_CHANGE");
536682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
537682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            default:
538682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                snprintf(itemString, sizeof(itemString), "0x%x", hdr->mItems.mTsCmdData.mTsCmdCode);
539682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
540682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            }
541682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            break;
542682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        case kAndroidBufferTypeAacadts:
543682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            switch (hdr->mItems.mAdtsCmdData.mAdtsCmdCode) {
544682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_ADTSEVENT_NONE:
545682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "NONE");
546682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
547682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            case ANDROID_ADTSEVENT_EOS:
548682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                strcpy(itemString, "EOS");
549682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
550682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            default:
551682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                snprintf(itemString, sizeof(itemString), "0x%x",
552682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                        hdr->mItems.mAdtsCmdData.mAdtsCmdCode);
553682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                break;
554682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            }
555682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            break;
556682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        default:
557682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            strcpy(itemString, "");
558682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            break;
559682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        }
560682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        SL_LOGI("  %5u %11p %9u %17u %14p %s",
561682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                i, hdr->mDataBuffer, hdr->mDataSize, hdr->mDataSizeConsumed,
562682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                hdr->mBufferContext, itemString);
563682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten                // mBufferState
564682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        if (++hdr == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
565682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten            hdr = thiz->mBufferArray;
566682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten        }
567682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    }
568682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten    interface_unlock_shared(thiz);
569682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten}
570682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten
571682f9be91e641e80739c21d6ff124379a806182aGlenn Kasten#endif
572