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