Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <inttypes.h>
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "AudioPlayer"
     21 #include <utils/Log.h>
     22 #include <cutils/compiler.h>
     23 
     24 #include <binder/IPCThreadState.h>
     25 #include <media/AudioTrack.h>
     26 #include <media/openmax/OMX_Audio.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 #include <media/stagefright/foundation/ALooper.h>
     29 #include <media/stagefright/AudioPlayer.h>
     30 #include <media/stagefright/MediaDefs.h>
     31 #include <media/stagefright/MediaErrors.h>
     32 #include <media/stagefright/MediaSource.h>
     33 #include <media/stagefright/MetaData.h>
     34 #include <media/stagefright/Utils.h>
     35 
     36 #include "include/AwesomePlayer.h"
     37 
     38 namespace android {
     39 
     40 AudioPlayer::AudioPlayer(
     41         const sp<MediaPlayerBase::AudioSink> &audioSink,
     42         uint32_t flags,
     43         AwesomePlayer *observer)
     44     : mInputBuffer(NULL),
     45       mSampleRate(0),
     46       mLatencyUs(0),
     47       mFrameSize(0),
     48       mNumFramesPlayed(0),
     49       mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
     50       mPositionTimeMediaUs(-1),
     51       mPositionTimeRealUs(-1),
     52       mSeeking(false),
     53       mReachedEOS(false),
     54       mFinalStatus(OK),
     55       mSeekTimeUs(0),
     56       mStarted(false),
     57       mIsFirstBuffer(false),
     58       mFirstBufferResult(OK),
     59       mFirstBuffer(NULL),
     60       mAudioSink(audioSink),
     61       mObserver(observer),
     62       mPinnedTimeUs(-1ll),
     63       mPlaying(false),
     64       mStartPosUs(0),
     65       mCreateFlags(flags) {
     66 }
     67 
     68 AudioPlayer::~AudioPlayer() {
     69     if (mStarted) {
     70         reset();
     71     }
     72 }
     73 
     74 void AudioPlayer::setSource(const sp<MediaSource> &source) {
     75     CHECK(mSource == NULL);
     76     mSource = source;
     77 }
     78 
     79 status_t AudioPlayer::start(bool sourceAlreadyStarted) {
     80     CHECK(!mStarted);
     81     CHECK(mSource != NULL);
     82 
     83     status_t err;
     84     if (!sourceAlreadyStarted) {
     85         err = mSource->start();
     86 
     87         if (err != OK) {
     88             return err;
     89         }
     90     }
     91 
     92     // We allow an optional INFO_FORMAT_CHANGED at the very beginning
     93     // of playback, if there is one, getFormat below will retrieve the
     94     // updated format, if there isn't, we'll stash away the valid buffer
     95     // of data to be used on the first audio callback.
     96 
     97     CHECK(mFirstBuffer == NULL);
     98 
     99     MediaSource::ReadOptions options;
    100     if (mSeeking) {
    101         options.setSeekTo(mSeekTimeUs);
    102         mSeeking = false;
    103     }
    104 
    105     mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
    106     if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
    107         ALOGV("INFO_FORMAT_CHANGED!!!");
    108 
    109         CHECK(mFirstBuffer == NULL);
    110         mFirstBufferResult = OK;
    111         mIsFirstBuffer = false;
    112     } else {
    113         mIsFirstBuffer = true;
    114     }
    115 
    116     sp<MetaData> format = mSource->getFormat();
    117     const char *mime;
    118     bool success = format->findCString(kKeyMIMEType, &mime);
    119     CHECK(success);
    120     CHECK(useOffload() || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
    121 
    122     success = format->findInt32(kKeySampleRate, &mSampleRate);
    123     CHECK(success);
    124 
    125     int32_t numChannels, channelMask;
    126     success = format->findInt32(kKeyChannelCount, &numChannels);
    127     CHECK(success);
    128 
    129     if(!format->findInt32(kKeyChannelMask, &channelMask)) {
    130         // log only when there's a risk of ambiguity of channel mask selection
    131         ALOGI_IF(numChannels > 2,
    132                 "source format didn't specify channel mask, using (%d) channel order", numChannels);
    133         channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
    134     }
    135 
    136     audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
    137 
    138     if (useOffload()) {
    139         if (mapMimeToAudioFormat(audioFormat, mime) != OK) {
    140             ALOGE("Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format", mime);
    141             audioFormat = AUDIO_FORMAT_INVALID;
    142         } else {
    143             ALOGV("Mime type \"%s\" mapped to audio_format 0x%x", mime, audioFormat);
    144         }
    145 
    146         int32_t aacaot = -1;
    147         if ((audioFormat == AUDIO_FORMAT_AAC) && format->findInt32(kKeyAACAOT, &aacaot)) {
    148             // Redefine AAC format corrosponding to aac profile
    149             mapAACProfileToAudioFormat(audioFormat,(OMX_AUDIO_AACPROFILETYPE) aacaot);
    150         }
    151     }
    152 
    153     int avgBitRate = -1;
    154     format->findInt32(kKeyBitRate, &avgBitRate);
    155 
    156     if (mAudioSink.get() != NULL) {
    157 
    158         uint32_t flags = AUDIO_OUTPUT_FLAG_NONE;
    159         audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
    160 
    161         if (allowDeepBuffering()) {
    162             flags |= AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
    163         }
    164         if (useOffload()) {
    165             flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
    166 
    167             int64_t durationUs;
    168             if (format->findInt64(kKeyDuration, &durationUs)) {
    169                 offloadInfo.duration_us = durationUs;
    170             } else {
    171                 offloadInfo.duration_us = -1;
    172             }
    173 
    174             offloadInfo.sample_rate = mSampleRate;
    175             offloadInfo.channel_mask = channelMask;
    176             offloadInfo.format = audioFormat;
    177             offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
    178             offloadInfo.bit_rate = avgBitRate;
    179             offloadInfo.has_video = ((mCreateFlags & HAS_VIDEO) != 0);
    180             offloadInfo.is_streaming = ((mCreateFlags & IS_STREAMING) != 0);
    181         }
    182 
    183         status_t err = mAudioSink->open(
    184                 mSampleRate, numChannels, channelMask, audioFormat,
    185                 DEFAULT_AUDIOSINK_BUFFERCOUNT,
    186                 &AudioPlayer::AudioSinkCallback,
    187                 this,
    188                 (audio_output_flags_t)flags,
    189                 useOffload() ? &offloadInfo : NULL);
    190 
    191         if (err == OK) {
    192             mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
    193             mFrameSize = mAudioSink->frameSize();
    194 
    195             if (useOffload()) {
    196                 // If the playback is offloaded to h/w we pass the
    197                 // HAL some metadata information
    198                 // We don't want to do this for PCM because it will be going
    199                 // through the AudioFlinger mixer before reaching the hardware
    200                 sendMetaDataToHal(mAudioSink, format);
    201             }
    202 
    203             err = mAudioSink->start();
    204             // do not alter behavior for non offloaded tracks: ignore start status.
    205             if (!useOffload()) {
    206                 err = OK;
    207             }
    208         }
    209 
    210         if (err != OK) {
    211             if (mFirstBuffer != NULL) {
    212                 mFirstBuffer->release();
    213                 mFirstBuffer = NULL;
    214             }
    215 
    216             if (!sourceAlreadyStarted) {
    217                 mSource->stop();
    218             }
    219 
    220             return err;
    221         }
    222 
    223     } else {
    224         // playing to an AudioTrack, set up mask if necessary
    225         audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
    226                 audio_channel_out_mask_from_count(numChannels) : channelMask;
    227         if (0 == audioMask) {
    228             return BAD_VALUE;
    229         }
    230 
    231         mAudioTrack = new AudioTrack(
    232                 AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
    233                 0 /*frameCount*/, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this,
    234                 0 /*notificationFrames*/);
    235 
    236         if ((err = mAudioTrack->initCheck()) != OK) {
    237             mAudioTrack.clear();
    238 
    239             if (mFirstBuffer != NULL) {
    240                 mFirstBuffer->release();
    241                 mFirstBuffer = NULL;
    242             }
    243 
    244             if (!sourceAlreadyStarted) {
    245                 mSource->stop();
    246             }
    247 
    248             return err;
    249         }
    250 
    251         mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
    252         mFrameSize = mAudioTrack->frameSize();
    253 
    254         mAudioTrack->start();
    255     }
    256 
    257     mStarted = true;
    258     mPlaying = true;
    259     mPinnedTimeUs = -1ll;
    260 
    261     return OK;
    262 }
    263 
    264 void AudioPlayer::pause(bool playPendingSamples) {
    265     CHECK(mStarted);
    266 
    267     if (playPendingSamples) {
    268         if (mAudioSink.get() != NULL) {
    269             mAudioSink->stop();
    270         } else {
    271             mAudioTrack->stop();
    272         }
    273 
    274         mNumFramesPlayed = 0;
    275         mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    276     } else {
    277         if (mAudioSink.get() != NULL) {
    278             mAudioSink->pause();
    279         } else {
    280             mAudioTrack->pause();
    281         }
    282 
    283         mPinnedTimeUs = ALooper::GetNowUs();
    284     }
    285 
    286     mPlaying = false;
    287 }
    288 
    289 status_t AudioPlayer::resume() {
    290     CHECK(mStarted);
    291     status_t err;
    292 
    293     if (mAudioSink.get() != NULL) {
    294         err = mAudioSink->start();
    295     } else {
    296         err = mAudioTrack->start();
    297     }
    298 
    299     if (err == OK) {
    300         mPlaying = true;
    301     }
    302 
    303     return err;
    304 }
    305 
    306 void AudioPlayer::reset() {
    307     CHECK(mStarted);
    308 
    309     ALOGV("reset: mPlaying=%d mReachedEOS=%d useOffload=%d",
    310                                 mPlaying, mReachedEOS, useOffload() );
    311 
    312     if (mAudioSink.get() != NULL) {
    313         mAudioSink->stop();
    314         // If we're closing and have reached EOS, we don't want to flush
    315         // the track because if it is offloaded there could be a small
    316         // amount of residual data in the hardware buffer which we must
    317         // play to give gapless playback.
    318         // But if we're resetting when paused or before we've reached EOS
    319         // we can't be doing a gapless playback and there could be a large
    320         // amount of data queued in the hardware if the track is offloaded,
    321         // so we must flush to prevent a track switch being delayed playing
    322         // the buffered data that we don't want now
    323         if (!mPlaying || !mReachedEOS) {
    324             mAudioSink->flush();
    325         }
    326 
    327         mAudioSink->close();
    328     } else {
    329         mAudioTrack->stop();
    330 
    331         if (!mPlaying || !mReachedEOS) {
    332             mAudioTrack->flush();
    333         }
    334 
    335         mAudioTrack.clear();
    336     }
    337 
    338     // Make sure to release any buffer we hold onto so that the
    339     // source is able to stop().
    340 
    341     if (mFirstBuffer != NULL) {
    342         mFirstBuffer->release();
    343         mFirstBuffer = NULL;
    344     }
    345 
    346     if (mInputBuffer != NULL) {
    347         ALOGV("AudioPlayer releasing input buffer.");
    348 
    349         mInputBuffer->release();
    350         mInputBuffer = NULL;
    351     }
    352 
    353     mSource->stop();
    354 
    355     // The following hack is necessary to ensure that the OMX
    356     // component is completely released by the time we may try
    357     // to instantiate it again.
    358     // When offloading, the OMX component is not used so this hack
    359     // is not needed
    360     if (!useOffload()) {
    361         wp<MediaSource> tmp = mSource;
    362         mSource.clear();
    363         while (tmp.promote() != NULL) {
    364             usleep(1000);
    365         }
    366     } else {
    367         mSource.clear();
    368     }
    369     IPCThreadState::self()->flushCommands();
    370 
    371     mNumFramesPlayed = 0;
    372     mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    373     mPositionTimeMediaUs = -1;
    374     mPositionTimeRealUs = -1;
    375     mSeeking = false;
    376     mSeekTimeUs = 0;
    377     mReachedEOS = false;
    378     mFinalStatus = OK;
    379     mStarted = false;
    380     mPlaying = false;
    381     mStartPosUs = 0;
    382 }
    383 
    384 // static
    385 void AudioPlayer::AudioCallback(int event, void *user, void *info) {
    386     static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
    387 }
    388 
    389 bool AudioPlayer::isSeeking() {
    390     Mutex::Autolock autoLock(mLock);
    391     return mSeeking;
    392 }
    393 
    394 bool AudioPlayer::reachedEOS(status_t *finalStatus) {
    395     *finalStatus = OK;
    396 
    397     Mutex::Autolock autoLock(mLock);
    398     *finalStatus = mFinalStatus;
    399     return mReachedEOS;
    400 }
    401 
    402 void AudioPlayer::notifyAudioEOS() {
    403     ALOGV("AudioPlayer@0x%p notifyAudioEOS", this);
    404 
    405     if (mObserver != NULL) {
    406         mObserver->postAudioEOS(0);
    407         ALOGV("Notified observer of EOS!");
    408     }
    409 }
    410 
    411 status_t AudioPlayer::setPlaybackRate(const AudioPlaybackRate &rate) {
    412     if (mAudioSink.get() != NULL) {
    413         return mAudioSink->setPlaybackRate(rate);
    414     } else if (mAudioTrack != 0){
    415         return mAudioTrack->setPlaybackRate(rate);
    416     } else {
    417         return NO_INIT;
    418     }
    419 }
    420 
    421 status_t AudioPlayer::getPlaybackRate(AudioPlaybackRate *rate /* nonnull */) {
    422     if (mAudioSink.get() != NULL) {
    423         return mAudioSink->getPlaybackRate(rate);
    424     } else if (mAudioTrack != 0) {
    425         *rate = mAudioTrack->getPlaybackRate();
    426         return OK;
    427     } else {
    428         return NO_INIT;
    429     }
    430 }
    431 
    432 // static
    433 size_t AudioPlayer::AudioSinkCallback(
    434         MediaPlayerBase::AudioSink * /* audioSink */,
    435         void *buffer, size_t size, void *cookie,
    436         MediaPlayerBase::AudioSink::cb_event_t event) {
    437     AudioPlayer *me = (AudioPlayer *)cookie;
    438 
    439     switch(event) {
    440     case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER:
    441         return me->fillBuffer(buffer, size);
    442 
    443     case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END:
    444         ALOGV("AudioSinkCallback: stream end");
    445         me->mReachedEOS = true;
    446         me->notifyAudioEOS();
    447         break;
    448 
    449     case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
    450         ALOGV("AudioSinkCallback: Tear down event");
    451         me->mObserver->postAudioTearDown();
    452         break;
    453     }
    454 
    455     return 0;
    456 }
    457 
    458 void AudioPlayer::AudioCallback(int event, void *info) {
    459     switch (event) {
    460     case AudioTrack::EVENT_MORE_DATA:
    461         {
    462         AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
    463         size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
    464         buffer->size = numBytesWritten;
    465         }
    466         break;
    467 
    468     case AudioTrack::EVENT_STREAM_END:
    469         mReachedEOS = true;
    470         notifyAudioEOS();
    471         break;
    472     }
    473 }
    474 
    475 uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
    476     uint32_t numFramesPlayedOut;
    477     status_t err;
    478 
    479     if (mAudioSink != NULL) {
    480         err = mAudioSink->getPosition(&numFramesPlayedOut);
    481     } else {
    482         err = mAudioTrack->getPosition(&numFramesPlayedOut);
    483     }
    484 
    485     if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
    486         return 0;
    487     }
    488 
    489     // mNumFramesPlayed is the number of frames submitted
    490     // to the audio sink for playback, but not all of them
    491     // may have played out by now.
    492     return mNumFramesPlayed - numFramesPlayedOut;
    493 }
    494 
    495 size_t AudioPlayer::fillBuffer(void *data, size_t size) {
    496     if (mNumFramesPlayed == 0) {
    497         ALOGV("AudioCallback");
    498     }
    499 
    500     if (mReachedEOS) {
    501         return 0;
    502     }
    503 
    504     bool postSeekComplete = false;
    505     bool postEOS = false;
    506     int64_t postEOSDelayUs = 0;
    507 
    508     size_t size_done = 0;
    509     size_t size_remaining = size;
    510     while (size_remaining > 0) {
    511         MediaSource::ReadOptions options;
    512         bool refreshSeekTime = false;
    513 
    514         {
    515             Mutex::Autolock autoLock(mLock);
    516 
    517             if (mSeeking) {
    518                 if (mIsFirstBuffer) {
    519                     if (mFirstBuffer != NULL) {
    520                         mFirstBuffer->release();
    521                         mFirstBuffer = NULL;
    522                     }
    523                     mIsFirstBuffer = false;
    524                 }
    525 
    526                 options.setSeekTo(mSeekTimeUs);
    527                 refreshSeekTime = true;
    528 
    529                 if (mInputBuffer != NULL) {
    530                     mInputBuffer->release();
    531                     mInputBuffer = NULL;
    532                 }
    533 
    534                 mSeeking = false;
    535                 if (mObserver) {
    536                     postSeekComplete = true;
    537                 }
    538             }
    539         }
    540 
    541         if (mInputBuffer == NULL) {
    542             status_t err;
    543 
    544             if (mIsFirstBuffer) {
    545                 mInputBuffer = mFirstBuffer;
    546                 mFirstBuffer = NULL;
    547                 err = mFirstBufferResult;
    548 
    549                 mIsFirstBuffer = false;
    550             } else {
    551                 err = mSource->read(&mInputBuffer, &options);
    552             }
    553 
    554             CHECK((err == OK && mInputBuffer != NULL)
    555                    || (err != OK && mInputBuffer == NULL));
    556 
    557             Mutex::Autolock autoLock(mLock);
    558 
    559             if (err != OK) {
    560                 if (!mReachedEOS) {
    561                     if (useOffload()) {
    562                         // no more buffers to push - stop() and wait for STREAM_END
    563                         // don't set mReachedEOS until stream end received
    564                         if (mAudioSink != NULL) {
    565                             mAudioSink->stop();
    566                         } else {
    567                             mAudioTrack->stop();
    568                         }
    569                     } else {
    570                         if (mObserver) {
    571                             // We don't want to post EOS right away but only
    572                             // after all frames have actually been played out.
    573 
    574                             // These are the number of frames submitted to the
    575                             // AudioTrack that you haven't heard yet.
    576                             uint32_t numFramesPendingPlayout =
    577                                 getNumFramesPendingPlayout();
    578 
    579                             // These are the number of frames we're going to
    580                             // submit to the AudioTrack by returning from this
    581                             // callback.
    582                             uint32_t numAdditionalFrames = size_done / mFrameSize;
    583 
    584                             numFramesPendingPlayout += numAdditionalFrames;
    585 
    586                             int64_t timeToCompletionUs =
    587                                 (1000000ll * numFramesPendingPlayout) / mSampleRate;
    588 
    589                             ALOGV("total number of frames played: %" PRId64 " (%lld us)",
    590                                     (mNumFramesPlayed + numAdditionalFrames),
    591                                     1000000ll * (mNumFramesPlayed + numAdditionalFrames)
    592                                         / mSampleRate);
    593 
    594                             ALOGV("%d frames left to play, %" PRId64 " us (%.2f secs)",
    595                                  numFramesPendingPlayout,
    596                                  timeToCompletionUs, timeToCompletionUs / 1E6);
    597 
    598                             postEOS = true;
    599                             if (mAudioSink->needsTrailingPadding()) {
    600                                 postEOSDelayUs = timeToCompletionUs + mLatencyUs;
    601                             } else {
    602                                 postEOSDelayUs = 0;
    603                             }
    604                         }
    605 
    606                         mReachedEOS = true;
    607                     }
    608                 }
    609 
    610                 mFinalStatus = err;
    611                 break;
    612             }
    613 
    614             if (mAudioSink != NULL) {
    615                 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
    616             } else {
    617                 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
    618             }
    619 
    620             if(mInputBuffer->range_length() != 0) {
    621                 CHECK(mInputBuffer->meta_data()->findInt64(
    622                         kKeyTime, &mPositionTimeMediaUs));
    623             }
    624 
    625             // need to adjust the mStartPosUs for offload decoding since parser
    626             // might not be able to get the exact seek time requested.
    627             if (refreshSeekTime) {
    628                 if (useOffload()) {
    629                     if (postSeekComplete) {
    630                         ALOGV("fillBuffer is going to post SEEK_COMPLETE");
    631                         mObserver->postAudioSeekComplete();
    632                         postSeekComplete = false;
    633                     }
    634 
    635                     mStartPosUs = mPositionTimeMediaUs;
    636                     ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6);
    637                 }
    638                 // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs
    639                 // and mPositionTimeRealUs
    640                 // before clearing mSeekTimeUs check if a new seek request has been received while
    641                 // we were reading from the source with mLock released.
    642                 if (!mSeeking) {
    643                     mSeekTimeUs = 0;
    644                 }
    645             }
    646 
    647             if (!useOffload()) {
    648                 mPositionTimeRealUs =
    649                     ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
    650                         / mSampleRate;
    651                 ALOGV("buffer->size() = %zu, "
    652                      "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
    653                      mInputBuffer->range_length(),
    654                      mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
    655             }
    656 
    657         }
    658 
    659         if (mInputBuffer->range_length() == 0) {
    660             mInputBuffer->release();
    661             mInputBuffer = NULL;
    662 
    663             continue;
    664         }
    665 
    666         size_t copy = size_remaining;
    667         if (copy > mInputBuffer->range_length()) {
    668             copy = mInputBuffer->range_length();
    669         }
    670 
    671         memcpy((char *)data + size_done,
    672                (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
    673                copy);
    674 
    675         mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
    676                                 mInputBuffer->range_length() - copy);
    677 
    678         size_done += copy;
    679         size_remaining -= copy;
    680     }
    681 
    682     if (useOffload()) {
    683         // We must ask the hardware what it has played
    684         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    685         ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
    686              mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
    687     }
    688 
    689     {
    690         Mutex::Autolock autoLock(mLock);
    691         mNumFramesPlayed += size_done / mFrameSize;
    692         mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    693 
    694         if (mReachedEOS) {
    695             mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
    696         } else {
    697             mPinnedTimeUs = -1ll;
    698         }
    699     }
    700 
    701     if (postEOS) {
    702         mObserver->postAudioEOS(postEOSDelayUs);
    703     }
    704 
    705     if (postSeekComplete) {
    706         mObserver->postAudioSeekComplete();
    707     }
    708 
    709     return size_done;
    710 }
    711 
    712 int64_t AudioPlayer::getRealTimeUs() {
    713     Mutex::Autolock autoLock(mLock);
    714     if (useOffload()) {
    715         if (mSeeking) {
    716             return mSeekTimeUs;
    717         }
    718         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    719         return mPositionTimeRealUs;
    720     }
    721 
    722     return getRealTimeUsLocked();
    723 }
    724 
    725 int64_t AudioPlayer::getRealTimeUsLocked() const {
    726     CHECK(mStarted);
    727     CHECK_NE(mSampleRate, 0);
    728     int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
    729 
    730     // Compensate for large audio buffers, updates of mNumFramesPlayed
    731     // are less frequent, therefore to get a "smoother" notion of time we
    732     // compensate using system time.
    733     int64_t diffUs;
    734     if (mPinnedTimeUs >= 0ll) {
    735         diffUs = mPinnedTimeUs;
    736     } else {
    737         diffUs = ALooper::GetNowUs();
    738     }
    739 
    740     diffUs -= mNumFramesPlayedSysTimeUs;
    741 
    742     return result + diffUs;
    743 }
    744 
    745 int64_t AudioPlayer::getOutputPlayPositionUs_l()
    746 {
    747     uint32_t playedSamples = 0;
    748     uint32_t sampleRate;
    749     if (mAudioSink != NULL) {
    750         mAudioSink->getPosition(&playedSamples);
    751         sampleRate = mAudioSink->getSampleRate();
    752     } else {
    753         mAudioTrack->getPosition(&playedSamples);
    754         sampleRate = mAudioTrack->getSampleRate();
    755     }
    756     if (sampleRate != 0) {
    757         mSampleRate = sampleRate;
    758     }
    759 
    760     int64_t playedUs;
    761     if (mSampleRate != 0) {
    762         playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
    763     } else {
    764         playedUs = 0;
    765     }
    766 
    767     // HAL position is relative to the first buffer we sent at mStartPosUs
    768     const int64_t renderedDuration = mStartPosUs + playedUs;
    769     ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration);
    770     return renderedDuration;
    771 }
    772 
    773 int64_t AudioPlayer::getMediaTimeUs() {
    774     Mutex::Autolock autoLock(mLock);
    775 
    776     if (useOffload()) {
    777         if (mSeeking) {
    778             return mSeekTimeUs;
    779         }
    780         if (mReachedEOS) {
    781             int64_t durationUs;
    782             mSource->getFormat()->findInt64(kKeyDuration, &durationUs);
    783             return durationUs;
    784         }
    785         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    786         ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64,
    787               mPositionTimeRealUs);
    788         return mPositionTimeRealUs;
    789     }
    790 
    791 
    792     if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
    793         // mSeekTimeUs is either seek time while seeking or 0 if playback did not start.
    794         return mSeekTimeUs;
    795     }
    796 
    797     int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
    798     if (realTimeOffset < 0) {
    799         realTimeOffset = 0;
    800     }
    801 
    802     return mPositionTimeMediaUs + realTimeOffset;
    803 }
    804 
    805 bool AudioPlayer::getMediaTimeMapping(
    806         int64_t *realtime_us, int64_t *mediatime_us) {
    807     Mutex::Autolock autoLock(mLock);
    808 
    809     if (useOffload()) {
    810         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    811         *realtime_us = mPositionTimeRealUs;
    812         *mediatime_us = mPositionTimeRealUs;
    813     } else {
    814         *realtime_us = mPositionTimeRealUs;
    815         *mediatime_us = mPositionTimeMediaUs;
    816     }
    817 
    818     return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
    819 }
    820 
    821 status_t AudioPlayer::seekTo(int64_t time_us) {
    822     Mutex::Autolock autoLock(mLock);
    823 
    824     ALOGV("seekTo( %" PRId64 " )", time_us);
    825 
    826     mSeeking = true;
    827     mPositionTimeRealUs = mPositionTimeMediaUs = -1;
    828     mReachedEOS = false;
    829     mSeekTimeUs = time_us;
    830     mStartPosUs = time_us;
    831 
    832     // Flush resets the number of played frames
    833     mNumFramesPlayed = 0;
    834     mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    835 
    836     if (mAudioSink != NULL) {
    837         if (mPlaying) {
    838             mAudioSink->pause();
    839         }
    840         mAudioSink->flush();
    841         if (mPlaying) {
    842             mAudioSink->start();
    843         }
    844     } else {
    845         if (mPlaying) {
    846             mAudioTrack->pause();
    847         }
    848         mAudioTrack->flush();
    849         if (mPlaying) {
    850             mAudioTrack->start();
    851         }
    852     }
    853 
    854     return OK;
    855 }
    856 
    857 }
    858