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