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