AudioPlayer.cpp revision ad3af3305f024bcbbd55c894a4995e449498e1ba
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        uint32_t flags,
38        AwesomePlayer *observer)
39    : mInputBuffer(NULL),
40      mSampleRate(0),
41      mLatencyUs(0),
42      mFrameSize(0),
43      mNumFramesPlayed(0),
44      mNumFramesPlayedSysTimeUs(ALooper::GetNowUs()),
45      mPositionTimeMediaUs(-1),
46      mPositionTimeRealUs(-1),
47      mSeeking(false),
48      mReachedEOS(false),
49      mFinalStatus(OK),
50      mStarted(false),
51      mIsFirstBuffer(false),
52      mFirstBufferResult(OK),
53      mFirstBuffer(NULL),
54      mAudioSink(audioSink),
55      mAllowDeepBuffering((flags & ALLOW_DEEP_BUFFERING) != 0),
56      mObserver(observer),
57      mPinnedTimeUs(-1ll) {
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            mAudioTrack.clear();
169
170            if (mFirstBuffer != NULL) {
171                mFirstBuffer->release();
172                mFirstBuffer = NULL;
173            }
174
175            if (!sourceAlreadyStarted) {
176                mSource->stop();
177            }
178
179            return err;
180        }
181
182        mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
183        mFrameSize = mAudioTrack->frameSize();
184
185        mAudioTrack->start();
186    }
187
188    mStarted = true;
189    mPinnedTimeUs = -1ll;
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        mPinnedTimeUs = ALooper::GetNowUs();
214    }
215}
216
217void AudioPlayer::resume() {
218    CHECK(mStarted);
219
220    if (mAudioSink.get() != NULL) {
221        mAudioSink->start();
222    } else {
223        mAudioTrack->start();
224    }
225}
226
227void AudioPlayer::reset() {
228    CHECK(mStarted);
229
230    if (mAudioSink.get() != NULL) {
231        mAudioSink->stop();
232        mAudioSink->close();
233    } else {
234        mAudioTrack->stop();
235
236        mAudioTrack.clear();
237    }
238
239    // Make sure to release any buffer we hold onto so that the
240    // source is able to stop().
241
242    if (mFirstBuffer != NULL) {
243        mFirstBuffer->release();
244        mFirstBuffer = NULL;
245    }
246
247    if (mInputBuffer != NULL) {
248        ALOGV("AudioPlayer releasing input buffer.");
249
250        mInputBuffer->release();
251        mInputBuffer = NULL;
252    }
253
254    mSource->stop();
255
256    // The following hack is necessary to ensure that the OMX
257    // component is completely released by the time we may try
258    // to instantiate it again.
259    wp<MediaSource> tmp = mSource;
260    mSource.clear();
261    while (tmp.promote() != NULL) {
262        usleep(1000);
263    }
264    IPCThreadState::self()->flushCommands();
265
266    mNumFramesPlayed = 0;
267    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
268    mPositionTimeMediaUs = -1;
269    mPositionTimeRealUs = -1;
270    mSeeking = false;
271    mReachedEOS = false;
272    mFinalStatus = OK;
273    mStarted = false;
274}
275
276// static
277void AudioPlayer::AudioCallback(int event, void *user, void *info) {
278    static_cast<AudioPlayer *>(user)->AudioCallback(event, info);
279}
280
281bool AudioPlayer::isSeeking() {
282    Mutex::Autolock autoLock(mLock);
283    return mSeeking;
284}
285
286bool AudioPlayer::reachedEOS(status_t *finalStatus) {
287    *finalStatus = OK;
288
289    Mutex::Autolock autoLock(mLock);
290    *finalStatus = mFinalStatus;
291    return mReachedEOS;
292}
293
294status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
295    if (mAudioSink.get() != NULL) {
296        return mAudioSink->setPlaybackRatePermille(ratePermille);
297    } else if (mAudioTrack != 0){
298        return mAudioTrack->setSampleRate(ratePermille * mSampleRate / 1000);
299    } else {
300        return NO_INIT;
301    }
302}
303
304// static
305size_t AudioPlayer::AudioSinkCallback(
306        MediaPlayerBase::AudioSink *audioSink,
307        void *buffer, size_t size, void *cookie,
308        MediaPlayerBase::AudioSink::cb_event_t event) {
309    AudioPlayer *me = (AudioPlayer *)cookie;
310
311    return me->fillBuffer(buffer, size);
312}
313
314void AudioPlayer::AudioCallback(int event, void *info) {
315    if (event != AudioTrack::EVENT_MORE_DATA) {
316        return;
317    }
318
319    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
320    size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
321
322    buffer->size = numBytesWritten;
323}
324
325uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
326    uint32_t numFramesPlayedOut;
327    status_t err;
328
329    if (mAudioSink != NULL) {
330        err = mAudioSink->getPosition(&numFramesPlayedOut);
331    } else {
332        err = mAudioTrack->getPosition(&numFramesPlayedOut);
333    }
334
335    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
336        return 0;
337    }
338
339    // mNumFramesPlayed is the number of frames submitted
340    // to the audio sink for playback, but not all of them
341    // may have played out by now.
342    return mNumFramesPlayed - numFramesPlayedOut;
343}
344
345size_t AudioPlayer::fillBuffer(void *data, size_t size) {
346    if (mNumFramesPlayed == 0) {
347        ALOGV("AudioCallback");
348    }
349
350    if (mReachedEOS) {
351        return 0;
352    }
353
354    bool postSeekComplete = false;
355    bool postEOS = false;
356    int64_t postEOSDelayUs = 0;
357
358    size_t size_done = 0;
359    size_t size_remaining = size;
360    while (size_remaining > 0) {
361        MediaSource::ReadOptions options;
362
363        {
364            Mutex::Autolock autoLock(mLock);
365
366            if (mSeeking) {
367                if (mIsFirstBuffer) {
368                    if (mFirstBuffer != NULL) {
369                        mFirstBuffer->release();
370                        mFirstBuffer = NULL;
371                    }
372                    mIsFirstBuffer = false;
373                }
374
375                options.setSeekTo(mSeekTimeUs);
376
377                if (mInputBuffer != NULL) {
378                    mInputBuffer->release();
379                    mInputBuffer = NULL;
380                }
381
382                mSeeking = false;
383                if (mObserver) {
384                    postSeekComplete = true;
385                }
386            }
387        }
388
389        if (mInputBuffer == NULL) {
390            status_t err;
391
392            if (mIsFirstBuffer) {
393                mInputBuffer = mFirstBuffer;
394                mFirstBuffer = NULL;
395                err = mFirstBufferResult;
396
397                mIsFirstBuffer = false;
398            } else {
399                err = mSource->read(&mInputBuffer, &options);
400            }
401
402            CHECK((err == OK && mInputBuffer != NULL)
403                   || (err != OK && mInputBuffer == NULL));
404
405            Mutex::Autolock autoLock(mLock);
406
407            if (err != OK) {
408                if (mObserver && !mReachedEOS) {
409                    // We don't want to post EOS right away but only
410                    // after all frames have actually been played out.
411
412                    // These are the number of frames submitted to the
413                    // AudioTrack that you haven't heard yet.
414                    uint32_t numFramesPendingPlayout =
415                        getNumFramesPendingPlayout();
416
417                    // These are the number of frames we're going to
418                    // submit to the AudioTrack by returning from this
419                    // callback.
420                    uint32_t numAdditionalFrames = size_done / mFrameSize;
421
422                    numFramesPendingPlayout += numAdditionalFrames;
423
424                    int64_t timeToCompletionUs =
425                        (1000000ll * numFramesPendingPlayout) / mSampleRate;
426
427                    ALOGV("total number of frames played: %lld (%lld us)",
428                            (mNumFramesPlayed + numAdditionalFrames),
429                            1000000ll * (mNumFramesPlayed + numAdditionalFrames)
430                                / mSampleRate);
431
432                    ALOGV("%d frames left to play, %lld us (%.2f secs)",
433                         numFramesPendingPlayout,
434                         timeToCompletionUs, timeToCompletionUs / 1E6);
435
436                    postEOS = true;
437                    if (mAudioSink->needsTrailingPadding()) {
438                        postEOSDelayUs = timeToCompletionUs + mLatencyUs;
439                    } else {
440                        postEOSDelayUs = 0;
441                    }
442                }
443
444                mReachedEOS = true;
445                mFinalStatus = err;
446                break;
447            }
448
449            if (mAudioSink != NULL) {
450                mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
451            } else {
452                mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
453            }
454
455            CHECK(mInputBuffer->meta_data()->findInt64(
456                        kKeyTime, &mPositionTimeMediaUs));
457
458            mPositionTimeRealUs =
459                ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
460                    / mSampleRate;
461
462            ALOGV("buffer->size() = %d, "
463                 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
464                 mInputBuffer->range_length(),
465                 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
466        }
467
468        if (mInputBuffer->range_length() == 0) {
469            mInputBuffer->release();
470            mInputBuffer = NULL;
471
472            continue;
473        }
474
475        size_t copy = size_remaining;
476        if (copy > mInputBuffer->range_length()) {
477            copy = mInputBuffer->range_length();
478        }
479
480        memcpy((char *)data + size_done,
481               (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
482               copy);
483
484        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
485                                mInputBuffer->range_length() - copy);
486
487        size_done += copy;
488        size_remaining -= copy;
489    }
490
491    {
492        Mutex::Autolock autoLock(mLock);
493        mNumFramesPlayed += size_done / mFrameSize;
494        mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
495
496        if (mReachedEOS) {
497            mPinnedTimeUs = mNumFramesPlayedSysTimeUs;
498        } else {
499            mPinnedTimeUs = -1ll;
500        }
501    }
502
503    if (postEOS) {
504        mObserver->postAudioEOS(postEOSDelayUs);
505    }
506
507    if (postSeekComplete) {
508        mObserver->postAudioSeekComplete();
509    }
510
511    return size_done;
512}
513
514int64_t AudioPlayer::getRealTimeUs() {
515    Mutex::Autolock autoLock(mLock);
516    return getRealTimeUsLocked();
517}
518
519int64_t AudioPlayer::getRealTimeUsLocked() const {
520    CHECK(mStarted);
521    CHECK_NE(mSampleRate, 0);
522    int64_t result = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
523
524    // Compensate for large audio buffers, updates of mNumFramesPlayed
525    // are less frequent, therefore to get a "smoother" notion of time we
526    // compensate using system time.
527    int64_t diffUs;
528    if (mPinnedTimeUs >= 0ll) {
529        diffUs = mPinnedTimeUs;
530    } else {
531        diffUs = ALooper::GetNowUs();
532    }
533
534    diffUs -= mNumFramesPlayedSysTimeUs;
535
536    return result + diffUs;
537}
538
539int64_t AudioPlayer::getMediaTimeUs() {
540    Mutex::Autolock autoLock(mLock);
541
542    if (mPositionTimeMediaUs < 0 || mPositionTimeRealUs < 0) {
543        if (mSeeking) {
544            return mSeekTimeUs;
545        }
546
547        return 0;
548    }
549
550    int64_t realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs;
551    if (realTimeOffset < 0) {
552        realTimeOffset = 0;
553    }
554
555    return mPositionTimeMediaUs + realTimeOffset;
556}
557
558bool AudioPlayer::getMediaTimeMapping(
559        int64_t *realtime_us, int64_t *mediatime_us) {
560    Mutex::Autolock autoLock(mLock);
561
562    *realtime_us = mPositionTimeRealUs;
563    *mediatime_us = mPositionTimeMediaUs;
564
565    return mPositionTimeRealUs != -1 && mPositionTimeMediaUs != -1;
566}
567
568status_t AudioPlayer::seekTo(int64_t time_us) {
569    Mutex::Autolock autoLock(mLock);
570
571    mSeeking = true;
572    mPositionTimeRealUs = mPositionTimeMediaUs = -1;
573    mReachedEOS = false;
574    mSeekTimeUs = time_us;
575
576    // Flush resets the number of played frames
577    mNumFramesPlayed = 0;
578    mNumFramesPlayedSysTimeUs = ALooper::GetNowUs();
579
580    if (mAudioSink != NULL) {
581        mAudioSink->flush();
582    } else {
583        mAudioTrack->flush();
584    }
585
586    return OK;
587}
588
589}
590