blob: b5d90671b1e57046857a864664059f8780366675 [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
Flavio Lerdae8638162011-09-02 16:40:13 +010029#include <sys/system_properties.h>
30
Hugo Hudsonb83ad732011-07-14 23:31:17 +010031// ****************************************************************************
32// Constants, utility methods, structures and other miscellany used throughout
33// this file.
34
35namespace {
36
37// These variables are used to determine the size of the buffer queue used by
38// the decoder.
39// This is not the same as the large buffer used to hold the uncompressed data
40// - for that see the member variable decodeBuffer_.
41// The choice of 1152 corresponds to the number of samples per mp3 frame, so is
42// a good choice of size for a decoding buffer in the absence of other
43// information (we don't know exactly what formats we will be working with).
44const size_t kNumberOfBuffersInQueue = 4;
45const size_t kNumberOfSamplesPerBuffer = 1152;
46const size_t kBufferSizeInBytes = 2 * kNumberOfSamplesPerBuffer;
47const size_t kSampleSizeInBytes = 4;
48
49// When calculating play buffer size before pushing to audio player.
50const size_t kNumberOfBytesPerInt16 = 2;
51
52// How long to sleep during the main play loop and the decoding callback loop.
53// In due course this should be replaced with the better signal and wait on
54// condition rather than busy-looping.
55const int kSleepTimeMicros = 1000;
56
57// Used in detecting errors with the OpenSL ES framework.
58const SLuint32 kPrefetchErrorCandidate =
59 SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE;
60
61// Structure used when we perform a decoding callback.
62typedef struct CallbackContext_ {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +010063 // Pointer to local storage buffers for decoded audio data.
64 int8_t* pDataBase;
65 // Pointer to the current buffer within local storage.
66 int8_t* pData;
67 // Used to read the sample rate and channels from the decoding stream during
68 // the first decoding callback.
69 SLMetadataExtractionItf decoderMetadata;
70 // The play interface used for reading duration.
71 SLPlayItf playItf;
Hugo Hudsonb83ad732011-07-14 23:31:17 +010072} CallbackContext;
73
74// Local storage for decoded audio data.
75int8_t pcmData[kNumberOfBuffersInQueue * kBufferSizeInBytes];
76
77#define CheckSLResult(message, result) \
78 CheckSLResult_Real(message, result, __LINE__)
79
80// Helper function for debugging - checks the OpenSL result for success.
81void CheckSLResult_Real(const char* message, SLresult result, int line) {
82 // This can be helpful when debugging.
83 // LOGD("sl result %d for %s", result, message);
84 if (SL_RESULT_SUCCESS != result) {
85 LOGE("slresult was %d at %s file variablespeed line %d",
86 static_cast<int>(result), message, line);
87 }
88 CHECK(SL_RESULT_SUCCESS == result);
89}
90
Flavio Lerdae8638162011-09-02 16:40:13 +010091// Whether logging should be enabled. Only used if LOG_OPENSL_API_CALL is
92// defined to use it.
93bool gLogEnabled = false;
94// The property to set in order to enable logging.
95const char *const kLogTagVariableSpeed = "log.tag.VariableSpeed";
96
97bool ShouldLog() {
98 char buffer[PROP_VALUE_MAX];
99 __system_property_get(kLogTagVariableSpeed, buffer);
100 return strlen(buffer) > 0;
101}
102
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100103} // namespace
104
105// ****************************************************************************
106// Static instance of audio engine, and methods for getting, setting and
107// deleting it.
108
109// The single global audio engine instance.
110AudioEngine* AudioEngine::audioEngine_ = NULL;
111android::Mutex publishEngineLock_;
112
113AudioEngine* AudioEngine::GetEngine() {
114 android::Mutex::Autolock autoLock(publishEngineLock_);
115 if (audioEngine_ == NULL) {
116 LOGE("you haven't initialized the audio engine");
117 CHECK(false);
118 return NULL;
119 }
120 return audioEngine_;
121}
122
123void AudioEngine::SetEngine(AudioEngine* engine) {
124 if (audioEngine_ != NULL) {
125 LOGE("you have already set the audio engine");
126 CHECK(false);
127 return;
128 }
129 audioEngine_ = engine;
130}
131
132void AudioEngine::DeleteEngine() {
133 if (audioEngine_ == NULL) {
134 LOGE("you haven't initialized the audio engine");
135 CHECK(false);
136 return;
137 }
138 delete audioEngine_;
139 audioEngine_ = NULL;
140}
141
142// ****************************************************************************
143// The callbacks from the engine require static callback functions.
144// Here are the static functions - they just delegate to instance methods on
145// the engine.
146
147static void PlayingBufferQueueCb(SLAndroidSimpleBufferQueueItf, void*) {
148 AudioEngine::GetEngine()->PlayingBufferQueueCallback();
149}
150
151static void PrefetchEventCb(SLPrefetchStatusItf caller, void*, SLuint32 event) {
152 AudioEngine::GetEngine()->PrefetchEventCallback(caller, event);
153}
154
155static void DecodingBufferQueueCb(SLAndroidSimpleBufferQueueItf queueItf,
156 void *context) {
157 AudioEngine::GetEngine()->DecodingBufferQueueCallback(queueItf, context);
158}
159
160static void DecodingEventCb(SLPlayItf caller, void*, SLuint32 event) {
161 AudioEngine::GetEngine()->DecodingEventCallback(caller, event);
162}
163
164// ****************************************************************************
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100165// Macros for making working with OpenSL easier.
166
Flavio Lerdae8638162011-09-02 16:40:13 +0100167// Log based on the value of a property.
168#define LOG_OPENSL_API_CALL(string) (gLogEnabled && LOGV(string))
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100169
170// The regular macro: log an api call, make the api call, check the result.
171#define OpenSL(obj, method, ...) \
172{ \
173 LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")"); \
174 SLresult result = (*obj)->method(obj, __VA_ARGS__); \
175 CheckSLResult("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")", result); \
176}
177
178// Special case call for api call that has void return value, can't be checked.
179#define VoidOpenSL(obj, method) \
180{ \
181 LOG_OPENSL_API_CALL("OpenSL (void) " #method "(" #obj ")"); \
182 (*obj)->method(obj); \
183}
184
185// Special case for api call with checked result but takes no arguments.
186#define OpenSL0(obj, method) \
187{ \
188 LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ")"); \
189 SLresult result = (*obj)->method(obj); \
190 CheckSLResult("OpenSL " #method "(" #obj ")", result); \
191}
192
193// Special case for api call whose result we want to store, not check.
194// We have to encapsulate the two calls in braces, so that this expression
195// evaluates to the last expression not the first.
196#define ReturnOpenSL(obj, method, ...) \
197( \
198 LOG_OPENSL_API_CALL("OpenSL (int) " \
199 #method "(" #obj ", " #__VA_ARGS__ ")"), \
200 (*obj)->method(obj, __VA_ARGS__) \
201) \
202
203// ****************************************************************************
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100204// Static utility methods.
205
Flavio Lerdadc442b42011-08-31 15:49:53 +0100206// Set the audio stream type for the player.
207//
208// Must be called before it is realized.
209//
210// The caller must have requested the SL_IID_ANDROIDCONFIGURATION interface when
211// creating the player.
212static void setAudioStreamType(SLObjectItf audioPlayer, SLint32 audioStreamType) {
213 SLAndroidConfigurationItf playerConfig;
214 OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDCONFIGURATION, &playerConfig);
215 // The STREAM_XXX constants defined by android.media.AudioManager match the
216 // corresponding SL_ANDROID_STREAM_XXX constants defined by
217 // include/SLES/OpenSLES_AndroidConfiguration.h, so we can just pass the
218 // value across.
219 OpenSL(playerConfig, SetConfiguration, SL_ANDROID_KEY_STREAM_TYPE,
220 &audioStreamType, sizeof(audioStreamType));
221}
222
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100223// Must be called with callbackLock_ held.
224static void ReadSampleRateAndChannelCount(CallbackContext *pContext,
225 SLuint32 *sampleRateOut, SLuint32 *channelsOut) {
226 SLMetadataExtractionItf decoderMetadata = pContext->decoderMetadata;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100227 SLuint32 itemCount;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100228 OpenSL(decoderMetadata, GetItemCount, &itemCount);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100229 SLuint32 i, keySize, valueSize;
230 SLMetadataInfo *keyInfo, *value;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100231 for (i = 0; i < itemCount; ++i) {
232 keyInfo = value = NULL;
233 keySize = valueSize = 0;
234 OpenSL(decoderMetadata, GetKeySize, i, &keySize);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100235 keyInfo = static_cast<SLMetadataInfo*>(malloc(keySize));
236 if (keyInfo) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100237 OpenSL(decoderMetadata, GetKey, i, keySize, keyInfo);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100238 if (keyInfo->encoding == SL_CHARACTERENCODING_ASCII
239 || keyInfo->encoding == SL_CHARACTERENCODING_UTF8) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100240 OpenSL(decoderMetadata, GetValueSize, i, &valueSize);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100241 value = static_cast<SLMetadataInfo*>(malloc(valueSize));
242 if (value) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100243 OpenSL(decoderMetadata, GetValue, i, valueSize, value);
Hugo Hudsonefaa38a2011-09-09 14:46:15 +0100244 if (strcmp((char*) keyInfo->data, ANDROID_KEY_PCMFORMAT_SAMPLERATE) == 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100245 SLuint32 sampleRate = *(reinterpret_cast<SLuint32*>(value->data));
246 LOGD("sample Rate: %d", sampleRate);
247 *sampleRateOut = sampleRate;
Hugo Hudsonefaa38a2011-09-09 14:46:15 +0100248 } else if (strcmp((char*) keyInfo->data, ANDROID_KEY_PCMFORMAT_NUMCHANNELS) == 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100249 SLuint32 channels = *(reinterpret_cast<SLuint32*>(value->data));
250 LOGD("channels: %d", channels);
251 *channelsOut = channels;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100252 }
253 free(value);
254 }
255 }
256 free(keyInfo);
257 }
258 }
259}
260
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100261// Must be called with callbackLock_ held.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100262static void RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100263 SLAndroidSimpleBufferQueueItf decoderQueue, CallbackContext* context) {
264 // Register a callback on the decoder queue, so that we will be called
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100265 // throughout the decoding process (and can then extract the decoded audio
266 // for the next bit of the pipeline).
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100267 OpenSL(decoderQueue, RegisterCallback, DecodingBufferQueueCb, context);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100268
269 // Enqueue buffers to map the region of memory allocated to store the
270 // decoded data.
271 for (size_t i = 0; i < kNumberOfBuffersInQueue; i++) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100272 OpenSL(decoderQueue, Enqueue, context->pData, kBufferSizeInBytes);
Hugo Hudson9730f152011-07-25 17:04:42 +0100273 context->pData += kBufferSizeInBytes;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100274 }
Hugo Hudson9730f152011-07-25 17:04:42 +0100275 context->pData = context->pDataBase;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100276}
277
278// ****************************************************************************
279// Constructor and Destructor.
280
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100281AudioEngine::AudioEngine(size_t targetFrames, float windowDuration,
282 float windowOverlapDuration, size_t maxPlayBufferCount, float initialRate,
Flavio Lerdadc442b42011-08-31 15:49:53 +0100283 size_t decodeInitialSize, size_t decodeMaxSize, size_t startPositionMillis,
284 int audioStreamType)
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100285 : decodeBuffer_(decodeInitialSize, decodeMaxSize),
286 playingBuffers_(), freeBuffers_(), timeScaler_(NULL),
287 floatBuffer_(NULL), injectBuffer_(NULL),
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100288 mSampleRate(0), mChannels(0),
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100289 targetFrames_(targetFrames),
290 windowDuration_(windowDuration),
291 windowOverlapDuration_(windowOverlapDuration),
292 maxPlayBufferCount_(maxPlayBufferCount), initialRate_(initialRate),
293 startPositionMillis_(startPositionMillis),
Flavio Lerdadc442b42011-08-31 15:49:53 +0100294 audioStreamType_(audioStreamType),
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100295 totalDurationMs_(0), decoderCurrentPosition_(0), startRequested_(false),
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100296 stopRequested_(false), finishedDecoding_(false) {
Flavio Lerdae8638162011-09-02 16:40:13 +0100297 // Determine whether we should log calls.
298 gLogEnabled = ShouldLog();
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100299}
300
301AudioEngine::~AudioEngine() {
302 // destroy the time scaler
303 if (timeScaler_ != NULL) {
304 delete timeScaler_;
305 timeScaler_ = NULL;
306 }
307
308 // delete all outstanding playing and free buffers
309 android::Mutex::Autolock autoLock(playBufferLock_);
310 while (playingBuffers_.size() > 0) {
311 delete[] playingBuffers_.front();
312 playingBuffers_.pop();
313 }
314 while (freeBuffers_.size() > 0) {
315 delete[] freeBuffers_.top();
316 freeBuffers_.pop();
317 }
318
319 delete[] floatBuffer_;
320 floatBuffer_ = NULL;
321 delete[] injectBuffer_;
322 injectBuffer_ = NULL;
323}
324
325// ****************************************************************************
326// Regular AudioEngine class methods.
327
328void AudioEngine::SetVariableSpeed(float speed) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100329 // TODO: Mutex for shared time scaler accesses.
Hugo Hudson64f5ba62011-08-10 15:57:28 +0100330 if (HasSampleRateAndChannels()) {
331 GetTimeScaler()->set_speed(speed);
332 } else {
333 // This is being called at a point where we have not yet processed enough
334 // data to determine the sample rate and number of channels.
335 // Ignore the call. See http://b/5140693.
336 LOGD("set varaible speed called, sample rate and channels not ready yet");
337 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100338}
339
340void AudioEngine::RequestStart() {
341 android::Mutex::Autolock autoLock(lock_);
342 startRequested_ = true;
343}
344
345void AudioEngine::ClearRequestStart() {
346 android::Mutex::Autolock autoLock(lock_);
347 startRequested_ = false;
348}
349
350bool AudioEngine::GetWasStartRequested() {
351 android::Mutex::Autolock autoLock(lock_);
352 return startRequested_;
353}
354
355void AudioEngine::RequestStop() {
356 android::Mutex::Autolock autoLock(lock_);
357 stopRequested_ = true;
358}
359
360int AudioEngine::GetCurrentPosition() {
361 android::Mutex::Autolock autoLock(decodeBufferLock_);
362 double result = decodeBuffer_.GetTotalAdvancedCount();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100363 // TODO: This is horrible, but should be removed soon once the outstanding
364 // issue with get current position on decoder is fixed.
365 android::Mutex::Autolock autoLock2(callbackLock_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100366 return static_cast<int>(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100367 (result * 1000) / mSampleRate / mChannels + startPositionMillis_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100368}
369
370int AudioEngine::GetTotalDuration() {
371 android::Mutex::Autolock autoLock(lock_);
372 return static_cast<int>(totalDurationMs_);
373}
374
375video_editing::SolaTimeScaler* AudioEngine::GetTimeScaler() {
376 if (timeScaler_ == NULL) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100377 CHECK(HasSampleRateAndChannels());
378 android::Mutex::Autolock autoLock(callbackLock_);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100379 timeScaler_ = new video_editing::SolaTimeScaler();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100380 timeScaler_->Init(mSampleRate, mChannels, initialRate_, windowDuration_,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100381 windowOverlapDuration_);
382 }
383 return timeScaler_;
384}
385
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100386bool AudioEngine::EnqueueNextBufferOfAudio(
387 SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100388 size_t channels;
389 {
390 android::Mutex::Autolock autoLock(callbackLock_);
391 channels = mChannels;
392 }
393 size_t frameSizeInBytes = kSampleSizeInBytes * channels;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100394 size_t frameCount = 0;
395 while (frameCount < targetFrames_) {
396 size_t framesLeft = targetFrames_ - frameCount;
397 // If there is data already in the time scaler, retrieve it.
398 if (GetTimeScaler()->available() > 0) {
399 size_t retrieveCount = min(GetTimeScaler()->available(), framesLeft);
400 int count = GetTimeScaler()->RetrieveSamples(
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100401 floatBuffer_ + frameCount * channels, retrieveCount);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100402 if (count <= 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100403 LOGD("error: count was %d", count);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100404 break;
405 }
406 frameCount += count;
407 continue;
408 }
409 // If there is no data in the time scaler, then feed some into it.
410 android::Mutex::Autolock autoLock(decodeBufferLock_);
411 size_t framesInDecodeBuffer =
412 decodeBuffer_.GetSizeInBytes() / frameSizeInBytes;
413 size_t framesScalerCanHandle = GetTimeScaler()->input_limit();
414 size_t framesToInject = min(framesInDecodeBuffer,
415 min(targetFrames_, framesScalerCanHandle));
416 if (framesToInject <= 0) {
417 // No more frames left to inject.
418 break;
419 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100420 for (size_t i = 0; i < framesToInject * channels; ++i) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100421 injectBuffer_[i] = decodeBuffer_.GetAtIndex(i);
422 }
423 int count = GetTimeScaler()->InjectSamples(injectBuffer_, framesToInject);
424 if (count <= 0) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100425 LOGD("error: count was %d", count);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100426 break;
427 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100428 decodeBuffer_.AdvanceHeadPointerShorts(count * channels);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100429 }
430 if (frameCount <= 0) {
431 // We must have finished playback.
432 if (GetEndOfDecoderReached()) {
433 // If we've finished decoding, clear the buffer - so we will terminate.
434 ClearDecodeBuffer();
435 }
436 return false;
437 }
438
439 // Get a free playing buffer.
440 int16* playBuffer;
441 {
442 android::Mutex::Autolock autoLock(playBufferLock_);
443 if (freeBuffers_.size() > 0) {
444 // If we have a free buffer, recycle it.
445 playBuffer = freeBuffers_.top();
446 freeBuffers_.pop();
447 } else {
448 // Otherwise allocate a new one.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100449 playBuffer = new int16[targetFrames_ * channels];
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100450 }
451 }
452
453 // Try to play the buffer.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100454 for (size_t i = 0; i < frameCount * channels; ++i) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100455 playBuffer[i] = floatBuffer_[i];
456 }
457 size_t sizeOfPlayBufferInBytes =
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100458 frameCount * channels * kNumberOfBytesPerInt16;
459 SLresult result = ReturnOpenSL(audioPlayerQueue, Enqueue, playBuffer,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100460 sizeOfPlayBufferInBytes);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100461 if (result == SL_RESULT_SUCCESS) {
462 android::Mutex::Autolock autoLock(playBufferLock_);
463 playingBuffers_.push(playBuffer);
464 } else {
465 LOGE("could not enqueue audio buffer");
466 delete[] playBuffer;
467 }
468
469 return (result == SL_RESULT_SUCCESS);
470}
471
472bool AudioEngine::GetEndOfDecoderReached() {
473 android::Mutex::Autolock autoLock(lock_);
474 return finishedDecoding_;
475}
476
477void AudioEngine::SetEndOfDecoderReached() {
478 android::Mutex::Autolock autoLock(lock_);
479 finishedDecoding_ = true;
480}
481
482bool AudioEngine::PlayFileDescriptor(int fd, int64 offset, int64 length) {
483 SLDataLocator_AndroidFD loc_fd = {
484 SL_DATALOCATOR_ANDROIDFD, fd, offset, length };
485 SLDataFormat_MIME format_mime = {
486 SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
487 SLDataSource audioSrc = { &loc_fd, &format_mime };
488 return PlayFromThisSource(audioSrc);
489}
490
491bool AudioEngine::PlayUri(const char* uri) {
492 // Source of audio data for the decoding
493 SLDataLocator_URI decUri = { SL_DATALOCATOR_URI,
494 const_cast<SLchar*>(reinterpret_cast<const SLchar*>(uri)) };
495 SLDataFormat_MIME decMime = {
496 SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
497 SLDataSource decSource = { &decUri, &decMime };
498 return PlayFromThisSource(decSource);
499}
500
501bool AudioEngine::IsDecodeBufferEmpty() {
502 android::Mutex::Autolock autoLock(decodeBufferLock_);
503 return decodeBuffer_.GetSizeInBytes() <= 0;
504}
505
506void AudioEngine::ClearDecodeBuffer() {
507 android::Mutex::Autolock autoLock(decodeBufferLock_);
508 decodeBuffer_.Clear();
509}
510
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100511static size_t ReadDuration(SLPlayItf playItf) {
512 SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
513 OpenSL(playItf, GetDuration, &durationInMsec);
514 if (durationInMsec == SL_TIME_UNKNOWN) {
515 LOGE("can't get duration");
516 return 0;
517 }
518 LOGD("duration: %d", static_cast<int>(durationInMsec));
519 return durationInMsec;
520}
521
522static size_t ReadPosition(SLPlayItf playItf) {
523 SLmillisecond positionInMsec = SL_TIME_UNKNOWN;
524 OpenSL(playItf, GetPosition, &positionInMsec);
525 if (positionInMsec == SL_TIME_UNKNOWN) {
526 LOGE("can't get position");
527 return 0;
528 }
529 LOGW("decoder position: %d", static_cast<int>(positionInMsec));
530 return positionInMsec;
531}
532
Hugo Hudson9730f152011-07-25 17:04:42 +0100533static void CreateAndRealizeEngine(SLObjectItf &engine,
534 SLEngineItf &engineInterface) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100535 SLEngineOption EngineOption[] = { {
536 SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE } };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100537 SLresult result = slCreateEngine(&engine, 1, EngineOption, 0, NULL, NULL);
538 CheckSLResult("create engine", result);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100539 OpenSL(engine, Realize, SL_BOOLEAN_FALSE);
540 OpenSL(engine, GetInterface, SL_IID_ENGINE, &engineInterface);
Hugo Hudson9730f152011-07-25 17:04:42 +0100541}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100542
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100543SLuint32 AudioEngine::GetSLSampleRate() {
544 android::Mutex::Autolock autoLock(callbackLock_);
545 return mSampleRate * 1000;
Hugo Hudson9730f152011-07-25 17:04:42 +0100546}
547
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100548SLuint32 AudioEngine::GetSLChannels() {
549 android::Mutex::Autolock autoLock(callbackLock_);
550 switch (mChannels) {
Hugo Hudson9730f152011-07-25 17:04:42 +0100551 case 2:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100552 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
Hugo Hudson9730f152011-07-25 17:04:42 +0100553 case 1:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100554 return SL_SPEAKER_FRONT_CENTER;
Hugo Hudson9730f152011-07-25 17:04:42 +0100555 default:
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100556 LOGE("unknown channels %d, using 2", mChannels);
557 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
Hugo Hudson9730f152011-07-25 17:04:42 +0100558 }
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100559}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100560
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100561SLuint32 AudioEngine::GetChannelCount() {
562 android::Mutex::Autolock autoLock(callbackLock_);
563 return mChannels;
564}
565
566static void CreateAndRealizeAudioPlayer(SLuint32 slSampleRate,
Ashok Bhatf12ca302014-02-12 13:43:25 +0000567 SLuint32 channelCount, SLuint32 slChannels, SLint32 audioStreamType, SLObjectItf &outputMix,
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100568 SLObjectItf &audioPlayer, SLEngineItf &engineInterface) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100569 // Define the source and sink for the audio player: comes from a buffer queue
570 // and goes to the output mix.
571 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
572 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100573 SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channelCount, slSampleRate,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100574 SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100575 slChannels, SL_BYTEORDER_LITTLEENDIAN};
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100576 SLDataSource playingSrc = {&loc_bufq, &format_pcm};
577 SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMix};
578 SLDataSink audioSnk = {&loc_outmix, NULL};
579
580 // Create the audio player, which will play from the buffer queue and send to
581 // the output mix.
Flavio Lerdadc442b42011-08-31 15:49:53 +0100582 const size_t playerInterfaceCount = 2;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100583 const SLInterfaceID iids[playerInterfaceCount] = {
Flavio Lerdadc442b42011-08-31 15:49:53 +0100584 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
Glenn Kastencd961432012-07-03 13:13:53 -0700585 const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100586 OpenSL(engineInterface, CreateAudioPlayer, &audioPlayer, &playingSrc,
587 &audioSnk, playerInterfaceCount, iids, reqs);
Flavio Lerdadc442b42011-08-31 15:49:53 +0100588 setAudioStreamType(audioPlayer, audioStreamType);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100589 OpenSL(audioPlayer, Realize, SL_BOOLEAN_FALSE);
Hugo Hudson9730f152011-07-25 17:04:42 +0100590}
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100591
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100592bool AudioEngine::HasSampleRateAndChannels() {
593 android::Mutex::Autolock autoLock(callbackLock_);
594 return mChannels != 0 && mSampleRate != 0;
Hugo Hudson9730f152011-07-25 17:04:42 +0100595}
596
597bool AudioEngine::PlayFromThisSource(const SLDataSource& audioSrc) {
598 ClearDecodeBuffer();
599
Hugo Hudson9730f152011-07-25 17:04:42 +0100600 SLObjectItf engine;
601 SLEngineItf engineInterface;
602 CreateAndRealizeEngine(engine, engineInterface);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100603
604 // Define the source and sink for the decoding player: comes from the source
605 // this method was called with, is sent to another buffer queue.
606 SLDataLocator_AndroidSimpleBufferQueue decBuffQueue;
607 decBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
608 decBuffQueue.numBuffers = kNumberOfBuffersInQueue;
609 // A valid value seems required here but is currently ignored.
Hugo Hudson9730f152011-07-25 17:04:42 +0100610 SLDataFormat_PCM pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1,
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100611 SL_PCMSAMPLEFORMAT_FIXED_16, 16,
612 SL_SPEAKER_FRONT_LEFT, SL_BYTEORDER_LITTLEENDIAN};
613 SLDataSink decDest = { &decBuffQueue, &pcm };
614
615 // Create the decoder with the given source and sink.
Flavio Lerdadc442b42011-08-31 15:49:53 +0100616 const size_t decoderInterfaceCount = 5;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100617 SLObjectItf decoder;
618 const SLInterfaceID decodePlayerInterfaces[decoderInterfaceCount] = {
619 SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PREFETCHSTATUS, SL_IID_SEEK,
Flavio Lerdadc442b42011-08-31 15:49:53 +0100620 SL_IID_METADATAEXTRACTION, SL_IID_ANDROIDCONFIGURATION };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100621 const SLboolean decodePlayerRequired[decoderInterfaceCount] = {
Glenn Kastencd961432012-07-03 13:13:53 -0700622 SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100623 SLDataSource sourceCopy(audioSrc);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100624 OpenSL(engineInterface, CreateAudioPlayer, &decoder, &sourceCopy, &decDest,
625 decoderInterfaceCount, decodePlayerInterfaces, decodePlayerRequired);
Flavio Lerdadc442b42011-08-31 15:49:53 +0100626 // Not sure if this is necessary, but just in case.
627 setAudioStreamType(decoder, audioStreamType_);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100628 OpenSL(decoder, Realize, SL_BOOLEAN_FALSE);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100629
630 // Get the play interface from the decoder, and register event callbacks.
631 // Get the buffer queue, prefetch and seek interfaces.
Hugo Hudson9730f152011-07-25 17:04:42 +0100632 SLPlayItf decoderPlay = NULL;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100633 SLAndroidSimpleBufferQueueItf decoderQueue = NULL;
634 SLPrefetchStatusItf decoderPrefetch = NULL;
635 SLSeekItf decoderSeek = NULL;
636 SLMetadataExtractionItf decoderMetadata = NULL;
637 OpenSL(decoder, GetInterface, SL_IID_PLAY, &decoderPlay);
638 OpenSL(decoderPlay, SetCallbackEventsMask, SL_PLAYEVENT_HEADATEND);
639 OpenSL(decoderPlay, RegisterCallback, DecodingEventCb, NULL);
640 OpenSL(decoder, GetInterface, SL_IID_PREFETCHSTATUS, &decoderPrefetch);
641 OpenSL(decoder, GetInterface, SL_IID_SEEK, &decoderSeek);
642 OpenSL(decoder, GetInterface, SL_IID_METADATAEXTRACTION, &decoderMetadata);
643 OpenSL(decoder, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
644 &decoderQueue);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100645
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100646 // Initialize the callback structure, used during the decoding.
Hugo Hudson9730f152011-07-25 17:04:42 +0100647 CallbackContext callbackContext;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100648 {
649 android::Mutex::Autolock autoLock(callbackLock_);
650 callbackContext.pDataBase = pcmData;
651 callbackContext.pData = pcmData;
652 callbackContext.decoderMetadata = decoderMetadata;
653 callbackContext.playItf = decoderPlay;
654 RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
655 decoderQueue, &callbackContext);
656 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100657
658 // Initialize the callback for prefetch errors, if we can't open the
659 // resource to decode.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100660 OpenSL(decoderPrefetch, SetCallbackEventsMask, kPrefetchErrorCandidate);
661 OpenSL(decoderPrefetch, RegisterCallback, PrefetchEventCb, &decoderPrefetch);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100662
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100663 // Seek to the start position.
664 OpenSL(decoderSeek, SetPosition, startPositionMillis_, SL_SEEKMODE_ACCURATE);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100665
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100666 // Start decoding immediately.
667 OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100668
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100669 // These variables hold the audio player and its output.
670 // They will only be constructed once the decoder has invoked the callback,
671 // and given us the correct sample rate, number of channels and duration.
Hugo Hudson9730f152011-07-25 17:04:42 +0100672 SLObjectItf outputMix = NULL;
673 SLObjectItf audioPlayer = NULL;
674 SLPlayItf audioPlayerPlay = NULL;
675 SLAndroidSimpleBufferQueueItf audioPlayerQueue = NULL;
676
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100677 // The main loop - until we're told to stop: if there is audio data coming
678 // out of the decoder, feed it through the time scaler.
679 // As it comes out of the time scaler, feed it into the audio player.
680 while (!Finished()) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100681 if (GetWasStartRequested() && HasSampleRateAndChannels()) {
682 // Build the audio player.
683 // TODO: What happens if I maliciously call start lots of times?
684 floatBuffer_ = new float[targetFrames_ * mChannels];
685 injectBuffer_ = new float[targetFrames_ * mChannels];
686 OpenSL(engineInterface, CreateOutputMix, &outputMix, 0, NULL, NULL);
687 OpenSL(outputMix, Realize, SL_BOOLEAN_FALSE);
688 CreateAndRealizeAudioPlayer(GetSLSampleRate(), GetChannelCount(),
Flavio Lerdadc442b42011-08-31 15:49:53 +0100689 GetSLChannels(), audioStreamType_, outputMix, audioPlayer,
690 engineInterface);
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100691 OpenSL(audioPlayer, GetInterface, SL_IID_PLAY, &audioPlayerPlay);
692 OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
693 &audioPlayerQueue);
694 OpenSL(audioPlayerQueue, RegisterCallback, PlayingBufferQueueCb, NULL);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100695 ClearRequestStart();
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100696 OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100697 }
698 EnqueueMoreAudioIfNecessary(audioPlayerQueue);
699 usleep(kSleepTimeMicros);
700 }
701
Hugo Hudson9730f152011-07-25 17:04:42 +0100702 // Delete the audio player and output mix, iff they have been created.
703 if (audioPlayer != NULL) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100704 OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
705 OpenSL0(audioPlayerQueue, Clear);
706 OpenSL(audioPlayerQueue, RegisterCallback, NULL, NULL);
707 VoidOpenSL(audioPlayer, AbortAsyncOperation);
708 VoidOpenSL(audioPlayer, Destroy);
709 VoidOpenSL(outputMix, Destroy);
Hugo Hudson9730f152011-07-25 17:04:42 +0100710 audioPlayer = NULL;
711 audioPlayerPlay = NULL;
712 audioPlayerQueue = NULL;
713 outputMix = NULL;
714 }
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100715
716 // Delete the decoder.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100717 OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
718 OpenSL(decoderPrefetch, RegisterCallback, NULL, NULL);
Hugo Hudson9730f152011-07-25 17:04:42 +0100719 // This is returning slresult 13 if I do no playback.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100720 // Repro is to comment out all before this line, and all after enqueueing
721 // my buffers.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100722 // OpenSL0(decoderQueue, Clear);
723 OpenSL(decoderQueue, RegisterCallback, NULL, NULL);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100724 decoderSeek = NULL;
725 decoderPrefetch = NULL;
726 decoderQueue = NULL;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100727 OpenSL(decoderPlay, RegisterCallback, NULL, NULL);
728 VoidOpenSL(decoder, AbortAsyncOperation);
729 VoidOpenSL(decoder, Destroy);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100730 decoderPlay = NULL;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100731
Hugo Hudson9730f152011-07-25 17:04:42 +0100732 // Delete the engine.
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100733 VoidOpenSL(engine, Destroy);
Hugo Hudson9730f152011-07-25 17:04:42 +0100734 engineInterface = NULL;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100735
736 return true;
737}
738
739bool AudioEngine::Finished() {
740 if (GetWasStopRequested()) {
741 return true;
742 }
743 android::Mutex::Autolock autoLock(playBufferLock_);
744 return playingBuffers_.size() <= 0 &&
745 IsDecodeBufferEmpty() &&
746 GetEndOfDecoderReached();
747}
748
749bool AudioEngine::GetWasStopRequested() {
750 android::Mutex::Autolock autoLock(lock_);
751 return stopRequested_;
752}
753
754bool AudioEngine::GetHasReachedPlayingBuffersLimit() {
755 android::Mutex::Autolock autoLock(playBufferLock_);
756 return playingBuffers_.size() >= maxPlayBufferCount_;
757}
758
759void AudioEngine::EnqueueMoreAudioIfNecessary(
760 SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
761 bool keepEnqueueing = true;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100762 while (audioPlayerQueue != NULL &&
763 !GetWasStopRequested() &&
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100764 !IsDecodeBufferEmpty() &&
765 !GetHasReachedPlayingBuffersLimit() &&
766 keepEnqueueing) {
767 keepEnqueueing = EnqueueNextBufferOfAudio(audioPlayerQueue);
768 }
769}
770
771bool AudioEngine::DecodeBufferTooFull() {
772 android::Mutex::Autolock autoLock(decodeBufferLock_);
773 return decodeBuffer_.IsTooLarge();
774}
775
776// ****************************************************************************
777// Code for handling the static callbacks.
778
779void AudioEngine::PlayingBufferQueueCallback() {
780 // The head playing buffer is done, move it to the free list.
781 android::Mutex::Autolock autoLock(playBufferLock_);
782 if (playingBuffers_.size() > 0) {
783 freeBuffers_.push(playingBuffers_.front());
784 playingBuffers_.pop();
785 }
786}
787
788void AudioEngine::PrefetchEventCallback(
789 SLPrefetchStatusItf caller, SLuint32 event) {
790 // If there was a problem during decoding, then signal the end.
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100791 SLpermille level = 0;
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100792 SLuint32 status;
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100793 OpenSL(caller, GetFillLevel, &level);
794 OpenSL(caller, GetPrefetchStatus, &status);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100795 if ((kPrefetchErrorCandidate == (event & kPrefetchErrorCandidate)) &&
796 (level == 0) &&
797 (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100798 LOGI("prefetcheventcallback error while prefetching data");
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100799 SetEndOfDecoderReached();
800 }
801 if (SL_PREFETCHSTATUS_SUFFICIENTDATA == event) {
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100802 // android::Mutex::Autolock autoLock(prefetchLock_);
803 // prefetchCondition_.broadcast();
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100804 }
805}
806
807void AudioEngine::DecodingBufferQueueCallback(
808 SLAndroidSimpleBufferQueueItf queueItf, void *context) {
809 if (GetWasStopRequested()) {
810 return;
811 }
812
813 CallbackContext *pCntxt;
814 {
815 android::Mutex::Autolock autoLock(callbackLock_);
816 pCntxt = reinterpret_cast<CallbackContext*>(context);
817 }
818 {
819 android::Mutex::Autolock autoLock(decodeBufferLock_);
Hugo Hudsond2772c42011-08-27 01:21:54 +0100820 decodeBuffer_.AddData(pCntxt->pData, kBufferSizeInBytes);
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100821 }
822
Hugo Hudson0bd6ec52011-07-26 20:05:25 +0100823 if (!HasSampleRateAndChannels()) {
824 android::Mutex::Autolock autoLock(callbackLock_);
825 ReadSampleRateAndChannelCount(pCntxt, &mSampleRate, &mChannels);
826 }
827
828 {
829 android::Mutex::Autolock autoLock(lock_);
830 if (totalDurationMs_ == 0) {
831 totalDurationMs_ = ReadDuration(pCntxt->playItf);
832 }
833 // TODO: This isn't working, it always reports zero.
834 // ReadPosition(pCntxt->playItf);
835 }
Hugo Hudson9730f152011-07-25 17:04:42 +0100836
Hugo Hudsond2772c42011-08-27 01:21:54 +0100837 OpenSL(queueItf, Enqueue, pCntxt->pData, kBufferSizeInBytes);
838
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100839 // Increase data pointer by buffer size
840 pCntxt->pData += kBufferSizeInBytes;
841 if (pCntxt->pData >= pCntxt->pDataBase +
842 (kNumberOfBuffersInQueue * kBufferSizeInBytes)) {
843 pCntxt->pData = pCntxt->pDataBase;
844 }
845
Hugo Hudsonb83ad732011-07-14 23:31:17 +0100846 // If we get too much data into the decoder,
847 // sleep until the playback catches up.
848 while (!GetWasStopRequested() && DecodeBufferTooFull()) {
849 usleep(kSleepTimeMicros);
850 }
851}
852
853void AudioEngine::DecodingEventCallback(SLPlayItf, SLuint32 event) {
854 if (SL_PLAYEVENT_HEADATEND & event) {
855 SetEndOfDecoderReached();
856 }
857}