blob: 61622422c915d11226e82aee02a9c73f16e245d5 [file] [log] [blame]
Hugo Hudsonb83ad732011-07-14 23:31:17 +01001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <variablespeed.h>
18
19#include <unistd.h>
20#include <stdlib.h>
21
22#include <sola_time_scaler.h>
23#include <ring_buffer.h>
24
25#include <hlogging.h>
26
27#include <vector>
28
29// ****************************************************************************
30// Constants, utility methods, structures and other miscellany used throughout
31// this file.
32
33namespace {
34
35// These variables are used to determine the size of the buffer queue used by
36// the decoder.
37// This is not the same as the large buffer used to hold the uncompressed data
38// - for that see the member variable decodeBuffer_.
39// The choice of 1152 corresponds to the number of samples per mp3 frame, so is
40// a good choice of size for a decoding buffer in the absence of other
41// information (we don't know exactly what formats we will be working with).
42const size_t kNumberOfBuffersInQueue = 4;
43const size_t kNumberOfSamplesPerBuffer = 1152;
44const size_t kBufferSizeInBytes = 2 * kNumberOfSamplesPerBuffer;
45const size_t kSampleSizeInBytes = 4;
46
Hugo Hudson0bd6ec52011-07-26 20:05:25 +010047// Keys used when extracting metadata from the decoder.
48// TODO: Remove these constants once they are part of OpenSLES_Android.h.
49const char* kKeyPcmFormatNumChannels = "AndroidPcmFormatNumChannels";
50const char* kKeyPcmFormatSamplesPerSec = "AndroidPcmFormatSamplesPerSec";
51
Hugo Hudsonb83ad732011-07-14 23:31:17 +010052// When calculating play buffer size before pushing to audio player.
53const size_t kNumberOfBytesPerInt16 = 2;
54
55// How long to sleep during the main play loop and the decoding callback loop.
56// In due course this should be replaced with the better signal and wait on
57// condition rather than busy-looping.
58const int kSleepTimeMicros = 1000;
59
60// Used in detecting errors with the OpenSL ES framework.
61const SLuint32 kPrefetchErrorCandidate =
62 SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE;
63
64// Structure used when we perform a decoding callback.
65typedef struct CallbackContext_ {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +010066 // Pointer to local storage buffers for decoded audio data.
67 int8_t* pDataBase;
68 // Pointer to the current buffer within local storage.
69 int8_t* pData;
70 // Used to read the sample rate and channels from the decoding stream during
71 // the first decoding callback.
72 SLMetadataExtractionItf decoderMetadata;
73 // The play interface used for reading duration.
74 SLPlayItf playItf;
Hugo Hudsonb83ad732011-07-14 23:31:17 +010075} CallbackContext;
76
77// Local storage for decoded audio data.
78int8_t pcmData[kNumberOfBuffersInQueue * kBufferSizeInBytes];
79
80#define CheckSLResult(message, result) \
81 CheckSLResult_Real(message, result, __LINE__)
82
83// Helper function for debugging - checks the OpenSL result for success.
84void CheckSLResult_Real(const char* message, SLresult result, int line) {
85 // This can be helpful when debugging.
86 // LOGD("sl result %d for %s", result, message);
87 if (SL_RESULT_SUCCESS != result) {
88 LOGE("slresult was %d at %s file variablespeed line %d",
89 static_cast<int>(result), message, line);
90 }
91 CHECK(SL_RESULT_SUCCESS == result);
92}
93
94} // namespace
95
96// ****************************************************************************
97// Static instance of audio engine, and methods for getting, setting and
98// deleting it.
99
100// The single global audio engine instance.
101AudioEngine* AudioEngine::audioEngine_ = NULL;
102android::Mutex publishEngineLock_;
103
104AudioEngine* AudioEngine::GetEngine() {
105 android::Mutex::Autolock autoLock(publishEngineLock_);
106 if (audioEngine_ == NULL) {
107 LOGE("you haven't initialized the audio engine");
108 CHECK(false);
109 return NULL;
110 }
111 return audioEngine_;
112}
113
114void AudioEngine::SetEngine(AudioEngine* engine) {
115 if (audioEngine_ != NULL) {
116 LOGE("you have already set the audio engine");
117 CHECK(false);
118 return;
119 }
120 audioEngine_ = engine;
121}
122
123void AudioEngine::DeleteEngine() {
124 if (audioEngine_ == NULL) {
125 LOGE("you haven't initialized the audio engine");
126 CHECK(false);
127 return;
128 }
129 delete audioEngine_;
130 audioEngine_ = NULL;
131}
132
133// ****************************************************************************
134// The callbacks from the engine require static callback functions.
135// Here are the static functions - they just delegate to instance methods on
136// the engine.
137
138static void PlayingBufferQueueCb(SLAndroidSimpleBufferQueueItf, void*) {
139 AudioEngine::GetEngine()->PlayingBufferQueueCallback();
140}
141
142static void PrefetchEventCb(SLPrefetchStatusItf caller, void*, SLuint32 event) {
143 AudioEngine::GetEngine()->PrefetchEventCallback(caller, event);
144}
145
146static void DecodingBufferQueueCb(SLAndroidSimpleBufferQueueItf queueItf,
147 void *context) {
148 AudioEngine::GetEngine()->DecodingBufferQueueCallback(queueItf, context);
149}
150
151static void DecodingEventCb(SLPlayItf caller, void*, SLuint32 event) {
152 AudioEngine::GetEngine()->DecodingEventCallback(caller, event);
153}
154
155// ****************************************************************************
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100156// Macros for making working with OpenSL easier.
157
158// #define LOG_OPENSL_API_CALL(string) LOGV(string)
159#define LOG_OPENSL_API_CALL(string) false
160
161// The regular macro: log an api call, make the api call, check the result.
162#define OpenSL(obj, method, ...) \
163{ \
164 LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")"); \
165 SLresult result = (*obj)->method(obj, __VA_ARGS__); \
166 CheckSLResult("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")", result); \
167}
168
169// Special case call for api call that has void return value, can't be checked.
170#define VoidOpenSL(obj, method) \
171{ \
172 LOG_OPENSL_API_CALL("OpenSL (void) " #method "(" #obj ")"); \
173 (*obj)->method(obj); \
174}
175
176// Special case for api call with checked result but takes no arguments.
177#define OpenSL0(obj, method) \
178{ \
179 LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ")"); \
180 SLresult result = (*obj)->method(obj); \
181 CheckSLResult("OpenSL " #method "(" #obj ")", result); \
182}
183
184// Special case for api call whose result we want to store, not check.
185// We have to encapsulate the two calls in braces, so that this expression
186// evaluates to the last expression not the first.
187#define ReturnOpenSL(obj, method, ...) \
188( \
189 LOG_OPENSL_API_CALL("OpenSL (int) " \
190 #method "(" #obj ", " #__VA_ARGS__ ")"), \
191 (*obj)->method(obj, __VA_ARGS__) \
192) \
193
194// ****************************************************************************
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100195// Static utility methods.
196
Flavio Lerdadc442b42011-08-31 15:49:53 +0100197// Set the audio stream type for the player.
198//
199// Must be called before it is realized.
200//
201// The caller must have requested the SL_IID_ANDROIDCONFIGURATION interface when
202// creating the player.
203static void setAudioStreamType(SLObjectItf audioPlayer, SLint32 audioStreamType) {
204 SLAndroidConfigurationItf playerConfig;
205 OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDCONFIGURATION, &playerConfig);
206 // The STREAM_XXX constants defined by android.media.AudioManager match the
207 // corresponding SL_ANDROID_STREAM_XXX constants defined by
208 // include/SLES/OpenSLES_AndroidConfiguration.h, so we can just pass the
209 // value across.
210 OpenSL(playerConfig, SetConfiguration, SL_ANDROID_KEY_STREAM_TYPE,
211 &audioStreamType, sizeof(audioStreamType));
212}
213
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100214// Must be called with callbackLock_ held.
215static void ReadSampleRateAndChannelCount(CallbackContext *pContext,
216 SLuint32 *sampleRateOut, SLuint32 *channelsOut) {
217 SLMetadataExtractionItf decoderMetadata = pContext->decoderMetadata;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100218 SLuint32 itemCount;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100219 OpenSL(decoderMetadata, GetItemCount, &itemCount);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100220 SLuint32 i, keySize, valueSize;
221 SLMetadataInfo *keyInfo, *value;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100222 for (i = 0; i < itemCount; ++i) {
223 keyInfo = value = NULL;
224 keySize = valueSize = 0;
225 OpenSL(decoderMetadata, GetKeySize, i, &keySize);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100226 keyInfo = static_cast<SLMetadataInfo*>(malloc(keySize));
227 if (keyInfo) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100228 OpenSL(decoderMetadata, GetKey, i, keySize, keyInfo);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100229 if (keyInfo->encoding == SL_CHARACTERENCODING_ASCII
230 || keyInfo->encoding == SL_CHARACTERENCODING_UTF8) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100231 OpenSL(decoderMetadata, GetValueSize, i, &valueSize);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100232 value = static_cast<SLMetadataInfo*>(malloc(valueSize));
233 if (value) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100234 OpenSL(decoderMetadata, GetValue, i, valueSize, value);
235 if (strcmp((char*) keyInfo->data, kKeyPcmFormatSamplesPerSec) == 0) {
236 SLuint32 sampleRate = *(reinterpret_cast<SLuint32*>(value->data));
237 LOGD("sample Rate: %d", sampleRate);
238 *sampleRateOut = sampleRate;
239 } else if (strcmp((char*) keyInfo->data, kKeyPcmFormatNumChannels) == 0) {
240 SLuint32 channels = *(reinterpret_cast<SLuint32*>(value->data));
241 LOGD("channels: %d", channels);
242 *channelsOut = channels;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100243 }
244 free(value);
245 }
246 }
247 free(keyInfo);
248 }
249 }
250}
251
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100252// Must be called with callbackLock_ held.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100253static void RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100254 SLAndroidSimpleBufferQueueItf decoderQueue, CallbackContext* context) {
255 // Register a callback on the decoder queue, so that we will be called
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100256 // throughout the decoding process (and can then extract the decoded audio
257 // for the next bit of the pipeline).
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100258 OpenSL(decoderQueue, RegisterCallback, DecodingBufferQueueCb, context);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100259
260 // Enqueue buffers to map the region of memory allocated to store the
261 // decoded data.
262 for (size_t i = 0; i < kNumberOfBuffersInQueue; i++) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100263 OpenSL(decoderQueue, Enqueue, context->pData, kBufferSizeInBytes);
Hugo Hudson9730f152011-07-25 17:04:42 +0100264 context->pData += kBufferSizeInBytes;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100265 }
Hugo Hudson9730f152011-07-25 17:04:42 +0100266 context->pData = context->pDataBase;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100267}
268
269// ****************************************************************************
270// Constructor and Destructor.
271
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100272AudioEngine::AudioEngine(size_t targetFrames, float windowDuration,
273 float windowOverlapDuration, size_t maxPlayBufferCount, float initialRate,
Flavio Lerdadc442b42011-08-31 15:49:53 +0100274 size_t decodeInitialSize, size_t decodeMaxSize, size_t startPositionMillis,
275 int audioStreamType)
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100276 : decodeBuffer_(decodeInitialSize, decodeMaxSize),
277 playingBuffers_(), freeBuffers_(), timeScaler_(NULL),
278 floatBuffer_(NULL), injectBuffer_(NULL),
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100279 mSampleRate(0), mChannels(0),
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100280 targetFrames_(targetFrames),
281 windowDuration_(windowDuration),
282 windowOverlapDuration_(windowOverlapDuration),
283 maxPlayBufferCount_(maxPlayBufferCount), initialRate_(initialRate),
284 startPositionMillis_(startPositionMillis),
Flavio Lerdadc442b42011-08-31 15:49:53 +0100285 audioStreamType_(audioStreamType),
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100286 totalDurationMs_(0), decoderCurrentPosition_(0), startRequested_(false),
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100287 stopRequested_(false), finishedDecoding_(false) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100288}
289
290AudioEngine::~AudioEngine() {
291 // destroy the time scaler
292 if (timeScaler_ != NULL) {
293 delete timeScaler_;
294 timeScaler_ = NULL;
295 }
296
297 // delete all outstanding playing and free buffers
298 android::Mutex::Autolock autoLock(playBufferLock_);
299 while (playingBuffers_.size() > 0) {
300 delete[] playingBuffers_.front();
301 playingBuffers_.pop();
302 }
303 while (freeBuffers_.size() > 0) {
304 delete[] freeBuffers_.top();
305 freeBuffers_.pop();
306 }
307
308 delete[] floatBuffer_;
309 floatBuffer_ = NULL;
310 delete[] injectBuffer_;
311 injectBuffer_ = NULL;
312}
313
314// ****************************************************************************
315// Regular AudioEngine class methods.
316
317void AudioEngine::SetVariableSpeed(float speed) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100318 // TODO: Mutex for shared time scaler accesses.
Hugo Hudson64f5ba62011-08-10 15:57:28 +0100319 if (HasSampleRateAndChannels()) {
320 GetTimeScaler()->set_speed(speed);
321 } else {
322 // This is being called at a point where we have not yet processed enough
323 // data to determine the sample rate and number of channels.
324 // Ignore the call. See http://b/5140693.
325 LOGD("set varaible speed called, sample rate and channels not ready yet");
326 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100327}
328
329void AudioEngine::RequestStart() {
330 android::Mutex::Autolock autoLock(lock_);
331 startRequested_ = true;
332}
333
334void AudioEngine::ClearRequestStart() {
335 android::Mutex::Autolock autoLock(lock_);
336 startRequested_ = false;
337}
338
339bool AudioEngine::GetWasStartRequested() {
340 android::Mutex::Autolock autoLock(lock_);
341 return startRequested_;
342}
343
344void AudioEngine::RequestStop() {
345 android::Mutex::Autolock autoLock(lock_);
346 stopRequested_ = true;
347}
348
349int AudioEngine::GetCurrentPosition() {
350 android::Mutex::Autolock autoLock(decodeBufferLock_);
351 double result = decodeBuffer_.GetTotalAdvancedCount();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100352 // TODO: This is horrible, but should be removed soon once the outstanding
353 // issue with get current position on decoder is fixed.
354 android::Mutex::Autolock autoLock2(callbackLock_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100355 return static_cast<int>(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100356 (result * 1000) / mSampleRate / mChannels + startPositionMillis_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100357}
358
359int AudioEngine::GetTotalDuration() {
360 android::Mutex::Autolock autoLock(lock_);
361 return static_cast<int>(totalDurationMs_);
362}
363
364video_editing::SolaTimeScaler* AudioEngine::GetTimeScaler() {
365 if (timeScaler_ == NULL) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100366 CHECK(HasSampleRateAndChannels());
367 android::Mutex::Autolock autoLock(callbackLock_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100368 timeScaler_ = new video_editing::SolaTimeScaler();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100369 timeScaler_->Init(mSampleRate, mChannels, initialRate_, windowDuration_,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100370 windowOverlapDuration_);
371 }
372 return timeScaler_;
373}
374
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100375bool AudioEngine::EnqueueNextBufferOfAudio(
376 SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100377 size_t channels;
378 {
379 android::Mutex::Autolock autoLock(callbackLock_);
380 channels = mChannels;
381 }
382 size_t frameSizeInBytes = kSampleSizeInBytes * channels;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100383 size_t frameCount = 0;
384 while (frameCount < targetFrames_) {
385 size_t framesLeft = targetFrames_ - frameCount;
386 // If there is data already in the time scaler, retrieve it.
387 if (GetTimeScaler()->available() > 0) {
388 size_t retrieveCount = min(GetTimeScaler()->available(), framesLeft);
389 int count = GetTimeScaler()->RetrieveSamples(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100390 floatBuffer_ + frameCount * channels, retrieveCount);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100391 if (count <= 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100392 LOGD("error: count was %d", count);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100393 break;
394 }
395 frameCount += count;
396 continue;
397 }
398 // If there is no data in the time scaler, then feed some into it.
399 android::Mutex::Autolock autoLock(decodeBufferLock_);
400 size_t framesInDecodeBuffer =
401 decodeBuffer_.GetSizeInBytes() / frameSizeInBytes;
402 size_t framesScalerCanHandle = GetTimeScaler()->input_limit();
403 size_t framesToInject = min(framesInDecodeBuffer,
404 min(targetFrames_, framesScalerCanHandle));
405 if (framesToInject <= 0) {
406 // No more frames left to inject.
407 break;
408 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100409 for (size_t i = 0; i < framesToInject * channels; ++i) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100410 injectBuffer_[i] = decodeBuffer_.GetAtIndex(i);
411 }
412 int count = GetTimeScaler()->InjectSamples(injectBuffer_, framesToInject);
413 if (count <= 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100414 LOGD("error: count was %d", count);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100415 break;
416 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100417 decodeBuffer_.AdvanceHeadPointerShorts(count * channels);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100418 }
419 if (frameCount <= 0) {
420 // We must have finished playback.
421 if (GetEndOfDecoderReached()) {
422 // If we've finished decoding, clear the buffer - so we will terminate.
423 ClearDecodeBuffer();
424 }
425 return false;
426 }
427
428 // Get a free playing buffer.
429 int16* playBuffer;
430 {
431 android::Mutex::Autolock autoLock(playBufferLock_);
432 if (freeBuffers_.size() > 0) {
433 // If we have a free buffer, recycle it.
434 playBuffer = freeBuffers_.top();
435 freeBuffers_.pop();
436 } else {
437 // Otherwise allocate a new one.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100438 playBuffer = new int16[targetFrames_ * channels];
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100439 }
440 }
441
442 // Try to play the buffer.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100443 for (size_t i = 0; i < frameCount * channels; ++i) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100444 playBuffer[i] = floatBuffer_[i];
445 }
446 size_t sizeOfPlayBufferInBytes =
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100447 frameCount * channels * kNumberOfBytesPerInt16;
448 SLresult result = ReturnOpenSL(audioPlayerQueue, Enqueue, playBuffer,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100449 sizeOfPlayBufferInBytes);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100450 if (result == SL_RESULT_SUCCESS) {
451 android::Mutex::Autolock autoLock(playBufferLock_);
452 playingBuffers_.push(playBuffer);
453 } else {
454 LOGE("could not enqueue audio buffer");
455 delete[] playBuffer;
456 }
457
458 return (result == SL_RESULT_SUCCESS);
459}
460
461bool AudioEngine::GetEndOfDecoderReached() {
462 android::Mutex::Autolock autoLock(lock_);
463 return finishedDecoding_;
464}
465
466void AudioEngine::SetEndOfDecoderReached() {
467 android::Mutex::Autolock autoLock(lock_);
468 finishedDecoding_ = true;
469}
470
471bool AudioEngine::PlayFileDescriptor(int fd, int64 offset, int64 length) {
472 SLDataLocator_AndroidFD loc_fd = {
473 SL_DATALOCATOR_ANDROIDFD, fd, offset, length };
474 SLDataFormat_MIME format_mime = {
475 SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
476 SLDataSource audioSrc = { &loc_fd, &format_mime };
477 return PlayFromThisSource(audioSrc);
478}
479
480bool AudioEngine::PlayUri(const char* uri) {
481 // Source of audio data for the decoding
482 SLDataLocator_URI decUri = { SL_DATALOCATOR_URI,
483 const_cast<SLchar*>(reinterpret_cast<const SLchar*>(uri)) };
484 SLDataFormat_MIME decMime = {
485 SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
486 SLDataSource decSource = { &decUri, &decMime };
487 return PlayFromThisSource(decSource);
488}
489
490bool AudioEngine::IsDecodeBufferEmpty() {
491 android::Mutex::Autolock autoLock(decodeBufferLock_);
492 return decodeBuffer_.GetSizeInBytes() <= 0;
493}
494
495void AudioEngine::ClearDecodeBuffer() {
496 android::Mutex::Autolock autoLock(decodeBufferLock_);
497 decodeBuffer_.Clear();
498}
499
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100500static size_t ReadDuration(SLPlayItf playItf) {
501 SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
502 OpenSL(playItf, GetDuration, &durationInMsec);
503 if (durationInMsec == SL_TIME_UNKNOWN) {
504 LOGE("can't get duration");
505 return 0;
506 }
507 LOGD("duration: %d", static_cast<int>(durationInMsec));
508 return durationInMsec;
509}
510
511static size_t ReadPosition(SLPlayItf playItf) {
512 SLmillisecond positionInMsec = SL_TIME_UNKNOWN;
513 OpenSL(playItf, GetPosition, &positionInMsec);
514 if (positionInMsec == SL_TIME_UNKNOWN) {
515 LOGE("can't get position");
516 return 0;
517 }
518 LOGW("decoder position: %d", static_cast<int>(positionInMsec));
519 return positionInMsec;
520}
521
Hugo Hudson9730f152011-07-25 17:04:42 +0100522static void CreateAndRealizeEngine(SLObjectItf &engine,
523 SLEngineItf &engineInterface) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100524 SLEngineOption EngineOption[] = { {
525 SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE } };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100526 SLresult result = slCreateEngine(&engine, 1, EngineOption, 0, NULL, NULL);
527 CheckSLResult("create engine", result);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100528 OpenSL(engine, Realize, SL_BOOLEAN_FALSE);
529 OpenSL(engine, GetInterface, SL_IID_ENGINE, &engineInterface);
Hugo Hudson9730f152011-07-25 17:04:42 +0100530}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100531
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100532SLuint32 AudioEngine::GetSLSampleRate() {
533 android::Mutex::Autolock autoLock(callbackLock_);
534 return mSampleRate * 1000;
Hugo Hudson9730f152011-07-25 17:04:42 +0100535}
536
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100537SLuint32 AudioEngine::GetSLChannels() {
538 android::Mutex::Autolock autoLock(callbackLock_);
539 switch (mChannels) {
Hugo Hudson9730f152011-07-25 17:04:42 +0100540 case 2:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100541 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
Hugo Hudson9730f152011-07-25 17:04:42 +0100542 case 1:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100543 return SL_SPEAKER_FRONT_CENTER;
Hugo Hudson9730f152011-07-25 17:04:42 +0100544 default:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100545 LOGE("unknown channels %d, using 2", mChannels);
546 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
Hugo Hudson9730f152011-07-25 17:04:42 +0100547 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100548}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100549
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100550SLuint32 AudioEngine::GetChannelCount() {
551 android::Mutex::Autolock autoLock(callbackLock_);
552 return mChannels;
553}
554
555static void CreateAndRealizeAudioPlayer(SLuint32 slSampleRate,
Flavio Lerdadc442b42011-08-31 15:49:53 +0100556 size_t channelCount, SLuint32 slChannels, SLint32 audioStreamType, SLObjectItf &outputMix,
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100557 SLObjectItf &audioPlayer, SLEngineItf &engineInterface) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100558 // Define the source and sink for the audio player: comes from a buffer queue
559 // and goes to the output mix.
560 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
561 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100562 SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channelCount, slSampleRate,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100563 SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100564 slChannels, SL_BYTEORDER_LITTLEENDIAN};
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100565 SLDataSource playingSrc = {&loc_bufq, &format_pcm};
566 SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMix};
567 SLDataSink audioSnk = {&loc_outmix, NULL};
568
569 // Create the audio player, which will play from the buffer queue and send to
570 // the output mix.
Flavio Lerdadc442b42011-08-31 15:49:53 +0100571 const size_t playerInterfaceCount = 2;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100572 const SLInterfaceID iids[playerInterfaceCount] = {
Flavio Lerdadc442b42011-08-31 15:49:53 +0100573 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100574 const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE };
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100575 OpenSL(engineInterface, CreateAudioPlayer, &audioPlayer, &playingSrc,
576 &audioSnk, playerInterfaceCount, iids, reqs);
Flavio Lerdadc442b42011-08-31 15:49:53 +0100577 setAudioStreamType(audioPlayer, audioStreamType);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100578 OpenSL(audioPlayer, Realize, SL_BOOLEAN_FALSE);
Hugo Hudson9730f152011-07-25 17:04:42 +0100579}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100580
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100581bool AudioEngine::HasSampleRateAndChannels() {
582 android::Mutex::Autolock autoLock(callbackLock_);
583 return mChannels != 0 && mSampleRate != 0;
Hugo Hudson9730f152011-07-25 17:04:42 +0100584}
585
586bool AudioEngine::PlayFromThisSource(const SLDataSource& audioSrc) {
587 ClearDecodeBuffer();
588
Hugo Hudson9730f152011-07-25 17:04:42 +0100589 SLObjectItf engine;
590 SLEngineItf engineInterface;
591 CreateAndRealizeEngine(engine, engineInterface);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100592
593 // Define the source and sink for the decoding player: comes from the source
594 // this method was called with, is sent to another buffer queue.
595 SLDataLocator_AndroidSimpleBufferQueue decBuffQueue;
596 decBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
597 decBuffQueue.numBuffers = kNumberOfBuffersInQueue;
598 // A valid value seems required here but is currently ignored.
Hugo Hudson9730f152011-07-25 17:04:42 +0100599 SLDataFormat_PCM pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100600 SL_PCMSAMPLEFORMAT_FIXED_16, 16,
601 SL_SPEAKER_FRONT_LEFT, SL_BYTEORDER_LITTLEENDIAN};
602 SLDataSink decDest = { &decBuffQueue, &pcm };
603
604 // Create the decoder with the given source and sink.
Flavio Lerdadc442b42011-08-31 15:49:53 +0100605 const size_t decoderInterfaceCount = 5;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100606 SLObjectItf decoder;
607 const SLInterfaceID decodePlayerInterfaces[decoderInterfaceCount] = {
608 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PREFETCHSTATUS, SL_IID_SEEK,
Flavio Lerdadc442b42011-08-31 15:49:53 +0100609 SL_IID_METADATAEXTRACTION, SL_IID_ANDROIDCONFIGURATION };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100610 const SLboolean decodePlayerRequired[decoderInterfaceCount] = {
611 SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
612 SLDataSource sourceCopy(audioSrc);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100613 OpenSL(engineInterface, CreateAudioPlayer, &decoder, &sourceCopy, &decDest,
614 decoderInterfaceCount, decodePlayerInterfaces, decodePlayerRequired);
Flavio Lerdadc442b42011-08-31 15:49:53 +0100615 // Not sure if this is necessary, but just in case.
616 setAudioStreamType(decoder, audioStreamType_);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100617 OpenSL(decoder, Realize, SL_BOOLEAN_FALSE);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100618
619 // Get the play interface from the decoder, and register event callbacks.
620 // Get the buffer queue, prefetch and seek interfaces.
Hugo Hudson9730f152011-07-25 17:04:42 +0100621 SLPlayItf decoderPlay = NULL;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100622 SLAndroidSimpleBufferQueueItf decoderQueue = NULL;
623 SLPrefetchStatusItf decoderPrefetch = NULL;
624 SLSeekItf decoderSeek = NULL;
625 SLMetadataExtractionItf decoderMetadata = NULL;
626 OpenSL(decoder, GetInterface, SL_IID_PLAY, &decoderPlay);
627 OpenSL(decoderPlay, SetCallbackEventsMask, SL_PLAYEVENT_HEADATEND);
628 OpenSL(decoderPlay, RegisterCallback, DecodingEventCb, NULL);
629 OpenSL(decoder, GetInterface, SL_IID_PREFETCHSTATUS, &decoderPrefetch);
630 OpenSL(decoder, GetInterface, SL_IID_SEEK, &decoderSeek);
631 OpenSL(decoder, GetInterface, SL_IID_METADATAEXTRACTION, &decoderMetadata);
632 OpenSL(decoder, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
633 &decoderQueue);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100634
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100635 // Initialize the callback structure, used during the decoding.
Hugo Hudson9730f152011-07-25 17:04:42 +0100636 CallbackContext callbackContext;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100637 {
638 android::Mutex::Autolock autoLock(callbackLock_);
639 callbackContext.pDataBase = pcmData;
640 callbackContext.pData = pcmData;
641 callbackContext.decoderMetadata = decoderMetadata;
642 callbackContext.playItf = decoderPlay;
643 RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
644 decoderQueue, &callbackContext);
645 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100646
647 // Initialize the callback for prefetch errors, if we can't open the
648 // resource to decode.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100649 OpenSL(decoderPrefetch, SetCallbackEventsMask, kPrefetchErrorCandidate);
650 OpenSL(decoderPrefetch, RegisterCallback, PrefetchEventCb, &decoderPrefetch);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100651
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100652 // Seek to the start position.
653 OpenSL(decoderSeek, SetPosition, startPositionMillis_, SL_SEEKMODE_ACCURATE);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100654
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100655 // Start decoding immediately.
656 OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100657
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100658 // These variables hold the audio player and its output.
659 // They will only be constructed once the decoder has invoked the callback,
660 // and given us the correct sample rate, number of channels and duration.
Hugo Hudson9730f152011-07-25 17:04:42 +0100661 SLObjectItf outputMix = NULL;
662 SLObjectItf audioPlayer = NULL;
663 SLPlayItf audioPlayerPlay = NULL;
664 SLAndroidSimpleBufferQueueItf audioPlayerQueue = NULL;
665
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100666 // The main loop - until we're told to stop: if there is audio data coming
667 // out of the decoder, feed it through the time scaler.
668 // As it comes out of the time scaler, feed it into the audio player.
669 while (!Finished()) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100670 if (GetWasStartRequested() && HasSampleRateAndChannels()) {
671 // Build the audio player.
672 // TODO: What happens if I maliciously call start lots of times?
673 floatBuffer_ = new float[targetFrames_ * mChannels];
674 injectBuffer_ = new float[targetFrames_ * mChannels];
675 OpenSL(engineInterface, CreateOutputMix, &outputMix, 0, NULL, NULL);
676 OpenSL(outputMix, Realize, SL_BOOLEAN_FALSE);
677 CreateAndRealizeAudioPlayer(GetSLSampleRate(), GetChannelCount(),
Flavio Lerdadc442b42011-08-31 15:49:53 +0100678 GetSLChannels(), audioStreamType_, outputMix, audioPlayer,
679 engineInterface);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100680 OpenSL(audioPlayer, GetInterface, SL_IID_PLAY, &audioPlayerPlay);
681 OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
682 &audioPlayerQueue);
683 OpenSL(audioPlayerQueue, RegisterCallback, PlayingBufferQueueCb, NULL);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100684 ClearRequestStart();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100685 OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100686 }
687 EnqueueMoreAudioIfNecessary(audioPlayerQueue);
688 usleep(kSleepTimeMicros);
689 }
690
Hugo Hudson9730f152011-07-25 17:04:42 +0100691 // Delete the audio player and output mix, iff they have been created.
692 if (audioPlayer != NULL) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100693 OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
694 OpenSL0(audioPlayerQueue, Clear);
695 OpenSL(audioPlayerQueue, RegisterCallback, NULL, NULL);
696 VoidOpenSL(audioPlayer, AbortAsyncOperation);
697 VoidOpenSL(audioPlayer, Destroy);
698 VoidOpenSL(outputMix, Destroy);
Hugo Hudson9730f152011-07-25 17:04:42 +0100699 audioPlayer = NULL;
700 audioPlayerPlay = NULL;
701 audioPlayerQueue = NULL;
702 outputMix = NULL;
703 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100704
705 // Delete the decoder.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100706 OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
707 OpenSL(decoderPrefetch, RegisterCallback, NULL, NULL);
Hugo Hudson9730f152011-07-25 17:04:42 +0100708 // This is returning slresult 13 if I do no playback.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100709 // Repro is to comment out all before this line, and all after enqueueing
710 // my buffers.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100711 // OpenSL0(decoderQueue, Clear);
712 OpenSL(decoderQueue, RegisterCallback, NULL, NULL);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100713 decoderSeek = NULL;
714 decoderPrefetch = NULL;
715 decoderQueue = NULL;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100716 OpenSL(decoderPlay, RegisterCallback, NULL, NULL);
717 VoidOpenSL(decoder, AbortAsyncOperation);
718 VoidOpenSL(decoder, Destroy);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100719 decoderPlay = NULL;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100720
Hugo Hudson9730f152011-07-25 17:04:42 +0100721 // Delete the engine.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100722 VoidOpenSL(engine, Destroy);
Hugo Hudson9730f152011-07-25 17:04:42 +0100723 engineInterface = NULL;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100724
725 return true;
726}
727
728bool AudioEngine::Finished() {
729 if (GetWasStopRequested()) {
730 return true;
731 }
732 android::Mutex::Autolock autoLock(playBufferLock_);
733 return playingBuffers_.size() <= 0 &&
734 IsDecodeBufferEmpty() &&
735 GetEndOfDecoderReached();
736}
737
738bool AudioEngine::GetWasStopRequested() {
739 android::Mutex::Autolock autoLock(lock_);
740 return stopRequested_;
741}
742
743bool AudioEngine::GetHasReachedPlayingBuffersLimit() {
744 android::Mutex::Autolock autoLock(playBufferLock_);
745 return playingBuffers_.size() >= maxPlayBufferCount_;
746}
747
748void AudioEngine::EnqueueMoreAudioIfNecessary(
749 SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
750 bool keepEnqueueing = true;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100751 while (audioPlayerQueue != NULL &&
752 !GetWasStopRequested() &&
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100753 !IsDecodeBufferEmpty() &&
754 !GetHasReachedPlayingBuffersLimit() &&
755 keepEnqueueing) {
756 keepEnqueueing = EnqueueNextBufferOfAudio(audioPlayerQueue);
757 }
758}
759
760bool AudioEngine::DecodeBufferTooFull() {
761 android::Mutex::Autolock autoLock(decodeBufferLock_);
762 return decodeBuffer_.IsTooLarge();
763}
764
765// ****************************************************************************
766// Code for handling the static callbacks.
767
768void AudioEngine::PlayingBufferQueueCallback() {
769 // The head playing buffer is done, move it to the free list.
770 android::Mutex::Autolock autoLock(playBufferLock_);
771 if (playingBuffers_.size() > 0) {
772 freeBuffers_.push(playingBuffers_.front());
773 playingBuffers_.pop();
774 }
775}
776
777void AudioEngine::PrefetchEventCallback(
778 SLPrefetchStatusItf caller, SLuint32 event) {
779 // If there was a problem during decoding, then signal the end.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100780 SLpermille level = 0;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100781 SLuint32 status;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100782 OpenSL(caller, GetFillLevel, &level);
783 OpenSL(caller, GetPrefetchStatus, &status);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100784 if ((kPrefetchErrorCandidate == (event & kPrefetchErrorCandidate)) &&
785 (level == 0) &&
786 (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100787 LOGI("prefetcheventcallback error while prefetching data");
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100788 SetEndOfDecoderReached();
789 }
790 if (SL_PREFETCHSTATUS_SUFFICIENTDATA == event) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100791 // android::Mutex::Autolock autoLock(prefetchLock_);
792 // prefetchCondition_.broadcast();
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100793 }
794}
795
796void AudioEngine::DecodingBufferQueueCallback(
797 SLAndroidSimpleBufferQueueItf queueItf, void *context) {
798 if (GetWasStopRequested()) {
799 return;
800 }
801
802 CallbackContext *pCntxt;
803 {
804 android::Mutex::Autolock autoLock(callbackLock_);
805 pCntxt = reinterpret_cast<CallbackContext*>(context);
806 }
807 {
808 android::Mutex::Autolock autoLock(decodeBufferLock_);
Hugo Hudsond2772c42011-08-27 01:21:54 +0100809 decodeBuffer_.AddData(pCntxt->pData, kBufferSizeInBytes);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100810 }
811
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100812 if (!HasSampleRateAndChannels()) {
813 android::Mutex::Autolock autoLock(callbackLock_);
814 ReadSampleRateAndChannelCount(pCntxt, &mSampleRate, &mChannels);
815 }
816
817 {
818 android::Mutex::Autolock autoLock(lock_);
819 if (totalDurationMs_ == 0) {
820 totalDurationMs_ = ReadDuration(pCntxt->playItf);
821 }
822 // TODO: This isn't working, it always reports zero.
823 // ReadPosition(pCntxt->playItf);
824 }
Hugo Hudson9730f152011-07-25 17:04:42 +0100825
Hugo Hudsond2772c42011-08-27 01:21:54 +0100826 OpenSL(queueItf, Enqueue, pCntxt->pData, kBufferSizeInBytes);
827
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100828 // Increase data pointer by buffer size
829 pCntxt->pData += kBufferSizeInBytes;
830 if (pCntxt->pData >= pCntxt->pDataBase +
831 (kNumberOfBuffersInQueue * kBufferSizeInBytes)) {
832 pCntxt->pData = pCntxt->pDataBase;
833 }
834
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100835 // If we get too much data into the decoder,
836 // sleep until the playback catches up.
837 while (!GetWasStopRequested() && DecodeBufferTooFull()) {
838 usleep(kSleepTimeMicros);
839 }
840}
841
842void AudioEngine::DecodingEventCallback(SLPlayItf, SLuint32 event) {
843 if (SL_PLAYEVENT_HEADATEND & event) {
844 SetEndOfDecoderReached();
845 }
846}