AudioPlayer.cpp revision 2829edccd7d2bb8244246f316face82b650b8949
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
38namespace android {
39
40AudioPlayer::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
68AudioPlayer::~AudioPlayer() {
69    if (mStarted) {
70        reset();
71    }
72}
73
74void AudioPlayer::setSource(const sp<MediaSource> &source) {
75    CHECK(mSource == NULL);
76    mSource = source;
77}
78
79status_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
264void 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
289status_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
306void 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
385void AudioPlayer::AudioCallback(int event, void *user, void *info) {
386    static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
387}
388
389bool AudioPlayer::isSeeking() {
390    Mutex::Autolock autoLock(mLock);
391    return mSeeking;
392}
393
394bool AudioPlayer::reachedEOS(status_t *finalStatus) {
395    *finalStatus = OK;
396
397    Mutex::Autolock autoLock(mLock);
398    *finalStatus = mFinalStatus;
399    return mReachedEOS;
400}
401
402void 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
411status_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
422size_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
447void 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
464uint32_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
484size_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
701int64_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
714int64_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
734int64_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
762int64_t AudioPlayer::getMediaTimeUs() {
763    Mutex::Autolock autoLock(mLock);
764
765    if (useOffload()) {
766        if (mSeeking) {
767            return mSeekTimeUs;
768        }
769        mPositionTimeRealUs = getOutputPlayPositionUs_l();
770        ALOGV("getMediaTimeUs getOutputPlayPositionUs_l() mPositionTimeRealUs %" PRId64,
771              mPositionTimeRealUs);
772        return mPositionTimeRealUs;
773    }
774
775
776    if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
777        // mSeekTimeUs is either seek time while seeking or 0 if playback did not start.
778        return mSeekTimeUs;
779    }
780
781    int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
782    if (realTimeOffset < 0) {
783        realTimeOffset = 0;
784    }
785
786    return mPositionTimeMediaUs + realTimeOffset;
787}
788
789bool AudioPlayer::getMediaTimeMapping(
790        int64_t *realtime_us, int64_t *mediatime_us) {
791    Mutex::Autolock autoLock(mLock);
792
793    if (useOffload()) {
794        mPositionTimeRealUs = getOutputPlayPositionUs_l();
795        *realtime_us = mPositionTimeRealUs;
796        *mediatime_us = mPositionTimeRealUs;
797    } else {
798        *realtime_us = mPositionTimeRealUs;
799        *mediatime_us = mPositionTimeMediaUs;
800    }
801
802    return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
803}
804
805status_t AudioPlayer::seekTo(int64_t time_us) {
806    Mutex::Autolock autoLock(mLock);
807
808    ALOGV("seekTo( %" PRId64 " )", time_us);
809
810    mSeeking = true;
811    mPositionTimeRealUs = mPositionTimeMediaUs = -1;
812    mReachedEOS = false;
813    mSeekTimeUs = time_us;
814    mStartPosUs = time_us;
815
816    // Flush resets the number of played frames
817    mNumFramesPlayed = 0;
818    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
819
820    if (mAudioSink != NULL) {
821        if (mPlaying) {
822            mAudioSink->pause();
823        }
824        mAudioSink->flush();
825        if (mPlaying) {
826            mAudioSink->start();
827        }
828    } else {
829        if (mPlaying) {
830            mAudioTrack->pause();
831        }
832        mAudioTrack->flush();
833        if (mPlaying) {
834            mAudioTrack->start();
835        }
836    }
837
838    return OK;
839}
840
841}
842