blob: 4208019378f3ee5e4b86142eeeaddeae5899c34f [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
2 * Copyright (C) 2009 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
Andreas Huberdae04ca2009-11-05 16:34:39 -080017//#define LOG_NDEBUG 0
Andreas Huber20111aa2009-07-14 16:56:47 -070018#define LOG_TAG "AudioPlayer"
19#include <utils/Log.h>
20
Andreas Huber25155ff2010-03-01 14:27:00 -080021#include <binder/IPCThreadState.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070022#include <media/AudioTrack.h>
Andreas Huberf7eade92011-09-08 11:33:47 -070023#include <media/stagefright/foundation/ADebug.h>
Andreas Hubere4451a92012-05-14 15:55:48 -070024#include <media/stagefright/foundation/ALooper.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070025#include <media/stagefright/AudioPlayer.h>
Andreas Huber18291bc2009-09-10 14:13:30 -070026#include <media/stagefright/MediaDefs.h>
Andreas Huber3cc219d2010-07-20 09:44:34 -070027#include <media/stagefright/MediaErrors.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070028#include <media/stagefright/MediaSource.h>
29#include <media/stagefright/MetaData.h>
30
Andreas Hubered54ad02010-09-28 11:56:39 -070031#include "include/AwesomePlayer.h"
32
Andreas Huber20111aa2009-07-14 16:56:47 -070033namespace android {
34
Andreas Hubered54ad02010-09-28 11:56:39 -070035AudioPlayer::AudioPlayer(
36 const sp<MediaPlayerBase::AudioSink> &audioSink,
Eric Laurent1948eb32012-04-13 16:50:19 -070037 bool allowDeepBuffering,
Andreas Hubered54ad02010-09-28 11:56:39 -070038 AwesomePlayer *observer)
Andreas Huber693d2712009-08-14 14:37:10 -070039 : mAudioTrack(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070040 mInputBuffer(NULL),
41 mSampleRate(0),
42 mLatencyUs(0),
43 mFrameSize(0),
44 mNumFramesPlayed(0),
Andreas Hubere4451a92012-05-14 15:55:48 -070045 mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
Andreas Huber20111aa2009-07-14 16:56:47 -070046 mPositionTimeMediaUs(-1),
47 mPositionTimeRealUs(-1),
48 mSeeking(false),
Andreas Huber1862a332010-02-03 11:37:29 -080049 mReachedEOS(false),
Andreas Huber5295c0c2010-02-23 13:45:33 -080050 mFinalStatus(OK),
Andreas Huber20111aa2009-07-14 16:56:47 -070051 mStarted(false),
Andreas Huber3cc219d2010-07-20 09:44:34 -070052 mIsFirstBuffer(false),
53 mFirstBufferResult(OK),
54 mFirstBuffer(NULL),
Andreas Hubered54ad02010-09-28 11:56:39 -070055 mAudioSink(audioSink),
Eric Laurent1948eb32012-04-13 16:50:19 -070056 mAllowDeepBuffering(allowDeepBuffering),
Andreas Hubera99a5bc2012-05-15 15:57:59 -070057 mObserver(observer),
58 mPinnedTimeUs(-1ll) {
Andreas Huber20111aa2009-07-14 16:56:47 -070059}
60
61AudioPlayer::~AudioPlayer() {
62 if (mStarted) {
Andreas Huberb2e39542010-10-05 10:25:34 -070063 reset();
Andreas Huber20111aa2009-07-14 16:56:47 -070064 }
65}
66
Andreas Huber693d2712009-08-14 14:37:10 -070067void AudioPlayer::setSource(const sp<MediaSource> &source) {
Andreas Huberf7eade92011-09-08 11:33:47 -070068 CHECK(mSource == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -070069 mSource = source;
70}
71
Andreas Hubere7e3b782010-03-08 15:46:13 -080072status_t AudioPlayer::start(bool sourceAlreadyStarted) {
Andreas Huber0c891992009-08-26 14:48:20 -070073 CHECK(!mStarted);
74 CHECK(mSource != NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -070075
Andreas Hubere7e3b782010-03-08 15:46:13 -080076 status_t err;
77 if (!sourceAlreadyStarted) {
78 err = mSource->start();
Andreas Huber88c030e2010-01-29 13:24:58 -080079
Andreas Hubere7e3b782010-03-08 15:46:13 -080080 if (err != OK) {
81 return err;
82 }
Andreas Huber88c030e2010-01-29 13:24:58 -080083 }
Andreas Huber20111aa2009-07-14 16:56:47 -070084
Andreas Huber3cc219d2010-07-20 09:44:34 -070085 // We allow an optional INFO_FORMAT_CHANGED at the very beginning
86 // of playback, if there is one, getFormat below will retrieve the
87 // updated format, if there isn't, we'll stash away the valid buffer
88 // of data to be used on the first audio callback.
89
90 CHECK(mFirstBuffer == NULL);
91
Andreas Huberc0dfc5b2011-05-10 13:56:39 -070092 MediaSource::ReadOptions options;
93 if (mSeeking) {
94 options.setSeekTo(mSeekTimeUs);
95 mSeeking = false;
96 }
97
98 mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
Andreas Huber3cc219d2010-07-20 09:44:34 -070099 if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
Steve Block3856b092011-10-20 11:56:00 +0100100 ALOGV("INFO_FORMAT_CHANGED!!!");
Andreas Huber3cc219d2010-07-20 09:44:34 -0700101
102 CHECK(mFirstBuffer == NULL);
103 mFirstBufferResult = OK;
104 mIsFirstBuffer = false;
105 } else {
106 mIsFirstBuffer = true;
107 }
108
Andreas Huber20111aa2009-07-14 16:56:47 -0700109 sp<MetaData> format = mSource->getFormat();
110 const char *mime;
111 bool success = format->findCString(kKeyMIMEType, &mime);
Andreas Huber0c891992009-08-26 14:48:20 -0700112 CHECK(success);
Andreas Huber18291bc2009-09-10 14:13:30 -0700113 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
Andreas Huber20111aa2009-07-14 16:56:47 -0700114
115 success = format->findInt32(kKeySampleRate, &mSampleRate);
Andreas Huber0c891992009-08-26 14:48:20 -0700116 CHECK(success);
Andreas Huber20111aa2009-07-14 16:56:47 -0700117
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800118 int32_t numChannels, channelMask;
Andreas Huber20111aa2009-07-14 16:56:47 -0700119 success = format->findInt32(kKeyChannelCount, &numChannels);
Andreas Huber0c891992009-08-26 14:48:20 -0700120 CHECK(success);
Andreas Huber20111aa2009-07-14 16:56:47 -0700121
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800122 if(!format->findInt32(kKeyChannelMask, &channelMask)) {
Jean-Michel Trivi2c3297a2012-05-01 14:30:58 -0700123 // log only when there's a risk of ambiguity of channel mask selection
124 ALOGI_IF(numChannels > 2,
125 "source format didn't specify channel mask, using (%d) channel order", numChannels);
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800126 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
127 }
128
Andreas Huber20111aa2009-07-14 16:56:47 -0700129 if (mAudioSink.get() != NULL) {
Eric Laurent1948eb32012-04-13 16:50:19 -0700130
Andreas Huber20111aa2009-07-14 16:56:47 -0700131 status_t err = mAudioSink->open(
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800132 mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT,
Andreas Huber20111aa2009-07-14 16:56:47 -0700133 DEFAULT_AUDIOSINK_BUFFERCOUNT,
Eric Laurent1948eb32012-04-13 16:50:19 -0700134 &AudioPlayer::AudioSinkCallback,
135 this,
136 (mAllowDeepBuffering ?
137 AUDIO_OUTPUT_FLAG_DEEP_BUFFER :
138 AUDIO_OUTPUT_FLAG_NONE));
Andreas Huber88c030e2010-01-29 13:24:58 -0800139 if (err != OK) {
Andreas Huber3cc219d2010-07-20 09:44:34 -0700140 if (mFirstBuffer != NULL) {
141 mFirstBuffer->release();
142 mFirstBuffer = NULL;
143 }
144
Andreas Huber4575beb2012-05-22 10:03:57 -0700145 if (!sourceAlreadyStarted) {
146 mSource->stop();
147 }
Andreas Huber88c030e2010-01-29 13:24:58 -0800148
149 return err;
150 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700151
152 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
153 mFrameSize = mAudioSink->frameSize();
154
155 mAudioSink->start();
156 } else {
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800157 // playing to an AudioTrack, set up mask if necessary
158 audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
Glenn Kastenab334fd2012-03-14 12:56:06 -0700159 audio_channel_out_mask_from_count(numChannels) : channelMask;
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800160 if (0 == audioMask) {
161 return BAD_VALUE;
162 }
163
Andreas Huber20111aa2009-07-14 16:56:47 -0700164 mAudioTrack = new AudioTrack(
Jean-Michel Trivi786618f2012-03-02 14:54:07 -0800165 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
Eric Laurent0ca3cf92012-04-18 09:24:29 -0700166 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
Andreas Huber20111aa2009-07-14 16:56:47 -0700167
Kenny Root32dcebf2010-02-18 09:03:06 -0800168 if ((err = mAudioTrack->initCheck()) != OK) {
Andreas Huber88c030e2010-01-29 13:24:58 -0800169 delete mAudioTrack;
170 mAudioTrack = NULL;
171
Andreas Huber3cc219d2010-07-20 09:44:34 -0700172 if (mFirstBuffer != NULL) {
173 mFirstBuffer->release();
174 mFirstBuffer = NULL;
175 }
176
Andreas Huber4575beb2012-05-22 10:03:57 -0700177 if (!sourceAlreadyStarted) {
178 mSource->stop();
179 }
Andreas Huber88c030e2010-01-29 13:24:58 -0800180
Kenny Root32dcebf2010-02-18 09:03:06 -0800181 return err;
Andreas Huber88c030e2010-01-29 13:24:58 -0800182 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700183
184 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
185 mFrameSize = mAudioTrack->frameSize();
186
187 mAudioTrack->start();
188 }
189
190 mStarted = true;
Andreas Hubera99a5bc2012-05-15 15:57:59 -0700191 mPinnedTimeUs = -1ll;
Andreas Huber88c030e2010-01-29 13:24:58 -0800192
193 return OK;
Andreas Huber20111aa2009-07-14 16:56:47 -0700194}
195
Andreas Huberb2e39542010-10-05 10:25:34 -0700196void AudioPlayer::pause(bool playPendingSamples) {
Andreas Huber0c891992009-08-26 14:48:20 -0700197 CHECK(mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700198
Andreas Huberb2e39542010-10-05 10:25:34 -0700199 if (playPendingSamples) {
200 if (mAudioSink.get() != NULL) {
201 mAudioSink->stop();
202 } else {
203 mAudioTrack->stop();
204 }
Andreas Huber0b293e72011-08-26 11:26:25 -0700205
206 mNumFramesPlayed = 0;
Andreas Hubere4451a92012-05-14 15:55:48 -0700207 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
Andreas Huber20111aa2009-07-14 16:56:47 -0700208 } else {
Andreas Huberb2e39542010-10-05 10:25:34 -0700209 if (mAudioSink.get() != NULL) {
210 mAudioSink->pause();
211 } else {
212 mAudioTrack->pause();
213 }
Andreas Hubera99a5bc2012-05-15 15:57:59 -0700214
215 mPinnedTimeUs = ALooper::GetNowUs();
Andreas Huber20111aa2009-07-14 16:56:47 -0700216 }
217}
218
219void AudioPlayer::resume() {
Andreas Huber0c891992009-08-26 14:48:20 -0700220 CHECK(mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700221
222 if (mAudioSink.get() != NULL) {
223 mAudioSink->start();
224 } else {
225 mAudioTrack->start();
226 }
227}
228
Andreas Huberb2e39542010-10-05 10:25:34 -0700229void AudioPlayer::reset() {
Andreas Huber0c891992009-08-26 14:48:20 -0700230 CHECK(mStarted);
Andreas Huber20111aa2009-07-14 16:56:47 -0700231
232 if (mAudioSink.get() != NULL) {
233 mAudioSink->stop();
Andreas Huberfc9ba092010-01-11 15:35:19 -0800234 mAudioSink->close();
Andreas Huber20111aa2009-07-14 16:56:47 -0700235 } else {
236 mAudioTrack->stop();
237
238 delete mAudioTrack;
239 mAudioTrack = NULL;
240 }
Andreas Huberfc9ba092010-01-11 15:35:19 -0800241
Andreas Huber20111aa2009-07-14 16:56:47 -0700242 // Make sure to release any buffer we hold onto so that the
243 // source is able to stop().
Andreas Huber3cc219d2010-07-20 09:44:34 -0700244
245 if (mFirstBuffer != NULL) {
246 mFirstBuffer->release();
247 mFirstBuffer = NULL;
248 }
249
Andreas Huber20111aa2009-07-14 16:56:47 -0700250 if (mInputBuffer != NULL) {
Steve Block3856b092011-10-20 11:56:00 +0100251 ALOGV("AudioPlayer releasing input buffer.");
Andreas Huber20111aa2009-07-14 16:56:47 -0700252
253 mInputBuffer->release();
254 mInputBuffer = NULL;
255 }
256
257 mSource->stop();
Andreas Huberfc9ba092010-01-11 15:35:19 -0800258
Andreas Huber25155ff2010-03-01 14:27:00 -0800259 // The following hack is necessary to ensure that the OMX
260 // component is completely released by the time we may try
261 // to instantiate it again.
262 wp<MediaSource> tmp = mSource;
263 mSource.clear();
264 while (tmp.promote() != NULL) {
265 usleep(1000);
266 }
267 IPCThreadState::self()->flushCommands();
268
Andreas Huber20111aa2009-07-14 16:56:47 -0700269 mNumFramesPlayed = 0;
Andreas Hubere4451a92012-05-14 15:55:48 -0700270 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
Andreas Huber20111aa2009-07-14 16:56:47 -0700271 mPositionTimeMediaUs = -1;
272 mPositionTimeRealUs = -1;
273 mSeeking = false;
Andreas Huber1862a332010-02-03 11:37:29 -0800274 mReachedEOS = false;
Andreas Huber5295c0c2010-02-23 13:45:33 -0800275 mFinalStatus = OK;
Andreas Huber20111aa2009-07-14 16:56:47 -0700276 mStarted = false;
277}
278
279// static
Glenn Kastend217a8c2011-06-01 15:20:35 -0700280void AudioPlayer::AudioCallback(int event, void *user, void *info) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700281 static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
282}
283
Andreas Huber1862a332010-02-03 11:37:29 -0800284bool AudioPlayer::isSeeking() {
285 Mutex::Autolock autoLock(mLock);
286 return mSeeking;
287}
288
Andreas Huber5295c0c2010-02-23 13:45:33 -0800289bool AudioPlayer::reachedEOS(status_t *finalStatus) {
290 *finalStatus = OK;
291
Andreas Huber1862a332010-02-03 11:37:29 -0800292 Mutex::Autolock autoLock(mLock);
Andreas Huber5295c0c2010-02-23 13:45:33 -0800293 *finalStatus = mFinalStatus;
Andreas Huber1862a332010-02-03 11:37:29 -0800294 return mReachedEOS;
295}
296
Jean-Michel Trivi7a8b0ed2012-02-02 09:06:31 -0800297status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
298 if (mAudioSink.get() != NULL) {
299 return mAudioSink->setPlaybackRatePermille(ratePermille);
300 } else if (mAudioTrack != NULL){
301 return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
302 } else {
303 return NO_INIT;
304 }
305}
306
Andreas Huber20111aa2009-07-14 16:56:47 -0700307// static
Andreas Huber7d5b8a72010-02-09 16:59:18 -0800308size_t AudioPlayer::AudioSinkCallback(
Andreas Huber20111aa2009-07-14 16:56:47 -0700309 MediaPlayerBase::AudioSink *audioSink,
310 void *buffer, size_t size, void *cookie) {
311 AudioPlayer *me = (AudioPlayer *)cookie;
312
Andreas Huber7d5b8a72010-02-09 16:59:18 -0800313 return me->fillBuffer(buffer, size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700314}
315
Glenn Kastend217a8c2011-06-01 15:20:35 -0700316void AudioPlayer::AudioCallback(int event, void *info) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700317 if (event != AudioTrack::EVENT_MORE_DATA) {
318 return;
319 }
320
321 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
Andreas Huber7d5b8a72010-02-09 16:59:18 -0800322 size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
323
324 buffer->size = numBytesWritten;
Andreas Huber20111aa2009-07-14 16:56:47 -0700325}
326
Andreas Huber84b343f2011-03-22 10:31:21 -0700327uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
328 uint32_t numFramesPlayedOut;
329 status_t err;
330
331 if (mAudioSink != NULL) {
332 err = mAudioSink->getPosition(&numFramesPlayedOut);
333 } else {
334 err = mAudioTrack->getPosition(&numFramesPlayedOut);
335 }
336
337 if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
338 return 0;
339 }
340
341 // mNumFramesPlayed is the number of frames submitted
342 // to the audio sink for playback, but not all of them
343 // may have played out by now.
344 return mNumFramesPlayed - numFramesPlayedOut;
345}
346
Andreas Huber7d5b8a72010-02-09 16:59:18 -0800347size_t AudioPlayer::fillBuffer(void *data, size_t size) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700348 if (mNumFramesPlayed == 0) {
Steve Block3856b092011-10-20 11:56:00 +0100349 ALOGV("AudioCallback");
Andreas Huber20111aa2009-07-14 16:56:47 -0700350 }
351
Andreas Huber1862a332010-02-03 11:37:29 -0800352 if (mReachedEOS) {
Andreas Huber51c1e0e2011-04-04 11:43:40 -0700353 return 0;
Andreas Huber1862a332010-02-03 11:37:29 -0800354 }
355
Andreas Huberbd7b7172011-04-04 09:12:56 -0700356 bool postSeekComplete = false;
357 bool postEOS = false;
358 int64_t postEOSDelayUs = 0;
359
Andreas Huber20111aa2009-07-14 16:56:47 -0700360 size_t size_done = 0;
361 size_t size_remaining = size;
362 while (size_remaining > 0) {
363 MediaSource::ReadOptions options;
364
365 {
366 Mutex::Autolock autoLock(mLock);
367
368 if (mSeeking) {
Andreas Huber3cc219d2010-07-20 09:44:34 -0700369 if (mIsFirstBuffer) {
370 if (mFirstBuffer != NULL) {
371 mFirstBuffer->release();
372 mFirstBuffer = NULL;
373 }
374 mIsFirstBuffer = false;
375 }
376
Andreas Huber20111aa2009-07-14 16:56:47 -0700377 options.setSeekTo(mSeekTimeUs);
378
379 if (mInputBuffer != NULL) {
380 mInputBuffer->release();
381 mInputBuffer = NULL;
382 }
Gloria Wangcb9859b2010-02-04 17:43:09 -0800383
384 mSeeking = false;
Andreas Hubered54ad02010-09-28 11:56:39 -0700385 if (mObserver) {
Andreas Huberbd7b7172011-04-04 09:12:56 -0700386 postSeekComplete = true;
Andreas Hubered54ad02010-09-28 11:56:39 -0700387 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700388 }
389 }
390
391 if (mInputBuffer == NULL) {
Andreas Huber3cc219d2010-07-20 09:44:34 -0700392 status_t err;
393
394 if (mIsFirstBuffer) {
395 mInputBuffer = mFirstBuffer;
396 mFirstBuffer = NULL;
397 err = mFirstBufferResult;
398
399 mIsFirstBuffer = false;
400 } else {
401 err = mSource->read(&mInputBuffer, &options);
402 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700403
Andreas Huber0c891992009-08-26 14:48:20 -0700404 CHECK((err == OK && mInputBuffer != NULL)
Andreas Huber20111aa2009-07-14 16:56:47 -0700405 || (err != OK && mInputBuffer == NULL));
406
Andreas Huber1862a332010-02-03 11:37:29 -0800407 Mutex::Autolock autoLock(mLock);
Andreas Huberbfa6b2d2009-11-20 09:32:46 -0800408
Andreas Huber20111aa2009-07-14 16:56:47 -0700409 if (err != OK) {
Andreas Hubered54ad02010-09-28 11:56:39 -0700410 if (mObserver && !mReachedEOS) {
Andreas Huber84b343f2011-03-22 10:31:21 -0700411 // We don't want to post EOS right away but only
412 // after all frames have actually been played out.
413
414 // These are the number of frames submitted to the
415 // AudioTrack that you haven't heard yet.
416 uint32_t numFramesPendingPlayout =
417 getNumFramesPendingPlayout();
418
419 // These are the number of frames we're going to
420 // submit to the AudioTrack by returning from this
421 // callback.
422 uint32_t numAdditionalFrames = size_done / mFrameSize;
423
424 numFramesPendingPlayout += numAdditionalFrames;
425
426 int64_t timeToCompletionUs =
427 (1000000ll * numFramesPendingPlayout) / mSampleRate;
428
Steve Block3856b092011-10-20 11:56:00 +0100429 ALOGV("total number of frames played: %lld (%lld us)",
Andreas Huber84b343f2011-03-22 10:31:21 -0700430 (mNumFramesPlayed + numAdditionalFrames),
431 1000000ll * (mNumFramesPlayed + numAdditionalFrames)
432 / mSampleRate);
433
Steve Block3856b092011-10-20 11:56:00 +0100434 ALOGV("%d frames left to play, %lld us (%.2f secs)",
Andreas Huber84b343f2011-03-22 10:31:21 -0700435 numFramesPendingPlayout,
436 timeToCompletionUs, timeToCompletionUs / 1E6);
437
Andreas Huberbd7b7172011-04-04 09:12:56 -0700438 postEOS = true;
Marco Nelissen6b74d672012-02-28 16:07:44 -0800439 if (mAudioSink->needsTrailingPadding()) {
440 postEOSDelayUs = timeToCompletionUs + mLatencyUs;
441 } else {
442 postEOSDelayUs = 0;
443 }
Andreas Hubered54ad02010-09-28 11:56:39 -0700444 }
445
Andreas Huber1862a332010-02-03 11:37:29 -0800446 mReachedEOS = true;
Andreas Huber5295c0c2010-02-23 13:45:33 -0800447 mFinalStatus = err;
Andreas Huber20111aa2009-07-14 16:56:47 -0700448 break;
449 }
450
Eric Laurentdb354e52012-03-05 17:27:11 -0800451 if (mAudioSink != NULL) {
452 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
453 } else {
454 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
455 }
456
Andreas Huber48c948b2009-10-08 10:07:49 -0700457 CHECK(mInputBuffer->meta_data()->findInt64(
458 kKeyTime, &mPositionTimeMediaUs));
Andreas Huber00242452009-07-28 10:03:13 -0700459
Andreas Huber20111aa2009-07-14 16:56:47 -0700460 mPositionTimeRealUs =
Eric Laurentb48aea12012-05-04 12:55:27 -0700461 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
Andreas Huber00242452009-07-28 10:03:13 -0700462 / mSampleRate;
Andreas Huberdae04ca2009-11-05 16:34:39 -0800463
Steve Block3856b092011-10-20 11:56:00 +0100464 ALOGV("buffer->size() = %d, "
Andreas Huberdae04ca2009-11-05 16:34:39 -0800465 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
466 mInputBuffer->range_length(),
467 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
Andreas Huber20111aa2009-07-14 16:56:47 -0700468 }
469
470 if (mInputBuffer->range_length() == 0) {
471 mInputBuffer->release();
472 mInputBuffer = NULL;
473
474 continue;
475 }
476
477 size_t copy = size_remaining;
478 if (copy > mInputBuffer->range_length()) {
479 copy = mInputBuffer->range_length();
480 }
481
482 memcpy((char *)data + size_done,
483 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
484 copy);
485
486 mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
487 mInputBuffer->range_length() - copy);
Andreas Huberfc9ba092010-01-11 15:35:19 -0800488
Andreas Huber20111aa2009-07-14 16:56:47 -0700489 size_done += copy;
490 size_remaining -= copy;
491 }
492
Andreas Huberbd7b7172011-04-04 09:12:56 -0700493 {
494 Mutex::Autolock autoLock(mLock);
495 mNumFramesPlayed += size_done / mFrameSize;
Andreas Hubere4451a92012-05-14 15:55:48 -0700496 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
Andreas Hubera99a5bc2012-05-15 15:57:59 -0700497
498 if (mReachedEOS) {
499 mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
500 } else {
501 mPinnedTimeUs = -1ll;
502 }
Andreas Huberbd7b7172011-04-04 09:12:56 -0700503 }
504
505 if (postEOS) {
506 mObserver->postAudioEOS(postEOSDelayUs);
507 }
508
509 if (postSeekComplete) {
510 mObserver->postAudioSeekComplete();
511 }
Andreas Huber7d5b8a72010-02-09 16:59:18 -0800512
513 return size_done;
Andreas Huber20111aa2009-07-14 16:56:47 -0700514}
515
516int64_t AudioPlayer::getRealTimeUs() {
517 Mutex::Autolock autoLock(mLock);
518 return getRealTimeUsLocked();
519}
520
521int64_t AudioPlayer::getRealTimeUsLocked() const {
Andreas Huberf7eade92011-09-08 11:33:47 -0700522 CHECK(mStarted);
523 CHECK_NE(mSampleRate, 0);
Andreas Hubere4451a92012-05-14 15:55:48 -0700524 int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
525
526 // Compensate for large audio buffers, updates of mNumFramesPlayed
527 // are less frequent, therefore to get a "smoother" notion of time we
528 // compensate using system time.
Andreas Hubera99a5bc2012-05-15 15:57:59 -0700529 int64_t diffUs;
530 if (mPinnedTimeUs >= 0ll) {
531 diffUs = mPinnedTimeUs;
532 } else {
533 diffUs = ALooper::GetNowUs();
534 }
535
536 diffUs -= mNumFramesPlayedSysTimeUs;
Andreas Hubere4451a92012-05-14 15:55:48 -0700537
538 return result + diffUs;
Andreas Huber20111aa2009-07-14 16:56:47 -0700539}
540
541int64_t AudioPlayer::getMediaTimeUs() {
542 Mutex::Autolock autoLock(mLock);
543
Andreas Huberad6516d2010-02-03 10:23:26 -0800544 if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
Andreas Huberfe9b7192011-03-25 16:36:13 -0700545 if (mSeeking) {
546 return mSeekTimeUs;
547 }
548
Andreas Huberad6516d2010-02-03 10:23:26 -0800549 return 0;
550 }
551
Andreas Huber80a68de2010-02-03 15:35:59 -0800552 int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
553 if (realTimeOffset < 0) {
554 realTimeOffset = 0;
555 }
556
557 return mPositionTimeMediaUs + realTimeOffset;
Andreas Huber20111aa2009-07-14 16:56:47 -0700558}
559
560bool AudioPlayer::getMediaTimeMapping(
561 int64_t *realtime_us, int64_t *mediatime_us) {
562 Mutex::Autolock autoLock(mLock);
563
564 *realtime_us = mPositionTimeRealUs;
565 *mediatime_us = mPositionTimeMediaUs;
566
Andreas Huberad6516d2010-02-03 10:23:26 -0800567 return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
Andreas Huber20111aa2009-07-14 16:56:47 -0700568}
569
570status_t AudioPlayer::seekTo(int64_t time_us) {
571 Mutex::Autolock autoLock(mLock);
572
573 mSeeking = true;
Andreas Huberfe9b7192011-03-25 16:36:13 -0700574 mPositionTimeRealUs = mPositionTimeMediaUs = -1;
Andreas Huber1862a332010-02-03 11:37:29 -0800575 mReachedEOS = false;
Andreas Huber20111aa2009-07-14 16:56:47 -0700576 mSeekTimeUs = time_us;
577
James Dong6c375492011-09-27 22:47:25 -0700578 // Flush resets the number of played frames
579 mNumFramesPlayed = 0;
Andreas Hubere4451a92012-05-14 15:55:48 -0700580 mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
James Dong6c375492011-09-27 22:47:25 -0700581
Andreas Huberc7d368d2010-09-28 13:13:38 -0700582 if (mAudioSink != NULL) {
583 mAudioSink->flush();
584 } else {
585 mAudioTrack->flush();
586 }
587
Andreas Huber20111aa2009-07-14 16:56:47 -0700588 return OK;
589}
590
591}