AudioPlayer.cpp revision e7d0c712f1c9fa0b0e413b8eb729049995290aee
1bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber/* 2bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 4bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * you may not use this file except in compliance with the License. 6bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * You may obtain a copy of the License at 7bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 8bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 10bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Unless required by applicable law or agreed to in writing, software 11bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * See the License for the specific language governing permissions and 14bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * limitations under the License. 15bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber */ 16bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 17bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//#define LOG_NDEBUG 0 18bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#define LOG_TAG "AudioPlayer" 19bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <utils/Log.h> 20bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 21bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <binder/IPCThreadState.h> 22bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/AudioTrack.h> 23bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/AudioPlayer.h> 25bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/MediaDefs.h> 26bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/MediaErrors.h> 27bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/MediaSource.h> 28bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/MetaData.h> 29bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 30bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include "include/AwesomePlayer.h" 31bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 32bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubernamespace android { 33bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 34bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberAudioPlayer::AudioPlayer( 35bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<MediaPlayerBase::AudioSink> &audioSink, 36bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AwesomePlayer *observer) 37bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber : mAudioTrack(NULL), 38bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer(NULL), 39bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSampleRate(0), 40bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mLatencyUs(0), 41bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFrameSize(0), 42bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNumFramesPlayed(0), 43bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeMediaUs(-1), 44bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeRealUs(-1), 45bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSeeking(false), 46bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mReachedEOS(false), 47bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFinalStatus(OK), 48bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mStarted(false), 49bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mIsFirstBuffer(false), 50bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBufferResult(OK), 51bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer(NULL), 52bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink(audioSink), 53bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mObserver(observer) { 54bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 55bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 56bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberAudioPlayer::~AudioPlayer() { 57bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mStarted) { 58bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber reset(); 59bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 60bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 61bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 62bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::setSource(const sp<MediaSource> &source) { 63bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mSource == NULL); 64bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSource = source; 65bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 66bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 67bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t AudioPlayer::start(bool sourceAlreadyStarted) { 68bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(!mStarted); 69bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mSource != NULL); 70bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 71bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err; 72bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!sourceAlreadyStarted) { 73bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mSource->start(); 74bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 75bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 76bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 77bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 78bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 79bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 80bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // We allow an optional INFO_FORMAT_CHANGED at the very beginning 81bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // of playback, if there is one, getFormat below will retrieve the 82bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // updated format, if there isn't, we'll stash away the valid buffer 83bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // of data to be used on the first audio callback. 84bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 85bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(mFirstBuffer == NULL); 86bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 87bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber MediaSource::ReadOptions options; 88bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mSeeking) { 89bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber options.setSeekTo(mSeekTimeUs); 90bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSeeking = false; 91bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 92bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 93bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBufferResult = mSource->read(&mFirstBuffer, &options); 94bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 95bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGV("INFO_FORMAT_CHANGED!!!"); 96bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 9790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mFirstBuffer == NULL); 98bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBufferResult = OK; 9990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mIsFirstBuffer = false; 10090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } else { 10190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mIsFirstBuffer = true; 102bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 103bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<MetaData> format = mSource->getFormat(); 105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *mime; 106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool success = format->findCString(kKeyMIMEType, &mime); 107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(success); 108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber success = format->findInt32(kKeySampleRate, &mSampleRate); 111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(success); 112bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 113bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t numChannels, channelMask; 114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber success = format->findInt32(kKeyChannelCount, &numChannels); 115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(success); 116bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if(!format->findInt32(kKeyChannelMask, &channelMask)) { 118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGW("source format didn't specify channel mask, using channel order"); 119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 120bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 121bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 122bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink.get() != NULL) { 123bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = mAudioSink->open( 124bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT, 125bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber DEFAULT_AUDIOSINK_BUFFERCOUNT, 126bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber &AudioPlayer::AudioSinkCallback, this); 127bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 128bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mFirstBuffer != NULL) { 129bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer->release(); 130bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer = NULL; 131bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 132bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 133bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!sourceAlreadyStarted) { 134bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mSource->stop(); 135bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 136bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 137bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 138bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 139bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 140bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 141bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFrameSize = mAudioSink->frameSize(); 142bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 143bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink->start(); 144bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 145bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // playing to an AudioTrack, set up mask if necessary 146bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ? 147bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber audio_channel_mask_from_count(numChannels) : channelMask; 148bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (0 == audioMask) { 149bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return BAD_VALUE; 150bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 151bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 152bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack = new AudioTrack( 153bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask, 154bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0, 0, &AudioCallback, this, 0); 155bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 156bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if ((err = mAudioTrack->initCheck()) != OK) { 157bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber delete mAudioTrack; 158bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack = NULL; 159bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 160bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mFirstBuffer != NULL) { 161bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer->release(); 162bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer = NULL; 163bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 164bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 165bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (!sourceAlreadyStarted) { 166bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSource->stop(); 167bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 168bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 169bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 170bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 171bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 172bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 173bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFrameSize = mAudioTrack->frameSize(); 174bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 175bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack->start(); 176bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 177bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 178bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mStarted = true; 179bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 180bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 181bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 18296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 183bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::pause(bool playPendingSamples) { 184bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mStarted); 185bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 186bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (playPendingSamples) { 187bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink.get() != NULL) { 188bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink->stop(); 189bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 190bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack->stop(); 191bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 192bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 193bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNumFramesPlayed = 0; 194bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 195bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink.get() != NULL) { 196bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mAudioSink->pause(); 197bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 198bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mAudioTrack->pause(); 199bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 200bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 201bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 202bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 203bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::resume() { 204bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(mStarted); 205bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 206bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mAudioSink.get() != NULL) { 207bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mAudioSink->start(); 208bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 209bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mAudioTrack->start(); 210bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 211bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 212bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 213bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::reset() { 214bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mStarted); 215bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 216bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink.get() != NULL) { 217bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink->stop(); 218bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink->close(); 21990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } else { 22090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mAudioTrack->stop(); 221bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 222bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber delete mAudioTrack; 223bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack = NULL; 224bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 225bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 226bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Make sure to release any buffer we hold onto so that the 227bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // source is able to stop(). 228bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 229bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mFirstBuffer != NULL) { 230bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer->release(); 231bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFirstBuffer = NULL; 232bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 233bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 234bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mInputBuffer != NULL) { 235bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGV("AudioPlayer releasing input buffer."); 236bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 237bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer->release(); 238bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer = NULL; 239bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 240bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 241bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSource->stop(); 242bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 243bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // The following hack is necessary to ensure that the OMX 244bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // component is completely released by the time we may try 245bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // to instantiate it again. 246bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber wp<MediaSource> tmp = mSource; 247bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSource.clear(); 248bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (tmp.promote() != NULL) { 249bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber usleep(1000); 250bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 251bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber IPCThreadState::self()->flushCommands(); 252bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 253bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNumFramesPlayed = 0; 254bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeMediaUs = -1; 255bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeRealUs = -1; 256bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSeeking = false; 257bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mReachedEOS = false; 258bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFinalStatus = OK; 259bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mStarted = false; 260bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 261bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 262bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 263bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::AudioCallback(int event, void *user, void *info) { 264bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber static_cast<AudioPlayer *>(user)->AudioCallback(event, info); 265bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 266bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 267bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool AudioPlayer::isSeeking() { 268bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 269bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mSeeking; 270bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 271bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 272bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool AudioPlayer::reachedEOS(status_t *finalStatus) { 273bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *finalStatus = OK; 274bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 275bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 276bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *finalStatus = mFinalStatus; 277bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mReachedEOS; 278bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 279bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 280bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) { 281bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink.get() != NULL) { 282bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mAudioSink->setPlaybackRatePermille(ratePermille); 283bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (mAudioTrack != NULL){ 284bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000); 285bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 286bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return NO_INIT; 287bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 288bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 289bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 290bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 291bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubersize_t AudioPlayer::AudioSinkCallback( 292bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber MediaPlayerBase::AudioSink *audioSink, 293bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber void *buffer, size_t size, void *cookie) { 294bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AudioPlayer *me = (AudioPlayer *)cookie; 295bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 296bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return me->fillBuffer(buffer, size); 297bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 298bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 299bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid AudioPlayer::AudioCallback(int event, void *info) { 300bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (event != AudioTrack::EVENT_MORE_DATA) { 301bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 302bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 303bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 304bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 305bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 306bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 307bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber buffer->size = numBytesWritten; 308bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 309bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 310bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberuint32_t AudioPlayer::getNumFramesPendingPlayout() const { 311bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber uint32_t numFramesPlayedOut; 312bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err; 313bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 314bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mAudioSink != NULL) { 315bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mAudioSink->getPosition(&numFramesPlayedOut); 316bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 317bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = mAudioTrack->getPosition(&numFramesPlayedOut); 318bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 319bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 320bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (err != OK || mNumFramesPlayed < numFramesPlayedOut) { 321bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return 0; 322bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 323bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 324bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // mNumFramesPlayed is the number of frames submitted 325bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // to the audio sink for playback, but not all of them 326bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // may have played out by now. 327bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mNumFramesPlayed - numFramesPlayedOut; 328bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 329bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 330bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Hubersize_t AudioPlayer::fillBuffer(void *data, size_t size) { 331bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mNumFramesPlayed == 0) { 332bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGV("AudioCallback"); 333bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 334bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 335bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mReachedEOS) { 336bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return 0; 337bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 338bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 339bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool postSeekComplete = false; 340bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber bool postEOS = false; 341bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int64_t postEOSDelayUs = 0; 342bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 343bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber size_t size_done = 0; 344bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t size_remaining = size; 345bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber while (size_remaining > 0) { 346bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber MediaSource::ReadOptions options; 347bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 348bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber Mutex::Autolock autoLock(mLock); 350bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 351bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mSeeking) { 352bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mIsFirstBuffer) { 353bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mFirstBuffer != NULL) { 354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mFirstBuffer->release(); 355bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mFirstBuffer = NULL; 356bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 357bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mIsFirstBuffer = false; 358bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 359bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 360bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber options.setSeekTo(mSeekTimeUs); 361bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 362bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInputBuffer != NULL) { 363bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInputBuffer->release(); 364bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInputBuffer = NULL; 365bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 366bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 367bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mSeeking = false; 368bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mObserver) { 369bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber postSeekComplete = true; 370bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 371bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 372bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 373bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 374bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInputBuffer == NULL) { 375bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber status_t err; 376bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 377bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mIsFirstBuffer) { 378bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInputBuffer = mFirstBuffer; 379bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mFirstBuffer = NULL; 380bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mFirstBufferResult; 381bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 382bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mIsFirstBuffer = false; 383bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 384bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = mSource->read(&mInputBuffer, &options); 385bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 386bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 387bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK((err == OK && mInputBuffer != NULL) 388bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || (err != OK && mInputBuffer == NULL)); 389bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 390bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber Mutex::Autolock autoLock(mLock); 391bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 392bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 393bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mObserver && !mReachedEOS) { 394bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // We don't want to post EOS right away but only 395bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // after all frames have actually been played out. 396bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 397bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // These are the number of frames submitted to the 398bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // AudioTrack that you haven't heard yet. 399bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber uint32_t numFramesPendingPlayout = 400bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber getNumFramesPendingPlayout(); 401bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 402bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // These are the number of frames we're going to 403bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // submit to the AudioTrack by returning from this 40490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // callback. 405bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber uint32_t numAdditionalFrames = size_done / mFrameSize; 406bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 407bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber numFramesPendingPlayout += numAdditionalFrames; 40890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 409bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int64_t timeToCompletionUs = 410bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (1000000ll * numFramesPendingPlayout) / mSampleRate; 411bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 41290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ALOGV("total number of frames played: %lld (%lld us)", 413bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (mNumFramesPlayed + numAdditionalFrames), 414bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1000000ll * (mNumFramesPlayed + numAdditionalFrames) 415bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber / mSampleRate); 416bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 417bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGV("%d frames left to play, %lld us (%.2f secs)", 41890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber numFramesPendingPlayout, 419bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber timeToCompletionUs, timeToCompletionUs / 1E6); 420bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 421bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber postEOS = true; 422bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber postEOSDelayUs = timeToCompletionUs + mLatencyUs; 423bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 42490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 425bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mReachedEOS = true; 426bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mFinalStatus = err; 427bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 428bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 429bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 430bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink != NULL) { 431bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 432bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 433bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 434bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 435bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 436bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mInputBuffer->meta_data()->findInt64( 437bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kKeyTime, &mPositionTimeMediaUs)); 438bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 439bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeRealUs = 440bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber -mLatencyUs + ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 441bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber / mSampleRate; 442bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mPositionTimeRealUs < 0) { 443bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeRealUs = 0; 444bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 445bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 446bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGV("buffer->size() = %d, " 447bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 448bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInputBuffer->range_length(), 449bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 450bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 451bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 452bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mInputBuffer->range_length() == 0) { 453bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer->release(); 454bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer = NULL; 455bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 456bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 457bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 458bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 459bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_t copy = size_remaining; 460bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (copy > mInputBuffer->range_length()) { 461bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber copy = mInputBuffer->range_length(); 462bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 463bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 464bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memcpy((char *)data + size_done, 465bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 466bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber copy); 467bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 46872f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 469bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInputBuffer->range_length() - copy); 470bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 47172f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber size_done += copy; 472bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber size_remaining -= copy; 473bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 474bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 475bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber { 476bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 477bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNumFramesPlayed += size_done / mFrameSize; 478bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 479bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 480bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (postEOS) { 481bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mObserver->postAudioEOS(postEOSDelayUs); 482bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 483bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 484bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (postSeekComplete) { 485bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mObserver->postAudioSeekComplete(); 486bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 487bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 488bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return size_done; 489bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 490bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 49190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberint64_t AudioPlayer::getRealTimeUs() { 49290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber Mutex::Autolock autoLock(mLock); 49390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return getRealTimeUsLocked(); 49490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 49590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 49690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberint64_t AudioPlayer::getRealTimeUsLocked() const { 49790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mStarted); 49890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_NE(mSampleRate, 0); 49990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int64_t t = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate; 50090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (t < 0) return 0; 501bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return t; 502bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 503bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 504bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberint64_t AudioPlayer::getMediaTimeUs() { 505bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber Mutex::Autolock autoLock(mLock); 506bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 507bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) { 508bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mSeeking) { 509bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mSeekTimeUs; 510bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 511bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 512bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return 0; 513bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 514bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 515bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 516bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (realTimeOffset < 0) { 517bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber realTimeOffset = 0; 518bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 519bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 520bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mPositionTimeMediaUs + realTimeOffset; 521bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 522bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 523bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool AudioPlayer::getMediaTimeMapping( 524bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int64_t *realtime_us, int64_t *mediatime_us) { 525bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 526bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 527bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *realtime_us = mPositionTimeRealUs; 528bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *mediatime_us = mPositionTimeMediaUs; 529bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 530bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1; 531bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 532bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 533bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t AudioPlayer::seekTo(int64_t time_us) { 534bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 535bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 536bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSeeking = true; 537bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPositionTimeRealUs = mPositionTimeMediaUs = -1; 538bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mReachedEOS = false; 539bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSeekTimeUs = time_us; 540bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 541bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // Flush resets the number of played frames 542bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNumFramesPlayed = 0; 543bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 544bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mAudioSink != NULL) { 545bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioSink->flush(); 546bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 547bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mAudioTrack->flush(); 548bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 549bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 550bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 551bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 552bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 553bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 554bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber