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