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