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
17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
19dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber//#define LOG_NDEBUG 0
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "AudioPlayer"
2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <cutils/compiler.h>
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2425155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber#include <binder/IPCThreadState.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/AudioTrack.h>
262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad#include <media/openmax/OMX_Audio.h>
27f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber#include <media/stagefright/foundation/ADebug.h>
28e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber#include <media/stagefright/foundation/ALooper.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/AudioPlayer.h>
3018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
313cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber#include <media/stagefright/MediaErrors.h>
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h>
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
3494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/Utils.h>
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber#include "include/AwesomePlayer.h"
37ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas HuberAudioPlayer::AudioPlayer(
41ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber        const sp<MediaPlayerBase::AudioSink> &audioSink,
42ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald        uint32_t flags,
43ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber        AwesomePlayer *observer)
442799d743ee2ae5a25fe869a7f9c052acc029559fGlenn Kasten    : mInputBuffer(NULL),
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleRate(0),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mLatencyUs(0),
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mFrameSize(0),
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumFramesPlayed(0),
49e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber      mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mPositionTimeMediaUs(-1),
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mPositionTimeRealUs(-1),
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSeeking(false),
531862a33b246249630b654182afb5914da3480d4cAndreas Huber      mReachedEOS(false),
545295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber      mFinalStatus(OK),
5594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald      mSeekTimeUs(0),
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mStarted(false),
573cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mIsFirstBuffer(false),
583cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mFirstBufferResult(OK),
593cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber      mFirstBuffer(NULL),
60ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber      mAudioSink(audioSink),
61a99a5bca365277271915cbaeea811ad87131270dAndreas Huber      mObserver(observer),
6294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald      mPinnedTimeUs(-1ll),
6394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald      mPlaying(false),
6494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald      mStartPosUs(0),
6594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald      mCreateFlags(flags) {
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberAudioPlayer::~AudioPlayer() {
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
70b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        reset();
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
74693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubervoid AudioPlayer::setSource(const sp<MediaSource> &source) {
75f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK(mSource == NULL);
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSource = source;
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huberstatus_t AudioPlayer::start(bool sourceAlreadyStarted) {
800c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(!mStarted);
810c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mSource != NULL);
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber    status_t err;
84e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber    if (!sourceAlreadyStarted) {
85e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        err = mSource->start();
8688c030e0e0152791ff74f90249f55fce01371198Andreas Huber
87e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        if (err != OK) {
88e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber            return err;
89e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber        }
9088c030e0e0152791ff74f90249f55fce01371198Andreas Huber    }
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
923cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // We allow an optional INFO_FORMAT_CHANGED at the very beginning
933cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // of playback, if there is one, getFormat below will retrieve the
943cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // updated format, if there isn't, we'll stash away the valid buffer
953cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    // of data to be used on the first audio callback.
963cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
973cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    CHECK(mFirstBuffer == NULL);
983cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
99c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    MediaSource::ReadOptions options;
100c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    if (mSeeking) {
101c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        options.setSeekTo(mSeekTimeUs);
102c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        mSeeking = false;
103c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    }
104c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
105c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber    mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
1063cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
1073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("INFO_FORMAT_CHANGED!!!");
1083cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
1093cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        CHECK(mFirstBuffer == NULL);
1103cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBufferResult = OK;
1113cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mIsFirstBuffer = false;
1123cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    } else {
1133cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mIsFirstBuffer = true;
1143cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    }
1153cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> format = mSource->getFormat();
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const char *mime;
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = format->findCString(kKeyMIMEType, &mime);
1190c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
12094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(useOffload() || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = format->findInt32(kKeySampleRate, &mSampleRate);
1230c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
125786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    int32_t numChannels, channelMask;
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = format->findInt32(kKeyChannelCount, &numChannels);
1270c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(success);
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
129786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    if(!format->findInt32(kKeyChannelMask, &channelMask)) {
1302c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi        // log only when there's a risk of ambiguity of channel mask selection
1312c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi        ALOGI_IF(numChannels > 2,
1322c3297ab6c4daaaa7b27eed8418c64cf168fe2a1Jean-Michel Trivi                "source format didn't specify channel mask, using (%d) channel order", numChannels);
133786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
134786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    }
135786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi
13694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
13794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
13894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (useOffload()) {
13994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mapMimeToAudioFormat(audioFormat, mime) != OK) {
14094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime);
14194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            audioFormat = AUDIO_FORMAT_INVALID;
14294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
14394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, audioFormat);
14494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
1452829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
1462829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        int32_t aacaot = -1;
1472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if ((audioFormat == AUDIO_FORMAT_AAC) && format->findInt32(kKeyAACAOT, &aacaot)) {
1482829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            // Redefine AAC format corrosponding to aac profile
1492829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            mapAACProfileToAudioFormat(audioFormat,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1502829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
15194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
15294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
15394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int avgBitRate = -1;
15494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    format->findInt32(kKeyBitRate, &avgBitRate);
15594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
1571948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
15894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        uint32_t flags = AUDIO_OUTPUT_FLAG_NONE;
15994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
16094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
16194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (allowDeepBuffering()) {
16294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            flags |= AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
16394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
16494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (useOffload()) {
16594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
16694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
16794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            int64_t durationUs;
16894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            if (format->findInt64(kKeyDuration, &durationUs)) {
16994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                offloadInfo.duration_us = durationUs;
17094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            } else {
17194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                offloadInfo.duration_us = -1;
17294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
17394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
17494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.sample_rate = mSampleRate;
17594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.channel_mask = channelMask;
17694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.format = audioFormat;
17794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
17894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.bit_rate = avgBitRate;
17994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0);
18094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0);
18194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
18294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        status_t err = mAudioSink->open(
18494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                mSampleRate, numChannels, channelMask, audioFormat,
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                DEFAULT_AUDIOSINK_BUFFERCOUNT,
1861948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                &AudioPlayer::AudioSinkCallback,
1871948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent                this,
18894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                (audio_output_flags_t)flags,
18994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                useOffload() ? &offloadInfo : NULL);
19094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
19194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (err == OK) {
19294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
19394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mFrameSize = mAudioSink->frameSize();
19494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
19594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            if (useOffload()) {
19694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                // If the playback is offloaded to h/w we pass the
19794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                // HAL some metadata information
19894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                // We don't want to do this for PCM because it will be going
19994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                // through the AudioFlinger mixer before reaching the hardware
20094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                sendMetaDataToHal(mAudioSink, format);
20194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
20294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
20394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            err = mAudioSink->start();
20494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            // do not alter behavior for non offloaded tracks: ignore start status.
20594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            if (!useOffload()) {
20694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                err = OK;
20794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
20894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
20994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
21088c030e0e0152791ff74f90249f55fce01371198Andreas Huber        if (err != OK) {
2113cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mFirstBuffer != NULL) {
2123cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer->release();
2133cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
2143cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
2153cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
2164575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            if (!sourceAlreadyStarted) {
2174575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber                mSource->stop();
2184575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            }
21988c030e0e0152791ff74f90249f55fce01371198Andreas Huber
22088c030e0e0152791ff74f90249f55fce01371198Andreas Huber            return err;
22188c030e0e0152791ff74f90249f55fce01371198Andreas Huber        }
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
224786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        // playing to an AudioTrack, set up mask if necessary
225786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
226ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten                audio_channel_out_mask_from_count(numChannels) : channelMask;
227786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        if (0 == audioMask) {
228786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi            return BAD_VALUE;
229786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        }
230786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack = new AudioTrack(
232786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi                AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
2332301acc6a9c7a3af4ad01f3d1d0f76f13eca7350Glenn Kasten                0 /*frameCount*/, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this,
2342301acc6a9c7a3af4ad01f3d1d0f76f13eca7350Glenn Kasten                0 /*notificationFrames*/);
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23632dcebf970356eb8599ea965d71535ed0c212c2dKenny Root        if ((err = mAudioTrack->initCheck()) != OK) {
2372799d743ee2ae5a25fe869a7f9c052acc029559fGlenn Kasten            mAudioTrack.clear();
23888c030e0e0152791ff74f90249f55fce01371198Andreas Huber
2393cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mFirstBuffer != NULL) {
2403cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer->release();
2413cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
2423cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
2433cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
2444575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            if (!sourceAlreadyStarted) {
2454575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber                mSource->stop();
2464575beb3dea80e271eaa6619234fdc02e914e6e6Andreas Huber            }
24788c030e0e0152791ff74f90249f55fce01371198Andreas Huber
24832dcebf970356eb8599ea965d71535ed0c212c2dKenny Root            return err;
24988c030e0e0152791ff74f90249f55fce01371198Andreas Huber        }
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mFrameSize = mAudioTrack->frameSize();
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack->start();
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = true;
25894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    mPlaying = true;
259a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    mPinnedTimeUs = -1ll;
26088c030e0e0152791ff74f90249f55fce01371198Andreas Huber
26188c030e0e0152791ff74f90249f55fce01371198Andreas Huber    return OK;
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
264b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Hubervoid AudioPlayer::pause(bool playPendingSamples) {
2650c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
267b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber    if (playPendingSamples) {
268b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (mAudioSink.get() != NULL) {
269b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioSink->stop();
270b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
271b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioTrack->stop();
272b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
2730b293e76c8fe4e973ccd8a872bc5320ba28d49ccAndreas Huber
2740b293e76c8fe4e973ccd8a872bc5320ba28d49ccAndreas Huber        mNumFramesPlayed = 0;
275e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
277b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (mAudioSink.get() != NULL) {
278b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioSink->pause();
279b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
280b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioTrack->pause();
281b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
282a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
283a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        mPinnedTimeUs = ALooper::GetNowUs();
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
28694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    mPlaying = false;
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t AudioPlayer::resume() {
2900c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
29194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    status_t err;
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
29494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        err = mAudioSink->start();
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
29694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        err = mAudioTrack->start();
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
29894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
29994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (err == OK) {
30094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mPlaying = true;
30194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
30294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
30394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return err;
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
306b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Hubervoid AudioPlayer::reset() {
3070c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mStarted);
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("reset: mPlaying=%d mReachedEOS=%d useOffload=%d",
31094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                mPlaying, mReachedEOS, useOffload() );
31194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mAudioSink.get() != NULL) {
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioSink->stop();
31494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // If we're closing and have reached EOS, we don't want to flush
31594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // the track because if it is offloaded there could be a small
31694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // amount of residual data in the hardware buffer which we must
31794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // play to give gapless playback.
31894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // But if we're resetting when paused or before we've reached EOS
31994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // we can't be doing a gapless playback and there could be a large
32094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // amount of data queued in the hardware if the track is offloaded,
32194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // so we must flush to prevent a track switch being delayed playing
32294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // the buffered data that we don't want now
32394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!mPlaying || !mReachedEOS) {
32494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioSink->flush();
32594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
32694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber        mAudioSink->close();
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mAudioTrack->stop();
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!mPlaying || !mReachedEOS) {
33294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioTrack->flush();
33394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
33494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
3352799d743ee2ae5a25fe869a7f9c052acc029559fGlenn Kasten        mAudioTrack.clear();
33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
337fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // Make sure to release any buffer we hold onto so that the
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    // source is able to stop().
3403cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
3413cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    if (mFirstBuffer != NULL) {
3423cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBuffer->release();
3433cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber        mFirstBuffer = NULL;
3443cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber    }
3453cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mInputBuffer != NULL) {
3473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioPlayer releasing input buffer.");
34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer->release();
35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer = NULL;
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSource->stop();
354fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
35525155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // The following hack is necessary to ensure that the OMX
35625155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // component is completely released by the time we may try
35725155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    // to instantiate it again.
35894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // When offloading, the OMX component is not used so this hack
35994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // is not needed
36094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!useOffload()) {
36194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        wp<MediaSource> tmp = mSource;
36294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mSource.clear();
36394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        while (tmp.promote() != NULL) {
36494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            usleep(1000);
36594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
36694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
36794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mSource.clear();
36825155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    }
36925155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber    IPCThreadState::self()->flushCommands();
37025155ff8ccf7898d08ab62fae46297e046a571f0Andreas Huber
37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumFramesPlayed = 0;
372e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mPositionTimeMediaUs = -1;
37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mPositionTimeRealUs = -1;
37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeeking = false;
37691b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent    mSeekTimeUs = 0;
3771862a33b246249630b654182afb5914da3480d4cAndreas Huber    mReachedEOS = false;
3785295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    mFinalStatus = OK;
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mStarted = false;
38094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    mPlaying = false;
38194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    mStartPosUs = 0;
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
385d217a8c4632b3e3065f8c2a26b9ce4dc4c97171fGlenn Kastenvoid AudioPlayer::AudioCallback(int event, void *user, void *info) {
38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3891862a33b246249630b654182afb5914da3480d4cAndreas Huberbool AudioPlayer::isSeeking() {
3901862a33b246249630b654182afb5914da3480d4cAndreas Huber    Mutex::Autolock autoLock(mLock);
3911862a33b246249630b654182afb5914da3480d4cAndreas Huber    return mSeeking;
3921862a33b246249630b654182afb5914da3480d4cAndreas Huber}
3931862a33b246249630b654182afb5914da3480d4cAndreas Huber
3945295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huberbool AudioPlayer::reachedEOS(status_t *finalStatus) {
3955295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    *finalStatus = OK;
3965295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber
3971862a33b246249630b654182afb5914da3480d4cAndreas Huber    Mutex::Autolock autoLock(mLock);
3985295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    *finalStatus = mFinalStatus;
3991862a33b246249630b654182afb5914da3480d4cAndreas Huber    return mReachedEOS;
4001862a33b246249630b654182afb5914da3480d4cAndreas Huber}
4011862a33b246249630b654182afb5914da3480d4cAndreas Huber
40294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldvoid AudioPlayer::notifyAudioEOS() {
40394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("AudioPlayer@0x%p notifyAudioEOS", this);
40494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
40594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mObserver != NULL) {
40694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mObserver->postAudioEOS(0);
40794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Notified observer of EOS!");
40894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
40994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}
41094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
4117a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivistatus_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
4127a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    if (mAudioSink.get() != NULL) {
4137a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return mAudioSink->setPlaybackRatePermille(ratePermille);
4142799d743ee2ae5a25fe869a7f9c052acc029559fGlenn Kasten    } else if (mAudioTrack != 0){
4157a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
4167a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    } else {
4177a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return NO_INIT;
4187a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    }
4197a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi}
4207a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi
42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
4227d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubersize_t AudioPlayer::AudioSinkCallback(
42384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaPlayerBase::AudioSink * /* audioSink */,
424ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald        void *buffer, size_t size, void *cookie,
425ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald        MediaPlayerBase::AudioSink::cb_event_t event) {
42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    AudioPlayer *me = (AudioPlayer *)cookie;
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
42894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    switch(event) {
42994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER:
43094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return me->fillBuffer(buffer, size);
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END:
43394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("AudioSinkCallback: stream end");
43494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        me->mReachedEOS = true;
43594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        me->notifyAudioEOS();
43694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        break;
43794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
43894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
43994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("AudioSinkCallback: Tear down event");
44094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        me->mObserver->postAudioTearDown();
44194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        break;
44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return 0;
44594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}
44694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
44794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldvoid AudioPlayer::AudioCallback(int event, void *info) {
44894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    switch (event) {
44994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    case AudioTrack::EVENT_MORE_DATA:
45094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        {
45194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
45294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
45394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        buffer->size = numBytesWritten;
45494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
45594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        break;
4567d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
45794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    case AudioTrack::EVENT_STREAM_END:
45894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mReachedEOS = true;
45994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        notifyAudioEOS();
46094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        break;
46194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huberuint32_t AudioPlayer::getNumFramesPendingPlayout() const {
46584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    uint32_t numFramesPlayedOut;
46684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    status_t err;
46784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
46884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    if (mAudioSink != NULL) {
46984b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        err = mAudioSink->getPosition(&numFramesPlayedOut);
47084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    } else {
47184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        err = mAudioTrack->getPosition(&numFramesPlayedOut);
47284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    }
47384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
47484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
47584b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber        return 0;
47684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    }
47784b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
47884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // mNumFramesPlayed is the number of frames submitted
47984b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // to the audio sink for playback, but not all of them
48084b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    // may have played out by now.
48184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    return mNumFramesPlayed - numFramesPlayedOut;
48284b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber}
48384b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber
4847d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubersize_t AudioPlayer::fillBuffer(void *data, size_t size) {
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumFramesPlayed == 0) {
4863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioCallback");
48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4891862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mReachedEOS) {
49051c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        return 0;
4911862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
4921862a33b246249630b654182afb5914da3480d4cAndreas Huber
493bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    bool postSeekComplete = false;
494bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    bool postEOS = false;
495bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    int64_t postEOSDelayUs = 0;
496bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size_done = 0;
49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size_remaining = size;
49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    while (size_remaining > 0) {
50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaSource::ReadOptions options;
50194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        bool refreshSeekTime = false;
50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        {
50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            Mutex::Autolock autoLock(mLock);
50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (mSeeking) {
5073cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                if (mIsFirstBuffer) {
5083cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    if (mFirstBuffer != NULL) {
5093cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                        mFirstBuffer->release();
5103cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                        mFirstBuffer = NULL;
5113cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    }
5123cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                    mIsFirstBuffer = false;
5133cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                }
5143cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                options.setSeekTo(mSeekTimeUs);
51694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                refreshSeekTime = true;
51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                if (mInputBuffer != NULL) {
51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    mInputBuffer->release();
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                    mInputBuffer = NULL;
52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                }
522cb9859bcf5f00cee57de06e9968b88a69b2d6d9cGloria Wang
523cb9859bcf5f00cee57de06e9968b88a69b2d6d9cGloria Wang                mSeeking = false;
524ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                if (mObserver) {
525bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber                    postSeekComplete = true;
526ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                }
52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mInputBuffer == NULL) {
5313cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            status_t err;
5323cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
5333cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            if (mIsFirstBuffer) {
5343cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mInputBuffer = mFirstBuffer;
5353cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mFirstBuffer = NULL;
5363cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                err = mFirstBufferResult;
5373cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber
5383cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                mIsFirstBuffer = false;
5393cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            } else {
5403cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber                err = mSource->read(&mInputBuffer, &options);
5413cc219dfc67b866e10828f0c17641668d47c1cd8Andreas Huber            }
54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5430c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber            CHECK((err == OK && mInputBuffer != NULL)
54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                   || (err != OK && mInputBuffer == NULL));
54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5461862a33b246249630b654182afb5914da3480d4cAndreas Huber            Mutex::Autolock autoLock(mLock);
547bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (err != OK) {
54994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                if (!mReachedEOS) {
55094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                    if (useOffload()) {
55194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        // no more buffers to push - stop() and wait for STREAM_END
55294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        // don't set mReachedEOS until stream end received
55394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        if (mAudioSink != NULL) {
55494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            mAudioSink->stop();
55594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        } else {
55694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            mAudioTrack->stop();
55794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        }
5586b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                    } else {
55994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        if (mObserver) {
56094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // We don't want to post EOS right away but only
56194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // after all frames have actually been played out.
56294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
56394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // These are the number of frames submitted to the
56494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // AudioTrack that you haven't heard yet.
56594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            uint32_t numFramesPendingPlayout =
56694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                getNumFramesPendingPlayout();
56794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
56894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // These are the number of frames we're going to
56994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // submit to the AudioTrack by returning from this
57094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            // callback.
57194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            uint32_t numAdditionalFrames = size_done / mFrameSize;
57294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
57394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            numFramesPendingPlayout += numAdditionalFrames;
57494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
57594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            int64_t timeToCompletionUs =
57694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                (1000000ll * numFramesPendingPlayout) / mSampleRate;
57794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
578a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                            ALOGV("total number of frames played: %" PRId64 " (%lld us)",
57994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                    (mNumFramesPlayed + numAdditionalFrames),
58094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                    1000000ll * (mNumFramesPlayed + numAdditionalFrames)
58194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                        / mSampleRate);
58294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
583a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                            ALOGV("%d frames left to play, %" PRId64 " us (%.2f secs)",
58494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                 numFramesPendingPlayout,
58594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                 timeToCompletionUs, timeToCompletionUs / 1E6);
58694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
58794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            postEOS = true;
58894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            if (mAudioSink->needsTrailingPadding()) {
58994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                postEOSDelayUs = timeToCompletionUs + mLatencyUs;
59094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            } else {
59194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                                postEOSDelayUs = 0;
59294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                            }
59394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        }
59494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
59594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        mReachedEOS = true;
5966b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                    }
597ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                }
598ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
5995295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                mFinalStatus = err;
60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                break;
60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
603db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            if (mAudioSink != NULL) {
604db354e58e65592777aa17caa47933e14838b8b35Eric Laurent                mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
605db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            } else {
606db354e58e65592777aa17caa47933e14838b8b35Eric Laurent                mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
607db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            }
608db354e58e65592777aa17caa47933e14838b8b35Eric Laurent
60994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            if(mInputBuffer->range_length() != 0) {
61094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                CHECK(mInputBuffer->meta_data()->findInt64(
61148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber                        kKeyTime, &mPositionTimeMediaUs));
61294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
61394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
61494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            // need to adjust the mStartPosUs for offload decoding since parser
61594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            // might not be able to get the exact seek time requested.
61691b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent            if (refreshSeekTime) {
61791b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                if (useOffload()) {
61891b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                    if (postSeekComplete) {
61991b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                        ALOGV("fillBuffer is going to post SEEK_COMPLETE");
62091b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                        mObserver->postAudioSeekComplete();
62191b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                        postSeekComplete = false;
62291b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                    }
62394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
62491b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                    mStartPosUs = mPositionTimeMediaUs;
62591b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                    ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6);
62691b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                }
62791b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs
62891b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                // and mPositionTimeRealUs
62991b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                // before clearing mSeekTimeUs check if a new seek request has been received while
63091b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                // we were reading from the source with mLock released.
63191b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                if (!mSeeking) {
63291b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                    mSeekTimeUs = 0;
63391b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent                }
63494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
6350024245e134467d120b40099da16c467dc365e76Andreas Huber
63694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            if (!useOffload()) {
63794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                mPositionTimeRealUs =
63894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                    ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
63994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                        / mSampleRate;
640a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGV("buffer->size() = %zu, "
64194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                     "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
64294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                     mInputBuffer->range_length(),
64394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald                     mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
64494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            }
645dae04ca7c4b5590786ffc336721ee8714cc79fefAndreas Huber
64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mInputBuffer->range_length() == 0) {
64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mInputBuffer->release();
65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            mInputBuffer = NULL;
65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            continue;
65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t copy = size_remaining;
65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (copy > mInputBuffer->range_length()) {
65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            copy = mInputBuffer->range_length();
65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        memcpy((char *)data + size_done,
66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber               (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber               copy);
66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                                mInputBuffer->range_length() - copy);
666fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber
66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_done += copy;
66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_remaining -= copy;
66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
67194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (useOffload()) {
67294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // We must ask the hardware what it has played
67394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mPositionTimeRealUs = getOutputPlayPositionUs_l();
67494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
67594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald             mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
67694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
67794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
678bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    {
679bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        Mutex::Autolock autoLock(mLock);
680bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mNumFramesPlayed += size_done / mFrameSize;
681e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
682a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
683a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        if (mReachedEOS) {
684a99a5bca365277271915cbaeea811ad87131270dAndreas Huber            mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
685a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        } else {
686a99a5bca365277271915cbaeea811ad87131270dAndreas Huber            mPinnedTimeUs = -1ll;
687a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        }
688bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
689bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
690bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    if (postEOS) {
691bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mObserver->postAudioEOS(postEOSDelayUs);
692bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
693bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber
694bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    if (postSeekComplete) {
695bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber        mObserver->postAudioSeekComplete();
696bd7b7177f88ae6e83bd7bb8bfd9b7018be923931Andreas Huber    }
6977d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
6987d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    return size_done;
69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getRealTimeUs() {
70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
70350d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George    if (useOffload()) {
70450d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        if (mSeeking) {
70550d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George            return mSeekTimeUs;
70650d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        }
70750d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        mPositionTimeRealUs = getOutputPlayPositionUs_l();
70850d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        return mPositionTimeRealUs;
70950d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George    }
71050d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George
71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return getRealTimeUsLocked();
71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getRealTimeUsLocked() const {
715f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK(mStarted);
716f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    CHECK_NE(mSampleRate, 0);
717e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
718e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber
719e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // Compensate for large audio buffers, updates of mNumFramesPlayed
720e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // are less frequent, therefore to get a "smoother" notion of time we
721e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    // compensate using system time.
722a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    int64_t diffUs;
723a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    if (mPinnedTimeUs >= 0ll) {
724a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        diffUs = mPinnedTimeUs;
725a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    } else {
726a99a5bca365277271915cbaeea811ad87131270dAndreas Huber        diffUs = ALooper::GetNowUs();
727a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    }
728a99a5bca365277271915cbaeea811ad87131270dAndreas Huber
729a99a5bca365277271915cbaeea811ad87131270dAndreas Huber    diffUs -= mNumFramesPlayedSysTimeUs;
730e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber
731e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    return result + diffUs;
73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7346f59db12a64f4496866952a251122ccb77a36c6bEric Laurentint64_t AudioPlayer::getOutputPlayPositionUs_l()
73594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald{
73694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    uint32_t playedSamples = 0;
7376f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    uint32_t sampleRate;
73894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mAudioSink != NULL) {
73994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mAudioSink->getPosition(&playedSamples);
7406f59db12a64f4496866952a251122ccb77a36c6bEric Laurent        sampleRate = mAudioSink->getSampleRate();
74194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
74294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mAudioTrack->getPosition(&playedSamples);
7436f59db12a64f4496866952a251122ccb77a36c6bEric Laurent        sampleRate = mAudioTrack->getSampleRate();
7446f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    }
7456f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    if (sampleRate != 0) {
7466f59db12a64f4496866952a251122ccb77a36c6bEric Laurent        mSampleRate = sampleRate;
74794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
74894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
7496f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    int64_t playedUs;
7506f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    if (mSampleRate != 0) {
7516f59db12a64f4496866952a251122ccb77a36c6bEric Laurent        playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
7526f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    } else {
7536f59db12a64f4496866952a251122ccb77a36c6bEric Laurent        playedUs = 0;
7546f59db12a64f4496866952a251122ccb77a36c6bEric Laurent    }
75594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
75694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // HAL position is relative to the first buffer we sent at mStartPosUs
75794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const int64_t renderedDuration = mStartPosUs + playedUs;
758a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration);
75994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return renderedDuration;
76094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}
76194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint64_t AudioPlayer::getMediaTimeUs() {
76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
76594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (useOffload()) {
76694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mSeeking) {
76794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return mSeekTimeUs;
76894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
769e125bba94afe74df330c661ab0a64b1e9e2ac5b7aarti jadhav-gaikwad        if (mReachedEOS) {
770e125bba94afe74df330c661ab0a64b1e9e2ac5b7aarti jadhav-gaikwad            int64_t durationUs;
771e125bba94afe74df330c661ab0a64b1e9e2ac5b7aarti jadhav-gaikwad            mSource->getFormat()->findInt64(kKeyDuration, &durationUs);
772e125bba94afe74df330c661ab0a64b1e9e2ac5b7aarti jadhav-gaikwad            return durationUs;
773e125bba94afe74df330c661ab0a64b1e9e2ac5b7aarti jadhav-gaikwad        }
77494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        mPositionTimeRealUs = getOutputPlayPositionUs_l();
775a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64,
77694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald              mPositionTimeRealUs);
77794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return mPositionTimeRealUs;
77894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
77994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
780fe9b71919cdddf898a516169db840751878098caAndreas Huber
78191b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent    if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
78291b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent        // mSeekTimeUs is either seek time while seeking or 0 if playback did not start.
78391b0ca1a5bea44dd9b5196910186dd2927821994Eric Laurent        return mSeekTimeUs;
784ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber    }
785ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber
78680a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
78780a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    if (realTimeOffset < 0) {
78880a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber        realTimeOffset = 0;
78980a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    }
79080a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber
79180a68deec52c9a1b47215ed68526206ec88197f8Andreas Huber    return mPositionTimeMediaUs + realTimeOffset;
79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool AudioPlayer::getMediaTimeMapping(
79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        int64_t *realtime_us, int64_t *mediatime_us) {
79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
79850d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George    if (useOffload()) {
79950d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        mPositionTimeRealUs = getOutputPlayPositionUs_l();
80050d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        *realtime_us = mPositionTimeRealUs;
80150d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        *mediatime_us = mPositionTimeRealUs;
80250d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George    } else {
80350d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        *realtime_us = mPositionTimeRealUs;
80450d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George        *mediatime_us = mPositionTimeMediaUs;
80550d9a8f7de5f79fa8a36489a53846d6653997e38Haynes Mathew George    }
80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
807ad6516d9247bd0a76a393810b041c3e4094f0e36Andreas Huber    return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t AudioPlayer::seekTo(int64_t time_us) {
81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
813a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("seekTo( %" PRId64 " )", time_us);
81494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeeking = true;
816fe9b71919cdddf898a516169db840751878098caAndreas Huber    mPositionTimeRealUs = mPositionTimeMediaUs = -1;
8171862a33b246249630b654182afb5914da3480d4cAndreas Huber    mReachedEOS = false;
81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSeekTimeUs = time_us;
81994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    mStartPosUs = time_us;
82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8216c375490a5536695770a85b57ec9f828d3c0c9d4James Dong    // Flush resets the number of played frames
8226c375490a5536695770a85b57ec9f828d3c0c9d4James Dong    mNumFramesPlayed = 0;
823e4451a91a61a341014f5eff61db356156c3ecb37Andreas Huber    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
8246c375490a5536695770a85b57ec9f828d3c0c9d4James Dong
825c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    if (mAudioSink != NULL) {
82694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mPlaying) {
82794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioSink->pause();
82894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
829c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber        mAudioSink->flush();
83094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mPlaying) {
83194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioSink->start();
83294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
833c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    } else {
83494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mPlaying) {
83594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioTrack->pause();
83694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
837c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber        mAudioTrack->flush();
83894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (mPlaying) {
83994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            mAudioTrack->start();
84094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
841c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber    }
842c7d368d990303dc5369c7c61579f88c5059dc8d7Andreas Huber
84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
847