120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber//#define LOG_NDEBUG 0
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "AudioPlayer"
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2125155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber#include <binder/IPCThreadState.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/AudioTrack.h>
23f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber#include <media/stagefright/foundation/ALooper.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/AudioPlayer.h>
2618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
273cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber#include <media/stagefright/MediaErrors.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber#include "include/AwesomePlayer.h"
32ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas HuberAudioPlayer::AudioPlayer(
36ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber        const sp<MediaPlayerBase::AudioSink> &audioSink,
371948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent        bool allowDeepBuffering,
38ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber        AwesomePlayer *observer)
39693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    : mAudioTrack(NULL),
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mInputBuffer(NULL),
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleRate(0),
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mLatencyUs(0),
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mFrameSize(0),
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumFramesPlayed(0),
45e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber      mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mPositionTimeMediaUs(-1),
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mPositionTimeRealUs(-1),
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSeeking(false),
491862a33b246249630b654182afb5914da3480d4cAndreas Huber      mReachedEOS(false),
505295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber      mFinalStatus(OK),
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
523cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mIsFirstBuffer(false),
533cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mFirstBufferResult(OK),
543cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mFirstBuffer(NULL),
55ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber      mAudioSink(audioSink),
561948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent      mAllowDeepBuffering(allowDeepBuffering),
57a99a5bca365277271915cbaeea811ad87131270dAndreas Huber      mObserver(observer),
58a99a5bca365277271915cbaeea811ad87131270dAndreas Huber      mPinnedTimeUs(-1ll) {
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberAudioPlayer::~AudioPlayer() {
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
63b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        reset();
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
67693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid AudioPlayer::setSource(const sp<MediaSource> &source) {
68f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK(mSource == NULL);
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSource = source;
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
72e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huberstatus_t AudioPlayer::start(bool sourceAlreadyStarted) {
730c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(!mStarted);
740c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mSource != NULL);
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
76e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber    status_t err;
77e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber    if (!sourceAlreadyStarted) {
78e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        err = mSource->start();
7988c030e0e0152791ff74f90249f55fce01371198Andreas Huber
80e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        if (err != OK) {
81e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber            return err;
82e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        }
8388c030e0e0152791ff74f90249f55fce01371198Andreas Huber    }
8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
853cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // We allow an optional INFO_FORMAT_CHANGED at the very beginning
863cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // of playback, if there is one, getFormat below will retrieve the
873cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // updated format, if there isn't, we'll stash away the valid buffer
883cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // of data to be used on the first audio callback.
893cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
903cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    CHECK(mFirstBuffer == NULL);
913cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
92c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    MediaSource::ReadOptions options;
93c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    if (mSeeking) {
94c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        options.setSeekTo(mSeekTimeUs);
95c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        mSeeking = false;
96c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    }
97c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
98c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
993cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
1003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("INFO_FORMAT_CHANGED!!!");
1013cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
1023cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        CHECK(mFirstBuffer == NULL);
1033cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBufferResult = OK;
1043cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mIsFirstBuffer = false;
1053cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    } else {
1063cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mIsFirstBuffer = true;
1073cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    }
1083cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> format = mSource->getFormat();
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = format->findCString(kKeyMIMEType, &mime);
1120c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
11318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = format->findInt32(kKeySampleRate, &mSampleRate);
1160c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
118786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    int32_t numChannels, channelMask;
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = format->findInt32(kKeyChannelCount, &numChannels);
1200c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
122786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    if(!format->findInt32(kKeyChannelMask, &channelMask)) {
1232c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi        // log only when there's a risk of ambiguity of channel mask selection
1242c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi        ALOGI_IF(numChannels > 2,
1252c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi                "source format didn't specify channel mask, using (%d) channel order", numChannels);
126786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
127786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    }
128786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
1301948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        status_t err = mAudioSink->open(
132786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi                mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT,
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                DEFAULT_AUDIOSINK_BUFFERCOUNT,
1341948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                &AudioPlayer::AudioSinkCallback,
1351948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                this,
1361948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                (mAllowDeepBuffering ?
1371948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            AUDIO_OUTPUT_FLAG_DEEP_BUFFER :
1381948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                            AUDIO_OUTPUT_FLAG_NONE));
13988c030e0e0152791ff74f90249f55fce01371198Andreas Huber        if (err != OK) {
1403cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mFirstBuffer != NULL) {
1413cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer->release();
1423cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
1433cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
1443cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
1454575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            if (!sourceAlreadyStarted) {
1464575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber                mSource->stop();
1474575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            }
14888c030e0e0152791ff74f90249f55fce01371198Andreas Huber
14988c030e0e0152791ff74f90249f55fce01371198Andreas Huber            return err;
15088c030e0e0152791ff74f90249f55fce01371198Andreas Huber        }
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mFrameSize = mAudioSink->frameSize();
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioSink->start();
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
157786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        // playing to an AudioTrack, set up mask if necessary
158786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
159ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten                audio_channel_out_mask_from_count(numChannels) : channelMask;
160786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        if (0 == audioMask) {
161786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi            return BAD_VALUE;
162786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        }
163786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack = new AudioTrack(
165786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi                AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
1660ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent                0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16832dcebf970356eb8599ea965d71535ed0c212c2dKenny Root        if ((err = mAudioTrack->initCheck()) != OK) {
16988c030e0e0152791ff74f90249f55fce01371198Andreas Huber            delete mAudioTrack;
17088c030e0e0152791ff74f90249f55fce01371198Andreas Huber            mAudioTrack = NULL;
17188c030e0e0152791ff74f90249f55fce01371198Andreas Huber
1723cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mFirstBuffer != NULL) {
1733cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer->release();
1743cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
1753cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
1763cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
1774575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            if (!sourceAlreadyStarted) {
1784575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber                mSource->stop();
1794575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            }
18088c030e0e0152791ff74f90249f55fce01371198Andreas Huber
18132dcebf970356eb8599ea965d71535ed0c212c2dKenny Root            return err;
18288c030e0e0152791ff74f90249f55fce01371198Andreas Huber        }
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mFrameSize = mAudioTrack->frameSize();
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack->start();
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
191a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    mPinnedTimeUs = -1ll;
19288c030e0e0152791ff74f90249f55fce01371198Andreas Huber
19388c030e0e0152791ff74f90249f55fce01371198Andreas Huber    return OK;
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
196b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Hubervoid AudioPlayer::pause(bool playPendingSamples) {
1970c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
199b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber    if (playPendingSamples) {
200b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (mAudioSink.get() != NULL) {
201b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioSink->stop();
202b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
203b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioTrack->stop();
204b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
2050b293e76c8fe4e973ccd8a872bc5320ba28d49ccAndreas Huber
2060b293e76c8fe4e973ccd8a872bc5320ba28d49ccAndreas Huber        mNumFramesPlayed = 0;
207e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
209b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (mAudioSink.get() != NULL) {
210b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioSink->pause();
211b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
212b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioTrack->pause();
213b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
214a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
215a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        mPinnedTimeUs = ALooper::GetNowUs();
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid AudioPlayer::resume() {
2200c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioSink->start();
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack->start();
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
229b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Hubervoid AudioPlayer::reset() {
2300c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioSink->stop();
234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mAudioSink->close();
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack->stop();
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete mAudioTrack;
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack = NULL;
24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
241fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Make sure to release any buffer we hold onto so that the
24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // source is able to stop().
2443cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
2453cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    if (mFirstBuffer != NULL) {
2463cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBuffer->release();
2473cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBuffer = NULL;
2483cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    }
2493cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mInputBuffer != NULL) {
2513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioPlayer releasing input buffer.");
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer->release();
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer = NULL;
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSource->stop();
258fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
25925155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // The following hack is necessary to ensure that the OMX
26025155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // component is completely released by the time we may try
26125155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // to instantiate it again.
26225155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    wp<MediaSource> tmp = mSource;
26325155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    mSource.clear();
26425155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    while (tmp.promote() != NULL) {
26525155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber        usleep(1000);
26625155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    }
26725155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    IPCThreadState::self()->flushCommands();
26825155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumFramesPlayed = 0;
270e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mPositionTimeMediaUs = -1;
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mPositionTimeRealUs = -1;
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeeking = false;
2741862a33b246249630b654182afb5914da3480d4cAndreas Huber    mReachedEOS = false;
2755295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    mFinalStatus = OK;
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
280d217a8c4632b3e3065f8c2a26b9ce4dc4c97171fGlenn Kastenvoid AudioPlayer::AudioCallback(int event, void *user, void *info) {
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2841862a33b246249630b654182afb5914da3480d4cAndreas Huberbool AudioPlayer::isSeeking() {
2851862a33b246249630b654182afb5914da3480d4cAndreas Huber    Mutex::Autolock autoLock(mLock);
2861862a33b246249630b654182afb5914da3480d4cAndreas Huber    return mSeeking;
2871862a33b246249630b654182afb5914da3480d4cAndreas Huber}
2881862a33b246249630b654182afb5914da3480d4cAndreas Huber
2895295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huberbool AudioPlayer::reachedEOS(status_t *finalStatus) {
2905295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    *finalStatus = OK;
2915295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber
2921862a33b246249630b654182afb5914da3480d4cAndreas Huber    Mutex::Autolock autoLock(mLock);
2935295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    *finalStatus = mFinalStatus;
2941862a33b246249630b654182afb5914da3480d4cAndreas Huber    return mReachedEOS;
2951862a33b246249630b654182afb5914da3480d4cAndreas Huber}
2961862a33b246249630b654182afb5914da3480d4cAndreas Huber
2977a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivistatus_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
2987a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    if (mAudioSink.get() != NULL) {
2997a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return mAudioSink->setPlaybackRatePermille(ratePermille);
3007a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    } else if (mAudioTrack != NULL){
3017a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
3027a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    } else {
3037a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return NO_INIT;
3047a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    }
3057a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi}
3067a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
3087d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubersize_t AudioPlayer::AudioSinkCallback(
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaPlayerBase::AudioSink *audioSink,
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        void *buffer, size_t size, void *cookie) {
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    AudioPlayer *me = (AudioPlayer *)cookie;
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3137d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    return me->fillBuffer(buffer, size);
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
316d217a8c4632b3e3065f8c2a26b9ce4dc4c97171fGlenn Kastenvoid AudioPlayer::AudioCallback(int event, void *info) {
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (event != AudioTrack::EVENT_MORE_DATA) {
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
3227d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
3237d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
3247d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    buffer->size = numBytesWritten;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huberuint32_t AudioPlayer::getNumFramesPendingPlayout() const {
32884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    uint32_t numFramesPlayedOut;
32984b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    status_t err;
33084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
33184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    if (mAudioSink != NULL) {
33284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        err = mAudioSink->getPosition(&numFramesPlayedOut);
33384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    } else {
33484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        err = mAudioTrack->getPosition(&numFramesPlayedOut);
33584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    }
33684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
33784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
33884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        return 0;
33984b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    }
34084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
34184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // mNumFramesPlayed is the number of frames submitted
34284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // to the audio sink for playback, but not all of them
34384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // may have played out by now.
34484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    return mNumFramesPlayed - numFramesPlayedOut;
34584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber}
34684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
3477d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubersize_t AudioPlayer::fillBuffer(void *data, size_t size) {
34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumFramesPlayed == 0) {
3493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioCallback");
35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3521862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mReachedEOS) {
35351c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        return 0;
3541862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
3551862a33b246249630b654182afb5914da3480d4cAndreas Huber
356bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    bool postSeekComplete = false;
357bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    bool postEOS = false;
358bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    int64_t postEOSDelayUs = 0;
359bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size_done = 0;
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size_remaining = size;
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (size_remaining > 0) {
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaSource::ReadOptions options;
36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            Mutex::Autolock autoLock(mLock);
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (mSeeking) {
3693cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                if (mIsFirstBuffer) {
3703cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    if (mFirstBuffer != NULL) {
3713cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                        mFirstBuffer->release();
3723cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                        mFirstBuffer = NULL;
3733cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    }
3743cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    mIsFirstBuffer = false;
3753cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                }
3763cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                options.setSeekTo(mSeekTimeUs);
37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (mInputBuffer != NULL) {
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    mInputBuffer->release();
38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    mInputBuffer = NULL;
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
383cb9859bcf5f00cee57de06e9968b88a69b2d6d9cGloria Wang
384cb9859bcf5f00cee57de06e9968b88a69b2d6d9cGloria Wang                mSeeking = false;
385ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                if (mObserver) {
386bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber                    postSeekComplete = true;
387ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                }
38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mInputBuffer == NULL) {
3923cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            status_t err;
3933cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
3943cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mIsFirstBuffer) {
3953cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mInputBuffer = mFirstBuffer;
3963cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
3973cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                err = mFirstBufferResult;
3983cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
3993cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mIsFirstBuffer = false;
4003cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            } else {
4013cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                err = mSource->read(&mInputBuffer, &options);
4023cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4040c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber            CHECK((err == OK && mInputBuffer != NULL)
40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                   || (err != OK && mInputBuffer == NULL));
40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4071862a33b246249630b654182afb5914da3480d4cAndreas Huber            Mutex::Autolock autoLock(mLock);
408bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
410ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                if (mObserver && !mReachedEOS) {
41184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // We don't want to post EOS right away but only
41284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // after all frames have actually been played out.
41384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
41484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // These are the number of frames submitted to the
41584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // AudioTrack that you haven't heard yet.
41684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    uint32_t numFramesPendingPlayout =
41784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                        getNumFramesPendingPlayout();
41884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
41984b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // These are the number of frames we're going to
42084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // submit to the AudioTrack by returning from this
42184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    // callback.
42284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    uint32_t numAdditionalFrames = size_done / mFrameSize;
42384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
42484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    numFramesPendingPlayout += numAdditionalFrames;
42584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
42684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                    int64_t timeToCompletionUs =
42784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                        (1000000ll * numFramesPendingPlayout) / mSampleRate;
42884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
4293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("total number of frames played: %lld (%lld us)",
43084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                            (mNumFramesPlayed + numAdditionalFrames),
43184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                            1000000ll * (mNumFramesPlayed + numAdditionalFrames)
43284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                                / mSampleRate);
43384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
4343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("%d frames left to play, %lld us (%.2f secs)",
43584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                         numFramesPendingPlayout,
43684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber                         timeToCompletionUs, timeToCompletionUs / 1E6);
43784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
438bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber                    postEOS = true;
4396b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                    if (mAudioSink->needsTrailingPadding()) {
4406b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                        postEOSDelayUs = timeToCompletionUs + mLatencyUs;
4416b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                    } else {
4426b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                        postEOSDelayUs = 0;
4436b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                    }
444ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                }
445ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
4461862a33b246249630b654182afb5914da3480d4cAndreas Huber                mReachedEOS = true;
4475295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                mFinalStatus = err;
44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                break;
44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
451db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            if (mAudioSink != NULL) {
452db354e58e65592777aa17caa47933e14838b8b35Eric Laurent                mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
453db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            } else {
454db354e58e65592777aa17caa47933e14838b8b35Eric Laurent                mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
455db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            }
456db354e58e65592777aa17caa47933e14838b8b35Eric Laurent
45748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber            CHECK(mInputBuffer->meta_data()->findInt64(
45848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, &mPositionTimeMediaUs));
4590024245e134467d120b40099da16c467dc365e76Andreas Huber
46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mPositionTimeRealUs =
461b48aea123775fb6ec7e6944826fc99da8d8996a5Eric Laurent                ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
4620024245e134467d120b40099da16c467dc365e76Andreas Huber                    / mSampleRate;
463dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber
4643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("buffer->size() = %d, "
465dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber                 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
466dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber                 mInputBuffer->range_length(),
467dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber                 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mInputBuffer->range_length() == 0) {
47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mInputBuffer->release();
47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mInputBuffer = NULL;
47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            continue;
47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t copy = size_remaining;
47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (copy > mInputBuffer->range_length()) {
47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            copy = mInputBuffer->range_length();
48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        memcpy((char *)data + size_done,
48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber               (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber               copy);
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                                mInputBuffer->range_length() - copy);
488fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_done += copy;
49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_remaining -= copy;
49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
493bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    {
494bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        Mutex::Autolock autoLock(mLock);
495bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mNumFramesPlayed += size_done / mFrameSize;
496e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
497a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
498a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        if (mReachedEOS) {
499a99a5bca365277271915cbaeea811ad87131270dAndreas Huber            mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
500a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        } else {
501a99a5bca365277271915cbaeea811ad87131270dAndreas Huber            mPinnedTimeUs = -1ll;
502a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        }
503bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
504bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
505bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    if (postEOS) {
506bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mObserver->postAudioEOS(postEOSDelayUs);
507bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
508bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
509bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    if (postSeekComplete) {
510bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mObserver->postAudioSeekComplete();
511bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
5127d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
5137d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    return size_done;
51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getRealTimeUs() {
51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return getRealTimeUsLocked();
51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getRealTimeUsLocked() const {
522f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK(mStarted);
523f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK_NE(mSampleRate, 0);
524e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
525e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber
526e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // Compensate for large audio buffers, updates of mNumFramesPlayed
527e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // are less frequent, therefore to get a "smoother" notion of time we
528e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // compensate using system time.
529a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    int64_t diffUs;
530a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    if (mPinnedTimeUs >= 0ll) {
531a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        diffUs = mPinnedTimeUs;
532a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    } else {
533a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        diffUs = ALooper::GetNowUs();
534a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    }
535a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
536a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    diffUs -= mNumFramesPlayedSysTimeUs;
537e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber
538e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    return result + diffUs;
53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getMediaTimeUs() {
54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
544ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber    if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
545fe9b71919cdddf898a516169db840751878098caAndreas Huber        if (mSeeking) {
546fe9b71919cdddf898a516169db840751878098caAndreas Huber            return mSeekTimeUs;
547fe9b71919cdddf898a516169db840751878098caAndreas Huber        }
548fe9b71919cdddf898a516169db840751878098caAndreas Huber
549ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber        return 0;
550ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber    }
551ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber
55280a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
55380a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    if (realTimeOffset < 0) {
55480a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber        realTimeOffset = 0;
55580a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    }
55680a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber
55780a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    return mPositionTimeMediaUs + realTimeOffset;
55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool AudioPlayer::getMediaTimeMapping(
56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        int64_t *realtime_us, int64_t *mediatime_us) {
56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *realtime_us = mPositionTimeRealUs;
56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *mediatime_us = mPositionTimeMediaUs;
56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
567ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber    return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t AudioPlayer::seekTo(int64_t time_us) {
57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeeking = true;
574fe9b71919cdddf898a516169db840751878098caAndreas Huber    mPositionTimeRealUs = mPositionTimeMediaUs = -1;
5751862a33b246249630b654182afb5914da3480d4cAndreas Huber    mReachedEOS = false;
57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeekTimeUs = time_us;
57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5786c375490a5536695770a85b57ec9f828d3c0c9d4James Dong    // Flush resets the number of played frames
5796c375490a5536695770a85b57ec9f828d3c0c9d4James Dong    mNumFramesPlayed = 0;
580e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
5816c375490a5536695770a85b57ec9f828d3c0c9d4James Dong
582c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    if (mAudioSink != NULL) {
583c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber        mAudioSink->flush();
584c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    } else {
585c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber        mAudioTrack->flush();
586c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    }
587c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber
58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
592