AudioPlayer.cpp revision e4451a91a61a341014f5eff61db356156c3ecb37
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
21#include <binder/IPCThreadState.h>
22#include <media/AudioTrack.h>
23#include <media/stagefright/foundation/ADebug.h>
24#include <media/stagefright/foundation/ALooper.h>
25#include <media/stagefright/AudioPlayer.h>
26#include <media/stagefright/MediaDefs.h>
27#include <media/stagefright/MediaErrors.h>
28#include <media/stagefright/MediaSource.h>
29#include <media/stagefright/MetaData.h>
30
31#include "include/AwesomePlayer.h"
32
33namespace android {
34
35AudioPlayer::AudioPlayer(
36        const sp<MediaPlayerBase::AudioSink> &audioSink,
37        bool allowDeepBuffering,
38        AwesomePlayer *observer)
39    : mAudioTrack(NULL),
40      mInputBuffer(NULL),
41      mSampleRate(0),
42      mLatencyUs(0),
43      mFrameSize(0),
44      mNumFramesPlayed(0),
45      mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
46      mPositionTimeMediaUs(-1),
47      mPositionTimeRealUs(-1),
48      mSeeking(false),
49      mReachedEOS(false),
50      mFinalStatus(OK),
51      mStarted(false),
52      mIsFirstBuffer(false),
53      mFirstBufferResult(OK),
54      mFirstBuffer(NULL),
55      mAudioSink(audioSink),
56      mAllowDeepBuffering(allowDeepBuffering),
57      mObserver(observer) {
58}
59
60AudioPlayer::~AudioPlayer() {
61    if (mStarted) {
62        reset();
63    }
64}
65
66void AudioPlayer::setSource(const sp<MediaSource> &source) {
67    CHECK(mSource == NULL);
68    mSource = source;
69}
70
71status_t AudioPlayer::start(bool sourceAlreadyStarted) {
72    CHECK(!mStarted);
73    CHECK(mSource != NULL);
74
75    status_t err;
76    if (!sourceAlreadyStarted) {
77        err = mSource->start();
78
79        if (err != OK) {
80            return err;
81        }
82    }
83
84    // We allow an optional INFO_FORMAT_CHANGED at the very beginning
85    // of playback, if there is one, getFormat below will retrieve the
86    // updated format, if there isn't, we'll stash away the valid buffer
87    // of data to be used on the first audio callback.
88
89    CHECK(mFirstBuffer == NULL);
90
91    MediaSource::ReadOptions options;
92    if (mSeeking) {
93        options.setSeekTo(mSeekTimeUs);
94        mSeeking = false;
95    }
96
97    mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
98    if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
99        ALOGV("INFO_FORMAT_CHANGED!!!");
100
101        CHECK(mFirstBuffer == NULL);
102        mFirstBufferResult = OK;
103        mIsFirstBuffer = false;
104    } else {
105        mIsFirstBuffer = true;
106    }
107
108    sp<MetaData> format = mSource->getFormat();
109    const char *mime;
110    bool success = format->findCString(kKeyMIMEType, &mime);
111    CHECK(success);
112    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
113
114    success = format->findInt32(kKeySampleRate, &mSampleRate);
115    CHECK(success);
116
117    int32_t numChannels, channelMask;
118    success = format->findInt32(kKeyChannelCount, &numChannels);
119    CHECK(success);
120
121    if(!format->findInt32(kKeyChannelMask, &channelMask)) {
122        // log only when there's a risk of ambiguity of channel mask selection
123        ALOGI_IF(numChannels > 2,
124                "source format didn't specify channel mask, using (%d) channel order", numChannels);
125        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
126    }
127
128    if (mAudioSink.get() != NULL) {
129
130        status_t err = mAudioSink->open(
131                mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT,
132                DEFAULT_AUDIOSINK_BUFFERCOUNT,
133                &AudioPlayer::AudioSinkCallback,
134                this,
135                (mAllowDeepBuffering ?
136                            AUDIO_OUTPUT_FLAG_DEEP_BUFFER :
137                            AUDIO_OUTPUT_FLAG_NONE));
138        if (err != OK) {
139            if (mFirstBuffer != NULL) {
140                mFirstBuffer->release();
141                mFirstBuffer = NULL;
142            }
143
144            if (!sourceAlreadyStarted) {
145                mSource->stop();
146            }
147
148            return err;
149        }
150
151        mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
152        mFrameSize = mAudioSink->frameSize();
153
154        mAudioSink->start();
155    } else {
156        // playing to an AudioTrack, set up mask if necessary
157        audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
158                audio_channel_out_mask_from_count(numChannels) : channelMask;
159        if (0 == audioMask) {
160            return BAD_VALUE;
161        }
162
163        mAudioTrack = new AudioTrack(
164                AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
165                0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
166
167        if ((err = mAudioTrack->initCheck()) != OK) {
168            delete mAudioTrack;
169            mAudioTrack = NULL;
170
171            if (mFirstBuffer != NULL) {
172                mFirstBuffer->release();
173                mFirstBuffer = NULL;
174            }
175
176            if (!sourceAlreadyStarted) {
177                mSource->stop();
178            }
179
180            return err;
181        }
182
183        mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
184        mFrameSize = mAudioTrack->frameSize();
185
186        mAudioTrack->start();
187    }
188
189    mStarted = true;
190
191    return OK;
192}
193
194void AudioPlayer::pause(bool playPendingSamples) {
195    CHECK(mStarted);
196
197    if (playPendingSamples) {
198        if (mAudioSink.get() != NULL) {
199            mAudioSink->stop();
200        } else {
201            mAudioTrack->stop();
202        }
203
204        mNumFramesPlayed = 0;
205        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
206    } else {
207        if (mAudioSink.get() != NULL) {
208            mAudioSink->pause();
209        } else {
210            mAudioTrack->pause();
211        }
212    }
213}
214
215void AudioPlayer::resume() {
216    CHECK(mStarted);
217
218    if (mAudioSink.get() != NULL) {
219        mAudioSink->start();
220    } else {
221        mAudioTrack->start();
222    }
223}
224
225void AudioPlayer::reset() {
226    CHECK(mStarted);
227
228    if (mAudioSink.get() != NULL) {
229        mAudioSink->stop();
230        mAudioSink->close();
231    } else {
232        mAudioTrack->stop();
233
234        delete mAudioTrack;
235        mAudioTrack = NULL;
236    }
237
238    // Make sure to release any buffer we hold onto so that the
239    // source is able to stop().
240
241    if (mFirstBuffer != NULL) {
242        mFirstBuffer->release();
243        mFirstBuffer = NULL;
244    }
245
246    if (mInputBuffer != NULL) {
247        ALOGV("AudioPlayer releasing input buffer.");
248
249        mInputBuffer->release();
250        mInputBuffer = NULL;
251    }
252
253    mSource->stop();
254
255    // The following hack is necessary to ensure that the OMX
256    // component is completely released by the time we may try
257    // to instantiate it again.
258    wp<MediaSource> tmp = mSource;
259    mSource.clear();
260    while (tmp.promote() != NULL) {
261        usleep(1000);
262    }
263    IPCThreadState::self()->flushCommands();
264
265    mNumFramesPlayed = 0;
266    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
267    mPositionTimeMediaUs = -1;
268    mPositionTimeRealUs = -1;
269    mSeeking = false;
270    mReachedEOS = false;
271    mFinalStatus = OK;
272    mStarted = false;
273}
274
275// static
276void AudioPlayer::AudioCallback(int event, void *user, void *info) {
277    static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
278}
279
280bool AudioPlayer::isSeeking() {
281    Mutex::Autolock autoLock(mLock);
282    return mSeeking;
283}
284
285bool AudioPlayer::reachedEOS(status_t *finalStatus) {
286    *finalStatus = OK;
287
288    Mutex::Autolock autoLock(mLock);
289    *finalStatus = mFinalStatus;
290    return mReachedEOS;
291}
292
293status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
294    if (mAudioSink.get() != NULL) {
295        return mAudioSink->setPlaybackRatePermille(ratePermille);
296    } else if (mAudioTrack != NULL){
297        return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
298    } else {
299        return NO_INIT;
300    }
301}
302
303// static
304size_t AudioPlayer::AudioSinkCallback(
305        MediaPlayerBase::AudioSink *audioSink,
306        void *buffer, size_t size, void *cookie) {
307    AudioPlayer *me = (AudioPlayer *)cookie;
308
309    return me->fillBuffer(buffer, size);
310}
311
312void AudioPlayer::AudioCallback(int event, void *info) {
313    if (event != AudioTrack::EVENT_MORE_DATA) {
314        return;
315    }
316
317    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
318    size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
319
320    buffer->size = numBytesWritten;
321}
322
323uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
324    uint32_t numFramesPlayedOut;
325    status_t err;
326
327    if (mAudioSink != NULL) {
328        err = mAudioSink->getPosition(&numFramesPlayedOut);
329    } else {
330        err = mAudioTrack->getPosition(&numFramesPlayedOut);
331    }
332
333    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
334        return 0;
335    }
336
337    // mNumFramesPlayed is the number of frames submitted
338    // to the audio sink for playback, but not all of them
339    // may have played out by now.
340    return mNumFramesPlayed - numFramesPlayedOut;
341}
342
343size_t AudioPlayer::fillBuffer(void *data, size_t size) {
344    if (mNumFramesPlayed == 0) {
345        ALOGV("AudioCallback");
346    }
347
348    if (mReachedEOS) {
349        return 0;
350    }
351
352    bool postSeekComplete = false;
353    bool postEOS = false;
354    int64_t postEOSDelayUs = 0;
355
356    size_t size_done = 0;
357    size_t size_remaining = size;
358    while (size_remaining > 0) {
359        MediaSource::ReadOptions options;
360
361        {
362            Mutex::Autolock autoLock(mLock);
363
364            if (mSeeking) {
365                if (mIsFirstBuffer) {
366                    if (mFirstBuffer != NULL) {
367                        mFirstBuffer->release();
368                        mFirstBuffer = NULL;
369                    }
370                    mIsFirstBuffer = false;
371                }
372
373                options.setSeekTo(mSeekTimeUs);
374
375                if (mInputBuffer != NULL) {
376                    mInputBuffer->release();
377                    mInputBuffer = NULL;
378                }
379
380                mSeeking = false;
381                if (mObserver) {
382                    postSeekComplete = true;
383                }
384            }
385        }
386
387        if (mInputBuffer == NULL) {
388            status_t err;
389
390            if (mIsFirstBuffer) {
391                mInputBuffer = mFirstBuffer;
392                mFirstBuffer = NULL;
393                err = mFirstBufferResult;
394
395                mIsFirstBuffer = false;
396            } else {
397                err = mSource->read(&mInputBuffer, &options);
398            }
399
400            CHECK((err == OK && mInputBuffer != NULL)
401                   || (err != OK && mInputBuffer == NULL));
402
403            Mutex::Autolock autoLock(mLock);
404
405            if (err != OK) {
406                if (mObserver && !mReachedEOS) {
407                    // We don't want to post EOS right away but only
408                    // after all frames have actually been played out.
409
410                    // These are the number of frames submitted to the
411                    // AudioTrack that you haven't heard yet.
412                    uint32_t numFramesPendingPlayout =
413                        getNumFramesPendingPlayout();
414
415                    // These are the number of frames we're going to
416                    // submit to the AudioTrack by returning from this
417                    // callback.
418                    uint32_t numAdditionalFrames = size_done / mFrameSize;
419
420                    numFramesPendingPlayout += numAdditionalFrames;
421
422                    int64_t timeToCompletionUs =
423                        (1000000ll * numFramesPendingPlayout) / mSampleRate;
424
425                    ALOGV("total number of frames played: %lld (%lld us)",
426                            (mNumFramesPlayed + numAdditionalFrames),
427                            1000000ll * (mNumFramesPlayed + numAdditionalFrames)
428                                / mSampleRate);
429
430                    ALOGV("%d frames left to play, %lld us (%.2f secs)",
431                         numFramesPendingPlayout,
432                         timeToCompletionUs, timeToCompletionUs / 1E6);
433
434                    postEOS = true;
435                    if (mAudioSink->needsTrailingPadding()) {
436                        postEOSDelayUs = timeToCompletionUs + mLatencyUs;
437                    } else {
438                        postEOSDelayUs = 0;
439                    }
440                }
441
442                mReachedEOS = true;
443                mFinalStatus = err;
444                break;
445            }
446
447            if (mAudioSink != NULL) {
448                mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
449            } else {
450                mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
451            }
452
453            CHECK(mInputBuffer->meta_data()->findInt64(
454                        kKeyTime, &mPositionTimeMediaUs));
455
456            mPositionTimeRealUs =
457                ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
458                    / mSampleRate;
459
460            ALOGV("buffer->size() = %d, "
461                 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
462                 mInputBuffer->range_length(),
463                 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
464        }
465
466        if (mInputBuffer->range_length() == 0) {
467            mInputBuffer->release();
468            mInputBuffer = NULL;
469
470            continue;
471        }
472
473        size_t copy = size_remaining;
474        if (copy > mInputBuffer->range_length()) {
475            copy = mInputBuffer->range_length();
476        }
477
478        memcpy((char *)data + size_done,
479               (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
480               copy);
481
482        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
483                                mInputBuffer->range_length() - copy);
484
485        size_done += copy;
486        size_remaining -= copy;
487    }
488
489    {
490        Mutex::Autolock autoLock(mLock);
491        mNumFramesPlayed += size_done / mFrameSize;
492        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
493    }
494
495    if (postEOS) {
496        mObserver->postAudioEOS(postEOSDelayUs);
497    }
498
499    if (postSeekComplete) {
500        mObserver->postAudioSeekComplete();
501    }
502
503    return size_done;
504}
505
506int64_t AudioPlayer::getRealTimeUs() {
507    Mutex::Autolock autoLock(mLock);
508    return getRealTimeUsLocked();
509}
510
511int64_t AudioPlayer::getRealTimeUsLocked() const {
512    CHECK(mStarted);
513    CHECK_NE(mSampleRate, 0);
514    int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
515
516    // Compensate for large audio buffers, updates of mNumFramesPlayed
517    // are less frequent, therefore to get a "smoother" notion of time we
518    // compensate using system time.
519    int64_t diffUs = ALooper::GetNowUs() - mNumFramesPlayedSysTimeUs;
520
521    return result + diffUs;
522}
523
524int64_t AudioPlayer::getMediaTimeUs() {
525    Mutex::Autolock autoLock(mLock);
526
527    if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
528        if (mSeeking) {
529            return mSeekTimeUs;
530        }
531
532        return 0;
533    }
534
535    int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
536    if (realTimeOffset < 0) {
537        realTimeOffset = 0;
538    }
539
540    return mPositionTimeMediaUs + realTimeOffset;
541}
542
543bool AudioPlayer::getMediaTimeMapping(
544        int64_t *realtime_us, int64_t *mediatime_us) {
545    Mutex::Autolock autoLock(mLock);
546
547    *realtime_us = mPositionTimeRealUs;
548    *mediatime_us = mPositionTimeMediaUs;
549
550    return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
551}
552
553status_t AudioPlayer::seekTo(int64_t time_us) {
554    Mutex::Autolock autoLock(mLock);
555
556    mSeeking = true;
557    mPositionTimeRealUs = mPositionTimeMediaUs = -1;
558    mReachedEOS = false;
559    mSeekTimeUs = time_us;
560
561    // Flush resets the number of played frames
562    mNumFramesPlayed = 0;
563    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
564
565    if (mAudioSink != NULL) {
566        mAudioSink->flush();
567    } else {
568        mAudioTrack->flush();
569    }
570
571    return OK;
572}
573
574}
575