1fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi/* 2fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project 3fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * 4fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 5fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * you may not use this file except in compliance with the License. 6fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * You may obtain a copy of the License at 7fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * 8fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 9fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * 10fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 11fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 12fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * See the License for the specific language governing permissions and 14fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi * limitations under the License. 15fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi */ 16fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 17fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 18fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <stdlib.h> 19fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <stdio.h> 20fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//#include <string.h> 21fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#include <unistd.h> 22fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//#include <sys/time.h> 23fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 24c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 25c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES_Android.h> 26fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 271c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi//#define TEST_DISPLAY_FIRST_BUFFER_ITEM 28e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi//#define TEST_CLEAR 29e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi//#define TEST_PTS 30fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 31fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define MAX_NUMBER_INTERFACES 2 32fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 33fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \ 34fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 35fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 36d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#define NB_BUFFERS 16 37d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi#define MPEG2_TS_BLOCK_SIZE 188 3837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi#define BUFFER_SIZE (20*MPEG2_TS_BLOCK_SIZE) 3937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi#define DISCONTINUITY_MAGIC 1977 40d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 41d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi/* Where we store the data to play */ 42d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivichar dataCache[BUFFER_SIZE * NB_BUFFERS]; 43d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi/* From where we read the data to play */ 4426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel TriviFILE *file; 4570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi/* Has the app reached the end of the file */ 4670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivibool reachedEof = false; 4737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi/* Special discontinuity buffer context */ 4837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Triviint myDiscBufferContext = DISCONTINUITY_MAGIC; 4926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 50e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi/* structure to store my discontinuity with PTS command */ 51e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivitypedef struct { 52e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SLuint32 discKey; // identifies the item 53e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SLuint32 discSize; 54e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi SLAuint64 discPts; 55e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi} DiscPts; 56e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi 57fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//----------------------------------------------------------------- 58e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi/* Exits the application if an error is encountered */ 59fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__) 60fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 61fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line) 62fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{ 63fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 6458432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line); 65fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi exit(EXIT_FAILURE); 66fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 67fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 68fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 69fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivibool prefetchError = false; 70fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 71fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//----------------------------------------------------------------- 72fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi/* AndroidBufferQueueItf callback for an audio player */ 73fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel TriviSLresult AndroidBufferQueueCallback( 74fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi SLAndroidBufferQueueItf caller, 75086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten void *pCallbackContext __unused, /* input */ 7637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi void *pBufferContext, /* input */ 77086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten void *pBufferData __unused, /* input */ 78086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten SLuint32 dataSize __unused, /* input */ 79086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten SLuint32 dataUsed __unused, /* input */ 80086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten const SLAndroidBufferItem *pItems __unused, /* input */ 81086a6f51a7b12880ed114962136972f89ed70da2Glenn Kasten SLuint32 itemsLength __unused /* input */) 82fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{ 83d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // assert(BUFFER_SIZE <= dataSize); 84e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi 85e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi //-------------------------------------------------------------------------------- 86e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // this section is for testing only, this is NOT an example of how to use the API 87e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // to play a .ts file, but rather shows more ways to exercise the API 88e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi //-------------------------------------------------------------------------------- 89e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi SLAndroidBufferQueueState state; 90e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi (*caller)->GetState(caller, &state); 91e31a69fcbe27894a597176d05a08e04c06092021Glenn Kasten //fprintf(stdout, "ABQ state count=%lu, index=%lu\n", state.count, state.index); 92e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi 93e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // just to test, clear the queue to see what happens 94e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi if (state.index == 500) { 95e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi#ifdef TEST_CLEAR 96e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi (*caller)->Clear(caller); 97e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // we've cleared the queue, and have introduced a discontinuity, so signal it 98e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi SLAndroidBufferItem msgDiscontinuity; 99e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi msgDiscontinuity.itemKey = SL_ANDROID_ITEMKEY_DISCONTINUITY; 100e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi msgDiscontinuity.itemSize = 0; 101e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // message has no parameters, so the total size of the message is the size of the key 102d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // plus the size if itemSize, both SLuint32 10337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi (*caller)->Enqueue(caller, (void*)&myDiscBufferContext /*pBufferContext*/, 10437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi NULL /*pData*/, 0 /*dataLength*/, 105e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi &msgDiscontinuity /*pMsg*/, 106e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi sizeof(SLuint32)*2 /*msgLength*/); 107e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // we've cleared the queue, it's now empty: let's rebuffer a bit so playback doesn't starve 1081c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi size_t nbRead = fread((void*)dataCache, 1, BUFFER_SIZE*(NB_BUFFERS/2), file); 109e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi if (nbRead == BUFFER_SIZE*(NB_BUFFERS/2)) { 110e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi for (int i=0 ; i < NB_BUFFERS/2 ; i++) { 11137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi SLresult res = (*caller)->Enqueue(caller, NULL /*pBufferContext*/, 11237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi dataCache + i*BUFFER_SIZE, 113e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi BUFFER_SIZE, NULL, 0); 114e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi CheckErr(res); 115e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 116e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 117e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi#endif 118e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi#ifdef TEST_PTS 119e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi DiscPts msgDiscontinuity = { SL_ANDROID_ITEMKEY_DISCONTINUITY, 120e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi sizeof(SLAuint64), 15*90*1000 /*15s in 90kHz clock */ }; 121e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi // enqueue discontinuity message with our PTS 122e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi (*caller)->Enqueue(caller, (void*)&myDiscBufferContext /*pBufferContext*/, 123e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi NULL /*pData*/, 0 /*dataLength*/, 124e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi (SLAndroidBufferItem*)&msgDiscontinuity, 125e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi sizeof(DiscPts) ); 126e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi fprintf(stdout, "rendering will resume at 15s mark"); 127e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi 128e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi#endif 129e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi return SL_RESULT_SUCCESS; 130e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 131e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi //-------------------------------------------------------------------------------- 132e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // end of test only section 133e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi //-------------------------------------------------------------------------------- 134e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi else { 135e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi 1361c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi#ifdef TEST_DISPLAY_FIRST_BUFFER_ITEM 1371c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi // display item data (only parsing first item) 1381c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi if (itemsLength !=0) { 1391c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi fprintf(stdout, "item key=0x%lx size=%lu data=0x%lx\n", 1401c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi pItems->itemKey, pItems->itemSize, *((SLuint32*)&pItems->itemData)); 1411c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi } 1421c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi#endif 1431c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi 144e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // pBufferData can be null if the last consumed buffer contained only a command 145e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // just like we do for signalling DISCONTINUITY (above) or EOS (below) 14637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi if ((pBufferContext != NULL) && (*((int*)pBufferContext) == DISCONTINUITY_MAGIC)) { 14737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi fprintf(stdout, "Successfully detected my discontinuity buffer having been consumed\n"); 14837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi } 149e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi if (pBufferData != NULL) { 150e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi size_t nbRead = fread((void*)pBufferData, 1, BUFFER_SIZE, file); 151e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi if (nbRead > 0) { 15237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi (*caller)->Enqueue(caller, NULL /*pBufferContext*/, 153e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi pBufferData /*pData*/, 154e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi nbRead /*dataLength*/, 155e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi NULL /*pMsg*/, 156e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi 0 /*msgLength*/); 157e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } else if (!reachedEof) { 158e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi // signal EOS 159e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi SLAndroidBufferItem msgEos; 160e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi msgEos.itemKey = SL_ANDROID_ITEMKEY_EOS; 161e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi msgEos.itemSize = 0; 16268686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten // EOS message has no parameters, so the total size of the message is the size of 16368686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten // the key plus the size if itemSize, both SLuint32 16437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi (*caller)->Enqueue(caller, NULL /*pBufferContext*/, 16537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi NULL /*pData*/, 0 /*dataLength*/, 166d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi &msgEos /*pMsg*/, 167d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi sizeof(SLuint32)*2 /*msgLength*/); 168e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi reachedEof = true; 169e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 170e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 171fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi 172e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi return SL_RESULT_SUCCESS; 173e7bfcdc183454ec959ff51342f0973cabba219b2Jean-Michel Trivi } 174fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 175fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 176fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 177fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//----------------------------------------------------------------- 178fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 179fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi/* Play some music from a URI */ 180fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivivoid TestPlayStream( SLObjectItf sl, const char* path) 181fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{ 182fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLEngineItf EngineItf; 183fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 184fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLint32 numOutputs = 0; 185fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLuint32 deviceID = 0; 186fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 187fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLresult res; 188fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 189fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLDataSource audioSource; 190fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi SLDataLocator_AndroidBufferQueue streamLocator; 191fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLDataFormat_MIME mime; 192fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 193fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLDataSink audioSink; 194fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 195fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 196fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLObjectItf player; 197fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLPlayItf playItf; 198fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLVolumeItf volItf; 199fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi SLAndroidBufferQueueItf abqItf; 200fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 201fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLObjectItf OutputMix; 202fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 203fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLboolean required[MAX_NUMBER_INTERFACES]; 204fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; 205fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 20670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi int playTimeInSec = 60; 207d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 20826043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi file = fopen(path, "rb"); 20926043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 210fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 211fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 212fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 213fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 214fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 215fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) { 216fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 217fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 218fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 219fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 220fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi // Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface 221fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 222fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 223fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 22460ca9f9ef02f6e486c3338cb811f603dd7825c05Glenn Kasten iidArray[1] = SL_IID_ANDROIDBUFFERQUEUESOURCE; 225fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi // Create Output Mix object to be used by player 226fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, 227fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi iidArray, required); CheckErr(res); 228fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 229fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi // Realizing the Output Mix object in synchronous mode. 230fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE); 231fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 232fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 233fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Setup the data source structure for the URI */ 234fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi streamLocator.locatorType = SL_DATALOCATOR_ANDROIDBUFFERQUEUE; 235d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi streamLocator.numBuffers = NB_BUFFERS; 236fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 23716ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi mime.mimeType = (SLchar *) "video/mp2ts";//(SLchar*)NULL; 23816ce39d96d41884c7b0d1676553ab8167baaab74Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_MPEG_TS; 239fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 240fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi audioSource.pFormat = (void *)&mime; 241ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi audioSource.pLocator = (void *)&streamLocator; 242fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 243fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Setup the data sink structure */ 244fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 245fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi locator_outputmix.outputMix = OutputMix; 246fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 247fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi audioSink.pFormat = NULL; 248fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 249fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Create the audio player */ 250fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 251fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res); 252fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 253fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Realizing the player in synchronous mode. */ 254fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res); 255fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 256fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 257fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Get interfaces */ 258ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); CheckErr(res); 259fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 260ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_VOLUME, (void*)&volItf); CheckErr(res); 261fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 26260ca9f9ef02f6e486c3338cb811f603dd7825c05Glenn Kasten res = (*player)->GetInterface(player, SL_IID_ANDROIDBUFFERQUEUESOURCE, (void*)&abqItf); 263fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 264be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 265d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi res = (*abqItf)->RegisterCallback(abqItf, AndroidBufferQueueCallback, 266d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // context is not used in the example, but can be used to track who registered 267d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi // the buffer queue callback 268d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi NULL /*pContext*/); CheckErr(res); 269fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 2701c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi res = (*abqItf)->SetCallbackEventsMask(abqItf, SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED); 2711c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi CheckErr(res); 2721c853a41d9d9886e60618a7c878ce3912f46bf3cJean-Michel Trivi 273fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Display duration */ 274fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 275fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); 276fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 277fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 278fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n"); 279fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } else { 28058432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n", 281fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi durationInMsec); 282fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 283fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 284fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Set the player volume */ 28526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi res = (*volItf)->SetVolumeLevel( volItf, 0);//-300); 286fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 287fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 288d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 289fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Play the URI */ 290fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* first cause the player to prefetch the data */ 291fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "Before set to PAUSED\n"); 292fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); 293fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "After set to PAUSED\n"); 294fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 295fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 296d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi /* Fill our cache */ 297d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi if (fread(dataCache, 1, BUFFER_SIZE * NB_BUFFERS, file) <= 0) { 298d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi fprintf(stderr, "Error filling cache, exiting\n"); 299d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi goto destroyRes; 300d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 301d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi /* Enqueue the content of our cache before starting to play, 302d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi * we don't want to starve the player */ 303d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi for (int i=0 ; i < NB_BUFFERS ; i++) { 30437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi res = (*abqItf)->Enqueue(abqItf, NULL /*pBufferContext*/, 30537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi dataCache + i*BUFFER_SIZE, BUFFER_SIZE, NULL, 0); 306d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi CheckErr(res); 307d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 308d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi 30970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi#if 0 // used to test ABQ starving where only one buffer is enqueued before playback 31070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi /* Fill our cache */ 31170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi if (fread(dataCache, 1, BUFFER_SIZE * 1, file) <= 0) { 31270c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi fprintf(stderr, "Error filling cache, exiting\n"); 31370c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi goto destroyRes; 31470c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 31570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi /* Enqueue the content of our cache before starting to play, 31670c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi * we don't want to starve the player */ 31770c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi for (int i=0 ; i < 1 ; i++) { 31870c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi res = (*abqItf)->Enqueue(abqItf, dataCache + i*BUFFER_SIZE, BUFFER_SIZE, NULL, 0); 31970c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi CheckErr(res); 32070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi } 32170c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi#endif 322fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* wait until there's data to play */ 323fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi //SLpermille fillLevel = 0; 324cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi /* 325cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 326fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLuint32 timeOutIndex = 2; 327fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0) && 328fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi !prefetchError) { 329fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi usleep(1 * 1000 * 1000); // 1s 330ad887a253969ac2017a1dbe062d0b76d505594c0Jean-Michel Trivi //(*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus); 331fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi timeOutIndex--; 332fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 333fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 334fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi if (timeOutIndex == 0 || prefetchError) { 335fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stderr, "We\'re done waiting, failed to prefetch data in time, exiting\n"); 336fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi goto destroyRes; 337cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi } 338cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi*/ 339fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 340fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Display duration again, */ 341aa2fafdac2711436e5fd8faf162d7087a515cb1cJean-Michel Trivi/* res = (*playItf)->GetDuration(playItf, &durationInMsec); 342fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 343fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 344fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "Content duration is unknown (after prefetch completed)\n"); 345fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } else { 346fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "Content duration is %lu ms (after prefetch completed)\n", durationInMsec); 347fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 348aa2fafdac2711436e5fd8faf162d7087a515cb1cJean-Michel Trivi*/ 349fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 350fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "URI example: starting to play\n"); 351fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); 352fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 353fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 354fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Wait as long as the duration of the content before stopping */ 355cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi fprintf(stdout, "Letting playback go on for %d sec\n", playTimeInSec); 356cb417262919560a715628f4317dc8a4de386f750Jean-Michel Trivi usleep(playTimeInSec /*s*/ * 1000 * 1000); 35726043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 358fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 359fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Make sure player is stopped */ 360fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "URI example: stopping playback\n"); 361fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 362fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 363fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 364be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi fprintf(stdout, "sleeping to verify playback stopped\n"); 365be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi usleep(2 /*s*/ * 1000 * 1000); 366be59fc5cfd9354d70d4b0e28bb2bca24a6ca6f22Jean-Michel Trivi 367fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel TrividestroyRes: 368fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 369fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Destroy the player */ 370fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi (*player)->Destroy(player); 371fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 372fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Destroy Output Mix object */ 373fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi (*OutputMix)->Destroy(OutputMix); 37426043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi 37526043f06b7d6cb2f93a2f2e7846a4e59da722206Jean-Michel Trivi fclose(file); 376fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 377fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 378fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi//----------------------------------------------------------------- 379fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Triviint main(int argc, char* const argv[]) 380fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi{ 381fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLresult res; 382fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLObjectItf sl; 383fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 384fa62f9f2c20b446178c05e3e92407fe5dfdbf8a1Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLAndroidBufferQueue \n", 385fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi argv[0]); 38668686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten fprintf(stdout, "and AudioPlayer with SL_DATALOCATOR_ANDROIDBUFFERQUEUE source / OutputMix " 38768686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten "sink\n"); 388fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi fprintf(stdout, "Plays a sound and stops after its reported duration\n\n"); 389fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 39027f019cc03c4a4011b2fcacadcd24b0e61b6ff58Glenn Kasten if (argc != 2) { 39127f019cc03c4a4011b2fcacadcd24b0e61b6ff58Glenn Kasten fprintf(stdout, "Usage: %s path.ts\n", argv[0]); 392fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi exit(EXIT_FAILURE); 393fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi } 394fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 395fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi SLEngineOption EngineOption[] = { 396fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 397fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 398fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 399fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 400fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 401fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 402fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 403fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi CheckErr(res); 404fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 405fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi TestPlayStream(sl, argv[1]); 406fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 407fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi /* Shutdown OpenSL ES */ 408fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi (*sl)->Destroy(sl); 409fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi 410fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi return EXIT_SUCCESS; 411fe6f6b9ed3683119721618e1aeaa8c7d6baee188Jean-Michel Trivi} 412