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::setPlaybackRatePermille(int32_t ratePermille) {
    412     if (mAudioSink.get() != NULL) {
    413         return mAudioSink->setPlaybackRatePermille(ratePermille);
    414     } else if (mAudioTrack != 0){
    415         return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
    416     } else {
    417         return NO_INIT;
    418     }
    419 }
    420 
    421 // static
    422 size_t AudioPlayer::AudioSinkCallback(
    423         MediaPlayerBase::AudioSink * /* audioSink */,
    424         void *buffer, size_t size, void *cookie,
    425         MediaPlayerBase::AudioSink::cb_event_t event) {
    426     AudioPlayer *me = (AudioPlayer *)cookie;
    427 
    428     switch(event) {
    429     case MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER:
    430         return me->fillBuffer(buffer, size);
    431 
    432     case MediaPlayerBase::AudioSink::CB_EVENT_STREAM_END:
    433         ALOGV("AudioSinkCallback: stream end");
    434         me->mReachedEOS = true;
    435         me->notifyAudioEOS();
    436         break;
    437 
    438     case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
    439         ALOGV("AudioSinkCallback: Tear down event");
    440         me->mObserver->postAudioTearDown();
    441         break;
    442     }
    443 
    444     return 0;
    445 }
    446 
    447 void AudioPlayer::AudioCallback(int event, void *info) {
    448     switch (event) {
    449     case AudioTrack::EVENT_MORE_DATA:
    450         {
    451         AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
    452         size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
    453         buffer->size = numBytesWritten;
    454         }
    455         break;
    456 
    457     case AudioTrack::EVENT_STREAM_END:
    458         mReachedEOS = true;
    459         notifyAudioEOS();
    460         break;
    461     }
    462 }
    463 
    464 uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
    465     uint32_t numFramesPlayedOut;
    466     status_t err;
    467 
    468     if (mAudioSink != NULL) {
    469         err = mAudioSink->getPosition(&numFramesPlayedOut);
    470     } else {
    471         err = mAudioTrack->getPosition(&numFramesPlayedOut);
    472     }
    473 
    474     if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
    475         return 0;
    476     }
    477 
    478     // mNumFramesPlayed is the number of frames submitted
    479     // to the audio sink for playback, but not all of them
    480     // may have played out by now.
    481     return mNumFramesPlayed - numFramesPlayedOut;
    482 }
    483 
    484 size_t AudioPlayer::fillBuffer(void *data, size_t size) {
    485     if (mNumFramesPlayed == 0) {
    486         ALOGV("AudioCallback");
    487     }
    488 
    489     if (mReachedEOS) {
    490         return 0;
    491     }
    492 
    493     bool postSeekComplete = false;
    494     bool postEOS = false;
    495     int64_t postEOSDelayUs = 0;
    496 
    497     size_t size_done = 0;
    498     size_t size_remaining = size;
    499     while (size_remaining > 0) {
    500         MediaSource::ReadOptions options;
    501         bool refreshSeekTime = false;
    502 
    503         {
    504             Mutex::Autolock autoLock(mLock);
    505 
    506             if (mSeeking) {
    507                 if (mIsFirstBuffer) {
    508                     if (mFirstBuffer != NULL) {
    509                         mFirstBuffer->release();
    510                         mFirstBuffer = NULL;
    511                     }
    512                     mIsFirstBuffer = false;
    513                 }
    514 
    515                 options.setSeekTo(mSeekTimeUs);
    516                 refreshSeekTime = true;
    517 
    518                 if (mInputBuffer != NULL) {
    519                     mInputBuffer->release();
    520                     mInputBuffer = NULL;
    521                 }
    522 
    523                 mSeeking = false;
    524                 if (mObserver) {
    525                     postSeekComplete = true;
    526                 }
    527             }
    528         }
    529 
    530         if (mInputBuffer == NULL) {
    531             status_t err;
    532 
    533             if (mIsFirstBuffer) {
    534                 mInputBuffer = mFirstBuffer;
    535                 mFirstBuffer = NULL;
    536                 err = mFirstBufferResult;
    537 
    538                 mIsFirstBuffer = false;
    539             } else {
    540                 err = mSource->read(&mInputBuffer, &options);
    541             }
    542 
    543             CHECK((err == OK && mInputBuffer != NULL)
    544                    || (err != OK && mInputBuffer == NULL));
    545 
    546             Mutex::Autolock autoLock(mLock);
    547 
    548             if (err != OK) {
    549                 if (!mReachedEOS) {
    550                     if (useOffload()) {
    551                         // no more buffers to push - stop() and wait for STREAM_END
    552                         // don't set mReachedEOS until stream end received
    553                         if (mAudioSink != NULL) {
    554                             mAudioSink->stop();
    555                         } else {
    556                             mAudioTrack->stop();
    557                         }
    558                     } else {
    559                         if (mObserver) {
    560                             // We don't want to post EOS right away but only
    561                             // after all frames have actually been played out.
    562 
    563                             // These are the number of frames submitted to the
    564                             // AudioTrack that you haven't heard yet.
    565                             uint32_t numFramesPendingPlayout =
    566                                 getNumFramesPendingPlayout();
    567 
    568                             // These are the number of frames we're going to
    569                             // submit to the AudioTrack by returning from this
    570                             // callback.
    571                             uint32_t numAdditionalFrames = size_done / mFrameSize;
    572 
    573                             numFramesPendingPlayout += numAdditionalFrames;
    574 
    575                             int64_t timeToCompletionUs =
    576                                 (1000000ll * numFramesPendingPlayout) / mSampleRate;
    577 
    578                             ALOGV("total number of frames played: %" PRId64 " (%lld us)",
    579                                     (mNumFramesPlayed + numAdditionalFrames),
    580                                     1000000ll * (mNumFramesPlayed + numAdditionalFrames)
    581                                         / mSampleRate);
    582 
    583                             ALOGV("%d frames left to play, %" PRId64 " us (%.2f secs)",
    584                                  numFramesPendingPlayout,
    585                                  timeToCompletionUs, timeToCompletionUs / 1E6);
    586 
    587                             postEOS = true;
    588                             if (mAudioSink->needsTrailingPadding()) {
    589                                 postEOSDelayUs = timeToCompletionUs + mLatencyUs;
    590                             } else {
    591                                 postEOSDelayUs = 0;
    592                             }
    593                         }
    594 
    595                         mReachedEOS = true;
    596                     }
    597                 }
    598 
    599                 mFinalStatus = err;
    600                 break;
    601             }
    602 
    603             if (mAudioSink != NULL) {
    604                 mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
    605             } else {
    606                 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
    607             }
    608 
    609             if(mInputBuffer->range_length() != 0) {
    610                 CHECK(mInputBuffer->meta_data()->findInt64(
    611                         kKeyTime, &mPositionTimeMediaUs));
    612             }
    613 
    614             // need to adjust the mStartPosUs for offload decoding since parser
    615             // might not be able to get the exact seek time requested.
    616             if (refreshSeekTime) {
    617                 if (useOffload()) {
    618                     if (postSeekComplete) {
    619                         ALOGV("fillBuffer is going to post SEEK_COMPLETE");
    620                         mObserver->postAudioSeekComplete();
    621                         postSeekComplete = false;
    622                     }
    623 
    624                     mStartPosUs = mPositionTimeMediaUs;
    625                     ALOGV("adjust seek time to: %.2f", mStartPosUs/ 1E6);
    626                 }
    627                 // clear seek time with mLock locked and once we have valid mPositionTimeMediaUs
    628                 // and mPositionTimeRealUs
    629                 // before clearing mSeekTimeUs check if a new seek request has been received while
    630                 // we were reading from the source with mLock released.
    631                 if (!mSeeking) {
    632                     mSeekTimeUs = 0;
    633                 }
    634             }
    635 
    636             if (!useOffload()) {
    637                 mPositionTimeRealUs =
    638                     ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
    639                         / mSampleRate;
    640                 ALOGV("buffer->size() = %zu, "
    641                      "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
    642                      mInputBuffer->range_length(),
    643                      mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
    644             }
    645 
    646         }
    647 
    648         if (mInputBuffer->range_length() == 0) {
    649             mInputBuffer->release();
    650             mInputBuffer = NULL;
    651 
    652             continue;
    653         }
    654 
    655         size_t copy = size_remaining;
    656         if (copy > mInputBuffer->range_length()) {
    657             copy = mInputBuffer->range_length();
    658         }
    659 
    660         memcpy((char *)data + size_done,
    661                (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
    662                copy);
    663 
    664         mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
    665                                 mInputBuffer->range_length() - copy);
    666 
    667         size_done += copy;
    668         size_remaining -= copy;
    669     }
    670 
    671     if (useOffload()) {
    672         // We must ask the hardware what it has played
    673         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    674         ALOGV("mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
    675              mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
    676     }
    677 
    678     {
    679         Mutex::Autolock autoLock(mLock);
    680         mNumFramesPlayed += size_done / mFrameSize;
    681         mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    682 
    683         if (mReachedEOS) {
    684             mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
    685         } else {
    686             mPinnedTimeUs = -1ll;
    687         }
    688     }
    689 
    690     if (postEOS) {
    691         mObserver->postAudioEOS(postEOSDelayUs);
    692     }
    693 
    694     if (postSeekComplete) {
    695         mObserver->postAudioSeekComplete();
    696     }
    697 
    698     return size_done;
    699 }
    700 
    701 int64_t AudioPlayer::getRealTimeUs() {
    702     Mutex::Autolock autoLock(mLock);
    703     if (useOffload()) {
    704         if (mSeeking) {
    705             return mSeekTimeUs;
    706         }
    707         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    708         return mPositionTimeRealUs;
    709     }
    710 
    711     return getRealTimeUsLocked();
    712 }
    713 
    714 int64_t AudioPlayer::getRealTimeUsLocked() const {
    715     CHECK(mStarted);
    716     CHECK_NE(mSampleRate, 0);
    717     int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
    718 
    719     // Compensate for large audio buffers, updates of mNumFramesPlayed
    720     // are less frequent, therefore to get a "smoother" notion of time we
    721     // compensate using system time.
    722     int64_t diffUs;
    723     if (mPinnedTimeUs >= 0ll) {
    724         diffUs = mPinnedTimeUs;
    725     } else {
    726         diffUs = ALooper::GetNowUs();
    727     }
    728 
    729     diffUs -= mNumFramesPlayedSysTimeUs;
    730 
    731     return result + diffUs;
    732 }
    733 
    734 int64_t AudioPlayer::getOutputPlayPositionUs_l()
    735 {
    736     uint32_t playedSamples = 0;
    737     uint32_t sampleRate;
    738     if (mAudioSink != NULL) {
    739         mAudioSink->getPosition(&playedSamples);
    740         sampleRate = mAudioSink->getSampleRate();
    741     } else {
    742         mAudioTrack->getPosition(&playedSamples);
    743         sampleRate = mAudioTrack->getSampleRate();
    744     }
    745     if (sampleRate != 0) {
    746         mSampleRate = sampleRate;
    747     }
    748 
    749     int64_t playedUs;
    750     if (mSampleRate != 0) {
    751         playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
    752     } else {
    753         playedUs = 0;
    754     }
    755 
    756     // HAL position is relative to the first buffer we sent at mStartPosUs
    757     const int64_t renderedDuration = mStartPosUs + playedUs;
    758     ALOGV("getOutputPlayPositionUs_l %" PRId64, renderedDuration);
    759     return renderedDuration;
    760 }
    761 
    762 int64_t AudioPlayer::getMediaTimeUs() {
    763     Mutex::Autolock autoLock(mLock);
    764 
    765     if (useOffload()) {
    766         if (mSeeking) {
    767             return mSeekTimeUs;
    768         }
    769         if (mReachedEOS) {
    770             int64_t durationUs;
    771             mSource->getFormat()->findInt64(kKeyDuration, &durationUs);
    772             return durationUs;
    773         }
    774         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    775         ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64,
    776               mPositionTimeRealUs);
    777         return mPositionTimeRealUs;
    778     }
    779 
    780 
    781     if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
    782         // mSeekTimeUs is either seek time while seeking or 0 if playback did not start.
    783         return mSeekTimeUs;
    784     }
    785 
    786     int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
    787     if (realTimeOffset < 0) {
    788         realTimeOffset = 0;
    789     }
    790 
    791     return mPositionTimeMediaUs + realTimeOffset;
    792 }
    793 
    794 bool AudioPlayer::getMediaTimeMapping(
    795         int64_t *realtime_us, int64_t *mediatime_us) {
    796     Mutex::Autolock autoLock(mLock);
    797 
    798     if (useOffload()) {
    799         mPositionTimeRealUs = getOutputPlayPositionUs_l();
    800         *realtime_us = mPositionTimeRealUs;
    801         *mediatime_us = mPositionTimeRealUs;
    802     } else {
    803         *realtime_us = mPositionTimeRealUs;
    804         *mediatime_us = mPositionTimeMediaUs;
    805     }
    806 
    807     return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
    808 }
    809 
    810 status_t AudioPlayer::seekTo(int64_t time_us) {
    811     Mutex::Autolock autoLock(mLock);
    812 
    813     ALOGV("seekTo( %" PRId64 " )", time_us);
    814 
    815     mSeeking = true;
    816     mPositionTimeRealUs = mPositionTimeMediaUs = -1;
    817     mReachedEOS = false;
    818     mSeekTimeUs = time_us;
    819     mStartPosUs = time_us;
    820 
    821     // Flush resets the number of played frames
    822     mNumFramesPlayed = 0;
    823     mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
    824 
    825     if (mAudioSink != NULL) {
    826         if (mPlaying) {
    827             mAudioSink->pause();
    828         }
    829         mAudioSink->flush();
    830         if (mPlaying) {
    831             mAudioSink->start();
    832         }
    833     } else {
    834         if (mPlaying) {
    835             mAudioTrack->pause();
    836         }
    837         mAudioTrack->flush();
    838         if (mPlaying) {
    839             mAudioTrack->start();
    840         }
    841     }
    842 
    843     return OK;
    844 }
    845 
    846 }
    847