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