11b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* 21b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project 31b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * 41b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 51b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * you may not use this file except in compliance with the License. 61b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * You may obtain a copy of the License at 71b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * 81b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 91b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * 101b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 111b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 121b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * See the License for the specific language governing permissions and 141b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * limitations under the License. 151b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi */ 161b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 171b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#include <stdlib.h> 181b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#include <stdio.h> 191b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#include <unistd.h> 201b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#include <utils/threads.h> 211b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 22a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h> 231b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 241b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* tolerance in ms for this test in time difference between reported position and time since 251b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * playback was requested to start. This is reasonable for a local file. 261b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi */ 271b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#define TIME_TOLERANCE_MS 600 281b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 291b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* explicitly requesting SL_IID_VOLUME and SL_IID_PREFETCHSTATUS 301b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * on the AudioPlayer object */ 311b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#define NUM_EXPLICIT_INTERFACES_FOR_PLAYER 2 321b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 331b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* used to detect errors likely to have occured when the OpenSL ES framework fails to open 341b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond. */ 351b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#define PREFETCHEVENT_ERROR_CANDIDATE \ 361b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 371b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 381b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* to signal to the test app the end of the stream to decode has been reached */ 391b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivibool eos = false; 401b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Triviandroid::Mutex eosLock; 411b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Triviandroid::Condition eosCondition; 421b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 431b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 441b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//* Exits the application if an error is encountered */ 451b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#define CheckErr(x) ExitOnErrorFunc(x,__LINE__) 461b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 471b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid ExitOnErrorFunc( SLresult result , int line) 481b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi{ 491b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (SL_RESULT_SUCCESS != result) { 501b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line); 511b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi exit(EXIT_FAILURE); 521b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 531b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 541b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 551b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivibool prefetchError = false; 561b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 571b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 581b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid SignalEos() { 591b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi android::Mutex::Autolock autoLock(eosLock); 601b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi eos = true; 611b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi eosCondition.signal(); 621b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 631b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 641b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 651b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* PrefetchStatusItf callback for an audio player */ 661b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint32 event) 671b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi{ 681b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLpermille level = 0; 691b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLresult res = (*caller)->GetFillLevel(caller, &level); CheckErr(res); 701b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint32 status; 711b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi //fprintf(stdout, "PrefetchEventCallback: received event %u\n", event); 721b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*caller)->GetPrefetchStatus(caller, &status); CheckErr(res); 731b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) 741b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 751b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Error while prefetching data, exiting\n"); 761b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi prefetchError = true; 770e24408bb4fadda368412d16e9e865afa46f8a87Glenn Kasten return; 781b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 791b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) { 801b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Buffer fill level is = %d\n", level); 811b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 821b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (event & SL_PREFETCHEVENT_STATUSCHANGE) { 831b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "PrefetchEventCallback: Prefetch Status is = %u\n", status); 841b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 851b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 861b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 871b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 881b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 891b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* PlayItf callback for playback events */ 901b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid PlayEventCallback( 911b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLPlayItf caller, 921b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi void *pContext, 931b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint32 event) 941b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi{ 951b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLmillisecond posMsec = SL_TIME_UNKNOWN; 961b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLresult res; 971b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (SL_PLAYEVENT_HEADATEND & event) { 981b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATEND reached\n"); 991b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#if 0 1001b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*caller)->GetPosition(caller, &posMsec); CheckErr(res); 1011b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "after getPosition in SL_PLAYEVENT_HEADATEND handler\n"); 1021b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (posMsec == SL_TIME_UNKNOWN) { 1031b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "Error: position is SL_TIME_UNKNOWN at SL_PLAYEVENT_HEADATEND\n"); 1041b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } else { 1051b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "position is %d at SL_PLAYEVENT_HEADATEND\n", posMsec); 1061b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 1071b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // FIXME compare position against duration 1081b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi#endif 1091b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SignalEos(); 1101b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 1111b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1121b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (SL_PLAYEVENT_HEADATNEWPOS & event) { 1131b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*caller)->GetPosition(caller, &posMsec); CheckErr(res); 1141b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS current position=%ums\n", posMsec); 1151b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 1161b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1171b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (SL_PLAYEVENT_HEADATMARKER & event) { 1181b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*caller)->GetPosition(caller, &posMsec); CheckErr(res); 1191b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER current position=%ums\n", posMsec); 1201b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 1211b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 1221b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1231b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1241b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 1251b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1261b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi/* Play some audio from a URI and regularly query the position */ 1271b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid TestGetPositionUri( SLObjectItf sl, const char* path) 1281b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi{ 1291b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLEngineItf EngineItf; 1301b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1311b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLint32 numOutputs = 0; 1321b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint32 deviceID = 0; 1331b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1341b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLresult res; 1351b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1361b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLDataSource audioSource; 1371b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLDataLocator_URI uri; 1381b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLDataFormat_MIME mime; 1391b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1401b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLDataSink audioSink; 1411b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLDataLocator_OutputMix locator_outputmix; 1421b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1431b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLObjectItf player; 1441b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLPlayItf playItf; 1451b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLVolumeItf volItf; 1461b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLPrefetchStatusItf prefetchItf; 1471b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1481b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLObjectItf OutputMix; 1491b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1501b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* variables for the duration and position tests */ 1511b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint16 counter = 0; 1521b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLmillisecond posInMsec = SL_TIME_UNKNOWN; 1531b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLmillisecond durationInMsec = SL_TIME_UNKNOWN; 1541b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1551b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLboolean required[NUM_EXPLICIT_INTERFACES_FOR_PLAYER]; 1561b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLInterfaceID iidArray[NUM_EXPLICIT_INTERFACES_FOR_PLAYER]; 1571b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1581b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Get the SL Engine Interface which is implicit */ 1591b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf); 1601b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 1611b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1621b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Initialize arrays required[] and iidArray[] */ 1631b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi for (int i=0 ; i < NUM_EXPLICIT_INTERFACES_FOR_PLAYER ; i++) { 1641b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi required[i] = SL_BOOLEAN_FALSE; 1651b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi iidArray[i] = SL_IID_NULL; 1661b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 1671b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1681b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // Set arrays required[] and iidArray[] for VOLUME and PREFETCHSTATUS interface 1691b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi required[0] = SL_BOOLEAN_TRUE; 1701b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi iidArray[0] = SL_IID_VOLUME; 1711b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi required[1] = SL_BOOLEAN_TRUE; 1721b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi iidArray[1] = SL_IID_PREFETCHSTATUS; 1731b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // Create Output Mix object to be used by player 1741b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, 1751b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi iidArray, required); CheckErr(res); 1761b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1771b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // Realizing the Output Mix object in synchronous mode. 1781b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE); 1791b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 1801b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1811b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Setup the data source structure for the URI */ 1821b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi uri.locatorType = SL_DATALOCATOR_URI; 1831b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi uri.URI = (SLchar*) path; 1841b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi mime.formatType = SL_DATAFORMAT_MIME; 1851b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi mime.mimeType = (SLchar*)NULL; 1861b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED; 1871b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1881b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi audioSource.pFormat = (void *)&mime; 1891b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi audioSource.pLocator = (void *)&uri; 1901b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1911b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Setup the data sink structure */ 1921b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; 1931b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi locator_outputmix.outputMix = OutputMix; 1941b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi audioSink.pLocator = (void *)&locator_outputmix; 1951b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi audioSink.pFormat = NULL; 1961b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 1971b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Create the audio player */ 1981b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 1991b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi NUM_EXPLICIT_INTERFACES_FOR_PLAYER, iidArray, required); CheckErr(res); 2001b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2011b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Realizing the player in synchronous mode. */ 2021b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res); 2031b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "URI example: after Realize\n"); 2041b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2051b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Get interfaces */ 2061b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf); 2071b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2081b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2091b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_VOLUME, (void*)&volItf); 2101b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2111b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2121b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf); 2131b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2141b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, &prefetchItf); 2151b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2161b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf, 2171b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); 2181b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2191b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2201b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Configure fill level updates every 5 percent */ 2211b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50); CheckErr(res); 2221b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2231b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Set up the player callback to get events during the decoding */ 2241b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetMarkerPosition(playItf, 2000); 2251b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2261b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetPositionUpdatePeriod(playItf, 500); 2271b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2281b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetCallbackEventsMask(playItf, 2291b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADATEND); 2301b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2311b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, NULL); 2321b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2331b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2341b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Set the player volume */ 2351b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*volItf)->SetVolumeLevel( volItf, -300); 2361b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 2371b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2381b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Play the URI */ 2391b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* first cause the player to prefetch the data */ 2401b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Setting the player to PAUSED to cause it to prefetch the data\n"); 2411b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); CheckErr(res); 2421b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2431b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi usleep(100 * 1000); 2441b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* wait until there's data to play */ 2451b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW; 2461b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLuint32 timeOutIndex = 100; // 10s 2471b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0) && 2481b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi !prefetchError) { 2491b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi usleep(100 * 1000); 2501b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus); 2511b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi timeOutIndex--; 2521b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2531b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2541b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (timeOutIndex == 0 || prefetchError) { 2551b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "We're done waiting, failed to prefetch data in time, exiting\n"); 2561b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi goto destroyRes; 2571b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2581b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2591b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Display duration */ 2601b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->GetDuration(playItf, &durationInMsec); CheckErr(res); 2611b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (durationInMsec == SL_TIME_UNKNOWN) { 2621b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "Error: Content duration is unknown after prefetch completed, exiting\n"); 2631b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi goto destroyRes; 2641b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } else { 2651b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec); 2661b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2671b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2681b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Setting the player to PLAYING\n"); 2691b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); CheckErr(res); 2701b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2711b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Test GetPosition every second */ 2721b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi while ((counter*1000) < durationInMsec) { 2731b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi counter++; 2741b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi usleep(1 * 1000 * 1000); //1s 2751b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->GetPosition(playItf, &posInMsec); CheckErr(res); 2761b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (posInMsec == SL_TIME_UNKNOWN) { 2771b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "Error: position is SL_TIME_UNKNOWN %ds after start, exiting\n", 2781b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi counter); 2791b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi goto destroyRes; 2801b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } else { 2811b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "position is %dms %ds after start\n", posInMsec, counter); 2821b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2831b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // this test would probably deserve to be improved by relying on drift relative to 2841b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // a clock, as the operations between two consecutive sleep() are taking time as well 2851b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi // and can add up 2861b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (((SLint32)posInMsec > (counter*1000 + TIME_TOLERANCE_MS)) || 2871b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi ((SLint32)posInMsec < (counter*1000 - TIME_TOLERANCE_MS))) { 2881b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stderr, "Error: position drifted too much, exiting\n"); 2891b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi goto destroyRes; 2901b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2911b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2921b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 2931b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Play until the end of file is reached */ 2941b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi { 2951b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi android::Mutex::Autolock autoLock(eosLock); 2961b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi while (!eos) { 2971b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi eosCondition.wait(eosLock); 2981b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 2991b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 3001b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "EOS signaled, stopping playback\n"); 3011b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); CheckErr(res); 3021b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3031b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel TrividestroyRes: 3041b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3051b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Destroy the player */ 3061b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Destroying the player\n"); 3071b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (*player)->Destroy(player); 3081b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3091b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Destroy Output Mix object */ 3101b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (*OutputMix)->Destroy(OutputMix); 3111b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 3121b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3131b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//----------------------------------------------------------------- 3141b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Triviint main(int argc, char* const argv[]) 3151b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi{ 3161b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLresult res; 3171b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLObjectItf sl; 3181b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3191b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf", argv[0]); 3201b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n"); 3211b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Plays a sound and requests position at various times\n\n"); 3221b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3231b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi if (argc == 1) { 3241b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Usage: %s path \n\t%s url\n", argv[0], argv[0]); 3251b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi fprintf(stdout, "Example: \"%s /sdcard/my.mp3\" or \"%s file:///sdcard/my.mp3\"\n", 3261b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi argv[0], argv[0]); 3271b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi exit(EXIT_FAILURE); 3281b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi } 3291b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3301b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi SLEngineOption EngineOption[] = { 3311b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi {(SLuint32) SL_ENGINEOPTION_THREADSAFE, 3321b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (SLuint32) SL_BOOLEAN_TRUE}}; 3331b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3341b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL); 3351b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 3361b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Realizing the SL Engine in synchronous mode. */ 3371b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE); 3381b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi CheckErr(res); 3391b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3401b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi TestGetPositionUri(sl, argv[1]); 3411b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3421b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi /* Shutdown OpenSL ES */ 3431b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi (*sl)->Destroy(sl); 3441b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi 3451b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi return EXIT_SUCCESS; 3461b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi} 347