1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/* 2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License. 6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at 7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * 10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software 11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and 14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License. 15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */ 16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 17c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber//#define LOG_NDEBUG 0 18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define LOG_TAG "AudioPlayer" 19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/Log.h> 20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 215f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber#include <binder/IPCThreadState.h> 22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/AudioTrack.h> 2384584471624775a849c880a50efc351e47c4a4afAndreas Huber#include <media/stagefright/foundation/ADebug.h> 24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/AudioPlayer.h> 25e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h> 2616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber#include <media/stagefright/MediaErrors.h> 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 302b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber#include "include/AwesomePlayer.h" 312b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber 32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 342b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas HuberAudioPlayer::AudioPlayer( 352b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber const sp<MediaPlayerBase::AudioSink> &audioSink, 362b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber AwesomePlayer *observer) 37be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber : mAudioTrack(NULL), 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer(NULL), 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleRate(0), 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLatencyUs(0), 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFrameSize(0), 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mNumFramesPlayed(0), 43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mPositionTimeMediaUs(-1), 44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mPositionTimeRealUs(-1), 45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSeeking(false), 4670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber mReachedEOS(false), 47d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber mFinalStatus(OK), 48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 4916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mIsFirstBuffer(false), 5016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBufferResult(OK), 5116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer(NULL), 522b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber mAudioSink(audioSink), 532b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber mObserver(observer) { 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 56e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberAudioPlayer::~AudioPlayer() { 57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 58c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber reset(); 59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 62be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubervoid AudioPlayer::setSource(const sp<MediaSource> &source) { 6384584471624775a849c880a50efc351e47c4a4afAndreas Huber CHECK(mSource == NULL); 64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSource = source; 65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 67dc9927d4641066fc966c9c69856167b8410abf90Andreas Huberstatus_t AudioPlayer::start(bool sourceAlreadyStarted) { 68b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(!mStarted); 69b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mSource != NULL); 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 71dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber status_t err; 72dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber if (!sourceAlreadyStarted) { 73dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber err = mSource->start(); 7462eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber 75dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber if (err != OK) { 76dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber return err; 77dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber } 7862eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber } 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber // We allow an optional INFO_FORMAT_CHANGED at the very beginning 8116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber // of playback, if there is one, getFormat below will retrieve the 8216263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber // updated format, if there isn't, we'll stash away the valid buffer 8316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber // of data to be used on the first audio callback. 8416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 8516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber CHECK(mFirstBuffer == NULL); 8616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 875fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber MediaSource::ReadOptions options; 885fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber if (mSeeking) { 895fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber options.setSeekTo(mSeekTimeUs); 905fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber mSeeking = false; 915fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber } 925fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber 935fd43e30516e490edb11ae3ad0795f069811dd7dAndreas Huber mFirstBufferResult = mSource->read(&mFirstBuffer, &options); 9416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 9516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber LOGV("INFO_FORMAT_CHANGED!!!"); 9616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 9716263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber CHECK(mFirstBuffer == NULL); 9816263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBufferResult = OK; 9916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mIsFirstBuffer = false; 10016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } else { 10116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mIsFirstBuffer = true; 10216263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 10316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber sp<MetaData> format = mSource->getFormat(); 105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = format->findCString(kKeyMIMEType, &mime); 107b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(success); 108e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber success = format->findInt32(kKeySampleRate, &mSampleRate); 111b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(success); 112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t numChannels; 114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber success = format->findInt32(kKeyChannelCount, &numChannels); 115b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(success); 116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mAudioSink.get() != NULL) { 118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mAudioSink->open( 11924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT, 120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber DEFAULT_AUDIOSINK_BUFFERCOUNT, 121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber &AudioPlayer::AudioSinkCallback, this); 12262eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber if (err != OK) { 12316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mFirstBuffer != NULL) { 12416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer->release(); 12516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer = NULL; 12616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 12716263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 12816263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (!sourceAlreadyStarted) { 12916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mSource->stop(); 13016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 13162eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber 13262eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber return err; 13362eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber } 134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFrameSize = mAudioSink->frameSize(); 137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioSink->start(); 139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioTrack = new AudioTrack( 14124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, 1428a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber (numChannels == 2) 14324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin ? AUDIO_CHANNEL_OUT_STEREO 14424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin : AUDIO_CHANNEL_OUT_MONO, 145662292ae2d4f50990d3f2a944b9d9059775b3cc0Andreas Huber 0, 0, &AudioCallback, this, 0); 146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1473cbd62c3cebf0c0c62a50ccc736ac4caa3a4bf64Kenny Root if ((err = mAudioTrack->initCheck()) != OK) { 14862eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber delete mAudioTrack; 14962eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber mAudioTrack = NULL; 15062eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber 15116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mFirstBuffer != NULL) { 15216263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer->release(); 15316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer = NULL; 15416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 15516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 15616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (!sourceAlreadyStarted) { 15716263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mSource->stop(); 15816263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 15962eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber 1603cbd62c3cebf0c0c62a50ccc736ac4caa3a4bf64Kenny Root return err; 16162eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber } 162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFrameSize = mAudioTrack->frameSize(); 165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioTrack->start(); 167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 17062eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber 17162eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber return OK; 172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 174c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Hubervoid AudioPlayer::pause(bool playPendingSamples) { 175b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mStarted); 176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 177c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber if (playPendingSamples) { 178c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber if (mAudioSink.get() != NULL) { 179c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber mAudioSink->stop(); 180c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber } else { 181c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber mAudioTrack->stop(); 182c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber } 1839ba16f6c5485d5384ed38df63c7d23e3d20e8d31Andreas Huber 1849ba16f6c5485d5384ed38df63c7d23e3d20e8d31Andreas Huber mNumFramesPlayed = 0; 185e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 186c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber if (mAudioSink.get() != NULL) { 187c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber mAudioSink->pause(); 188c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber } else { 189c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber mAudioTrack->pause(); 190c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber } 191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid AudioPlayer::resume() { 195b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mStarted); 196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mAudioSink.get() != NULL) { 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioSink->start(); 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioTrack->start(); 201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 204c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Hubervoid AudioPlayer::reset() { 205b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK(mStarted); 206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mAudioSink.get() != NULL) { 208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioSink->stop(); 209aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber mAudioSink->close(); 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioTrack->stop(); 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mAudioTrack; 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mAudioTrack = NULL; 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 216aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Make sure to release any buffer we hold onto so that the 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // source is able to stop(). 21916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 22016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mFirstBuffer != NULL) { 22116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer->release(); 22216263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer = NULL; 22316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 22416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mInputBuffer != NULL) { 226c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber LOGV("AudioPlayer releasing input buffer."); 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer->release(); 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer = NULL; 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSource->stop(); 233aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 2345f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber // The following hack is necessary to ensure that the OMX 2355f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber // component is completely released by the time we may try 2365f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber // to instantiate it again. 2375f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber wp<MediaSource> tmp = mSource; 2385f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber mSource.clear(); 2395f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber while (tmp.promote() != NULL) { 2405f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber usleep(1000); 2415f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber } 2425f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber IPCThreadState::self()->flushCommands(); 2435f0d5ce38a4f01ca986e6fe514c57a17b83dd841Andreas Huber 244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mNumFramesPlayed = 0; 245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mPositionTimeMediaUs = -1; 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mPositionTimeRealUs = -1; 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSeeking = false; 24870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber mReachedEOS = false; 249d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber mFinalStatus = OK; 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber// static 254e46a86fcb6a0849fc05c4cade6cb94aad0325295Glenn Kastenvoid AudioPlayer::AudioCallback(int event, void *user, void *info) { 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 256e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 25870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huberbool AudioPlayer::isSeeking() { 25970d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber Mutex::Autolock autoLock(mLock); 26070d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber return mSeeking; 26170d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber} 26270d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber 263d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huberbool AudioPlayer::reachedEOS(status_t *finalStatus) { 264d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber *finalStatus = OK; 265d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber 26670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber Mutex::Autolock autoLock(mLock); 267d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber *finalStatus = mFinalStatus; 26870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber return mReachedEOS; 26970d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber} 27070d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber// static 2726ed937ebe99088b5671a645060340a558b02fefbAndreas Hubersize_t AudioPlayer::AudioSinkCallback( 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaPlayerBase::AudioSink *audioSink, 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber void *buffer, size_t size, void *cookie) { 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber AudioPlayer *me = (AudioPlayer *)cookie; 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2776ed937ebe99088b5671a645060340a558b02fefbAndreas Huber return me->fillBuffer(buffer, size); 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 280e46a86fcb6a0849fc05c4cade6cb94aad0325295Glenn Kastenvoid AudioPlayer::AudioCallback(int event, void *info) { 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (event != AudioTrack::EVENT_MORE_DATA) { 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return; 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 2866ed937ebe99088b5671a645060340a558b02fefbAndreas Huber size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 2876ed937ebe99088b5671a645060340a558b02fefbAndreas Huber 2886ed937ebe99088b5671a645060340a558b02fefbAndreas Huber buffer->size = numBytesWritten; 289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 290e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 2914dc482daac5d484f338865cdddd57528276a7ca0Andreas Huberuint32_t AudioPlayer::getNumFramesPendingPlayout() const { 2924dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber uint32_t numFramesPlayedOut; 2934dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber status_t err; 2944dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 2954dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber if (mAudioSink != NULL) { 2964dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber err = mAudioSink->getPosition(&numFramesPlayedOut); 2974dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber } else { 2984dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber err = mAudioTrack->getPosition(&numFramesPlayedOut); 2994dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber } 3004dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3014dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 3024dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber return 0; 3034dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber } 3044dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3054dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // mNumFramesPlayed is the number of frames submitted 3064dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // to the audio sink for playback, but not all of them 3074dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // may have played out by now. 3084dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber return mNumFramesPlayed - numFramesPlayedOut; 3094dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber} 3104dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3116ed937ebe99088b5671a645060340a558b02fefbAndreas Hubersize_t AudioPlayer::fillBuffer(void *data, size_t size) { 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mNumFramesPlayed == 0) { 313c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber LOGV("AudioCallback"); 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 31670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber if (mReachedEOS) { 317c6e3b27fa1c2bf9863dcf017019c976ec98bce42Andreas Huber return 0; 31870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber } 31970d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber 3208e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber bool postSeekComplete = false; 3218e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber bool postEOS = false; 3228e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber int64_t postEOSDelayUs = 0; 3238e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber 324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t size_done = 0; 325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t size_remaining = size; 326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (size_remaining > 0) { 327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaSource::ReadOptions options; 328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Mutex::Autolock autoLock(mLock); 331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mSeeking) { 33316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mIsFirstBuffer) { 33416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mFirstBuffer != NULL) { 33516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer->release(); 33616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer = NULL; 33716263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 33816263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mIsFirstBuffer = false; 33916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 34016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber options.setSeekTo(mSeekTimeUs); 342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mInputBuffer != NULL) { 344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer->release(); 345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer = NULL; 346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 3472b7bb21a5c96caf16b8a13691fd7c3971ff3c7bdGloria Wang 3482b7bb21a5c96caf16b8a13691fd7c3971ff3c7bdGloria Wang mSeeking = false; 3492b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber if (mObserver) { 3508e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber postSeekComplete = true; 3512b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber } 352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mInputBuffer == NULL) { 35616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber status_t err; 35716263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 35816263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber if (mIsFirstBuffer) { 35916263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mInputBuffer = mFirstBuffer; 36016263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mFirstBuffer = NULL; 36116263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber err = mFirstBufferResult; 36216263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber 36316263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber mIsFirstBuffer = false; 36416263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } else { 36516263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber err = mSource->read(&mInputBuffer, &options); 36616263d9f8cc01392c2f3678b381ce897647c8c81Andreas Huber } 367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 368b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber CHECK((err == OK && mInputBuffer != NULL) 369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber || (err != OK && mInputBuffer == NULL)); 370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 37170d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber Mutex::Autolock autoLock(mLock); 37227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber 373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 3742b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber if (mObserver && !mReachedEOS) { 3754dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // We don't want to post EOS right away but only 3764dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // after all frames have actually been played out. 3774dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3784dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // These are the number of frames submitted to the 3794dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // AudioTrack that you haven't heard yet. 3804dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber uint32_t numFramesPendingPlayout = 3814dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber getNumFramesPendingPlayout(); 3824dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3834dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // These are the number of frames we're going to 3844dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // submit to the AudioTrack by returning from this 3854dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber // callback. 3864dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber uint32_t numAdditionalFrames = size_done / mFrameSize; 3874dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3884dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber numFramesPendingPlayout += numAdditionalFrames; 3894dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3904dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber int64_t timeToCompletionUs = 3914dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber (1000000ll * numFramesPendingPlayout) / mSampleRate; 3924dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3934dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber LOGV("total number of frames played: %lld (%lld us)", 3944dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber (mNumFramesPlayed + numAdditionalFrames), 3954dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 3964dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber / mSampleRate); 3974dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 3984dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber LOGV("%d frames left to play, %lld us (%.2f secs)", 3994dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber numFramesPendingPlayout, 4004dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber timeToCompletionUs, timeToCompletionUs / 1E6); 4014dc482daac5d484f338865cdddd57528276a7ca0Andreas Huber 4028e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber postEOS = true; 4038e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber postEOSDelayUs = timeToCompletionUs + mLatencyUs; 4042b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber } 4052b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber 40670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber mReachedEOS = true; 407d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber mFinalStatus = err; 408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 411fa8de752507feaca695123911915070c1ce463b2Andreas Huber CHECK(mInputBuffer->meta_data()->findInt64( 412fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, &mPositionTimeMediaUs)); 4138a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 414e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mPositionTimeRealUs = 415065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 4168a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber / mSampleRate; 417c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber 418c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber LOGV("buffer->size() = %d, " 419c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 420c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber mInputBuffer->range_length(), 421c997acacd54e30293920a7e2bda80a3d9a7d76c6Andreas Huber mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mInputBuffer->range_length() == 0) { 425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer->release(); 426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer = NULL; 427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber continue; 429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t copy = size_remaining; 432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (copy > mInputBuffer->range_length()) { 433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber copy = mInputBuffer->range_length(); 434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber memcpy((char *)data + size_done, 437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber copy); 439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mInputBuffer->range_length() - copy); 442aee3c6394a367abf283936cb8b8bd85ed028c050Andreas Huber 443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_done += copy; 444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_remaining -= copy; 445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 4478e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber { 4488e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber Mutex::Autolock autoLock(mLock); 4498e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber mNumFramesPlayed += size_done / mFrameSize; 4508e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber } 4518e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber 4528e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber if (postEOS) { 4538e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber mObserver->postAudioEOS(postEOSDelayUs); 4548e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber } 4558e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber 4568e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber if (postSeekComplete) { 4578e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber mObserver->postAudioSeekComplete(); 4588e64c31f6c7aca87197976ee5e1b3359507e5e0fAndreas Huber } 4596ed937ebe99088b5671a645060340a558b02fefbAndreas Huber 4606ed937ebe99088b5671a645060340a558b02fefbAndreas Huber return size_done; 461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberint64_t AudioPlayer::getRealTimeUs() { 464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Mutex::Autolock autoLock(mLock); 465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return getRealTimeUsLocked(); 466e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberint64_t AudioPlayer::getRealTimeUsLocked() const { 46984584471624775a849c880a50efc351e47c4a4afAndreas Huber CHECK(mStarted); 47084584471624775a849c880a50efc351e47c4a4afAndreas Huber CHECK_NE(mSampleRate, 0); 471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberint64_t AudioPlayer::getMediaTimeUs() { 475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Mutex::Autolock autoLock(mLock); 476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 477c119f7ea23d7cffc5dcac49ec4c41a0c68290549Andreas Huber if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 47859529e1474a5e696e83955ccf0876992299bc86fAndreas Huber if (mSeeking) { 47959529e1474a5e696e83955ccf0876992299bc86fAndreas Huber return mSeekTimeUs; 48059529e1474a5e696e83955ccf0876992299bc86fAndreas Huber } 48159529e1474a5e696e83955ccf0876992299bc86fAndreas Huber 482c119f7ea23d7cffc5dcac49ec4c41a0c68290549Andreas Huber return 0; 483c119f7ea23d7cffc5dcac49ec4c41a0c68290549Andreas Huber } 484c119f7ea23d7cffc5dcac49ec4c41a0c68290549Andreas Huber 485065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 486065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber if (realTimeOffset < 0) { 487065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber realTimeOffset = 0; 488065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber } 489065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber 490065f69ef53f88bd0dcdb36e543c9d1cae1d6b628Andreas Huber return mPositionTimeMediaUs + realTimeOffset; 491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberbool AudioPlayer::getMediaTimeMapping( 494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t *realtime_us, int64_t *mediatime_us) { 495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Mutex::Autolock autoLock(mLock); 496e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 497e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *realtime_us = mPositionTimeRealUs; 498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *mediatime_us = mPositionTimeMediaUs; 499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 500c119f7ea23d7cffc5dcac49ec4c41a0c68290549Andreas Huber return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t AudioPlayer::seekTo(int64_t time_us) { 504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Mutex::Autolock autoLock(mLock); 505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 506e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSeeking = true; 50759529e1474a5e696e83955ccf0876992299bc86fAndreas Huber mPositionTimeRealUs = mPositionTimeMediaUs = -1; 50870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber mReachedEOS = false; 509e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSeekTimeUs = time_us; 510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 511dbf85120b8ca5e2bdc64f4085e9d6a036ac2ce5eJames Dong // Flush resets the number of played frames 512dbf85120b8ca5e2bdc64f4085e9d6a036ac2ce5eJames Dong mNumFramesPlayed = 0; 513dbf85120b8ca5e2bdc64f4085e9d6a036ac2ce5eJames Dong 514ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber if (mAudioSink != NULL) { 515ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber mAudioSink->flush(); 516ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber } else { 517ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber mAudioTrack->flush(); 518ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber } 519ad3fcfe845163e6fd40e13faf179c6c595963256Andreas Huber 520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 524