android_AudioSfDecoder.cpp revision b4fb100d7122d118d3da9d1d08ffacef68dd38b0
1/*
2 * Copyright (C) 2011 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 USE_LOG SLAndroidLogLevel_Verbose
18
19#include "sles_allinclusive.h"
20#include "android/android_AudioSfDecoder.h"
21
22#include <media/stagefright/foundation/ADebug.h>
23
24
25#define SIZE_CACHED_HIGH_BYTES 1000000
26#define SIZE_CACHED_MED_BYTES   700000
27#define SIZE_CACHED_LOW_BYTES   400000
28
29namespace android {
30
31//--------------------------------------------------------------------------------------------------
32AudioSfDecoder::AudioSfDecoder(const AudioPlayback_Parameters* params) : GenericPlayer(params),
33        mDataSource(0),
34        mAudioSource(0),
35        mBitrate(-1),
36        mNumChannels(1),
37        mSampleRateHz(0),
38        mDurationUsec(-1),
39        mDecodeBuffer(NULL),
40        mTimeDelta(-1),
41        mSeekTimeMsec(0),
42        mLastDecodedPositionUs(-1)
43{
44    SL_LOGV("AudioSfDecoder::AudioSfDecoder()");
45
46}
47
48
49AudioSfDecoder::~AudioSfDecoder() {
50    SL_LOGV("AudioSfDecoder::~AudioSfDecoder()");
51    if (mAudioSource != 0) {
52        mAudioSource->stop();
53    }
54}
55
56
57//--------------------------------------------------
58void AudioSfDecoder::play() {
59    SL_LOGV("AudioSfDecoder::play");
60
61    GenericPlayer::play();
62    (new AMessage(kWhatDecode, id()))->post();
63}
64
65
66void AudioSfDecoder::startPrefetch_async() {
67    SL_LOGV("AudioSfDecoder::startPrefetch_async()");
68
69    if (wantPrefetch()) {
70        SL_LOGV("AudioSfDecoder::startPrefetch_async(): sending check cache msg");
71
72        mStateFlags |= kFlagPreparing | kFlagBuffering;
73
74        (new AMessage(kWhatCheckCache, id()))->post();
75    }
76}
77
78
79//--------------------------------------------------
80// Event handlers
81void AudioSfDecoder::onPrepare() {
82    SL_LOGD("AudioSfDecoder::onPrepare()");
83
84    sp<DataSource> dataSource;
85
86    switch (mDataLocatorType) {
87
88    case kDataLocatorNone:
89        SL_LOGE("AudioSfDecoder::onPrepare: no data locator set");
90        notifyPrepared(MEDIA_ERROR_BASE);
91        return;
92
93    case kDataLocatorUri:
94        dataSource = DataSource::CreateFromURI(mDataLocator.uriRef);
95        if (dataSource == NULL) {
96            SL_LOGE("AudioSfDecoder::onPrepare(): Error opening %s", mDataLocator.uriRef);
97            notifyPrepared(MEDIA_ERROR_BASE);
98            return;
99        }
100        break;
101
102    case kDataLocatorFd:
103    {
104        dataSource = new FileSource(
105                mDataLocator.fdi.fd, mDataLocator.fdi.offset, mDataLocator.fdi.length);
106        status_t err = dataSource->initCheck();
107        if (err != OK) {
108            notifyPrepared(err);
109            return;
110        }
111        break;
112    }
113
114    default:
115        TRESPASS();
116    }
117
118    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
119    if (extractor == NULL) {
120        SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate extractor.");
121        notifyPrepared(ERROR_UNSUPPORTED);
122        return;
123    }
124
125    ssize_t audioTrackIndex = -1;
126    bool isRawAudio = false;
127    for (size_t i = 0; i < extractor->countTracks(); ++i) {
128        sp<MetaData> meta = extractor->getTrackMetaData(i);
129
130        const char *mime;
131        CHECK(meta->findCString(kKeyMIMEType, &mime));
132
133        if (!strncasecmp("audio/", mime, 6)) {
134            audioTrackIndex = i;
135
136            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
137                isRawAudio = true;
138            }
139            break;
140        }
141    }
142
143    if (audioTrackIndex < 0) {
144        SL_LOGE("AudioSfDecoder::onPrepare: Could not find a supported audio track.");
145        notifyPrepared(ERROR_UNSUPPORTED);
146        return;
147    }
148
149    sp<MediaSource> source = extractor->getTrack(audioTrackIndex);
150    sp<MetaData> meta = source->getFormat();
151
152    off64_t size;
153    int64_t durationUs;
154    if (dataSource->getSize(&size) == OK
155            && meta->findInt64(kKeyDuration, &durationUs)) {
156        mBitrate = size * 8000000ll / durationUs;  // in bits/sec
157        mDurationUsec = durationUs;
158    } else {
159        mBitrate = -1;
160        mDurationUsec = -1;
161    }
162
163    if (!isRawAudio) {
164        OMXClient client;
165        CHECK_EQ(client.connect(), (status_t)OK);
166
167        source = OMXCodec::Create(
168                client.interface(), meta, false /* createEncoder */,
169                source);
170
171        if (source == NULL) {
172            SL_LOGE("AudioSfDecoder::onPrepare: Could not instantiate decoder.");
173            notifyPrepared(ERROR_UNSUPPORTED);
174            return;
175        }
176
177        meta = source->getFormat();
178    }
179
180
181    if (source->start() != OK) {
182        SL_LOGE("AudioSfDecoder::onPrepare: Failed to start source/decoder.");
183        notifyPrepared(MEDIA_ERROR_BASE);
184        return;
185    }
186
187    mDataSource = dataSource;
188    mAudioSource = source;
189
190    CHECK(meta->findInt32(kKeyChannelCount, &mNumChannels));
191    CHECK(meta->findInt32(kKeySampleRate, &mSampleRateHz));
192
193    if (!wantPrefetch()) {
194        SL_LOGV("AudioSfDecoder::onPrepare: no need to prefetch");
195        // doesn't need prefetching, notify good to go
196        mCacheStatus = kStatusHigh;
197        mCacheFill = 1000;
198        notifyStatus();
199        notifyCacheFill();
200    }
201
202    // at this point we have enough information about the source to create the sink that
203    // will consume the data
204    createAudioSink();
205
206    GenericPlayer::onPrepare();
207    SL_LOGD("AudioSfDecoder::onPrepare() done, mStateFlags=0x%x", mStateFlags);
208}
209
210
211void AudioSfDecoder::onPause() {
212    SL_LOGD("AudioSfDecoder::onPause()");
213    GenericPlayer::onPause();
214    pauseAudioSink();
215}
216
217
218void AudioSfDecoder::onPlay() {
219    SL_LOGD("AudioSfDecoder::onPlay()");
220    GenericPlayer::onPlay();
221    startAudioSink();
222}
223
224
225void AudioSfDecoder::onSeek(const sp<AMessage> &msg) {
226    SL_LOGV("AudioSfDecoder::onSeek");
227    int64_t timeMsec;
228    CHECK(msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec));
229
230    Mutex::Autolock _l(mSeekLock);
231    mStateFlags |= kFlagSeeking;
232    mSeekTimeMsec = timeMsec;
233    mTimeDelta = -1;
234    mLastDecodedPositionUs = -1;
235}
236
237
238void AudioSfDecoder::onLoop(const sp<AMessage> &msg) {
239    SL_LOGV("AudioSfDecoder::onLoop");
240    int32_t loop;
241    CHECK(msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop));
242
243    if (loop) {
244        //SL_LOGV("AudioSfDecoder::onLoop start looping");
245        mStateFlags |= kFlagLooping;
246    } else {
247        //SL_LOGV("AudioSfDecoder::onLoop stop looping");
248        mStateFlags &= ~kFlagLooping;
249    }
250}
251
252
253void AudioSfDecoder::onCheckCache(const sp<AMessage> &msg) {
254    //SL_LOGV("AudioSfDecoder::onCheckCache");
255    bool eos;
256    CacheStatus_t status = getCacheRemaining(&eos);
257
258    if (eos || status == kStatusHigh
259            || ((mStateFlags & kFlagPreparing) && (status >= kStatusEnough))) {
260        if (mStateFlags & kFlagPlaying) {
261            startAudioSink();
262        }
263        mStateFlags &= ~kFlagBuffering;
264
265        SL_LOGV("AudioSfDecoder::onCheckCache: buffering done.");
266
267        if (mStateFlags & kFlagPreparing) {
268            //SL_LOGV("AudioSfDecoder::onCheckCache: preparation done.");
269            mStateFlags &= ~kFlagPreparing;
270        }
271
272        mTimeDelta = -1;
273        if (mStateFlags & kFlagPlaying) {
274            (new AMessage(kWhatDecode, id()))->post();
275        }
276        return;
277    }
278
279    msg->post(100000);
280}
281
282
283void AudioSfDecoder::onDecode() {
284    SL_LOGV("AudioSfDecoder::onDecode");
285
286    //-------------------------------- Need to buffer some more before decoding?
287    bool eos;
288    if (mDataSource == 0) {
289        // application set play state to paused which failed, then set play state to playing
290        return;
291    }
292    if (wantPrefetch()
293            && (getCacheRemaining(&eos) == kStatusLow)
294            && !eos) {
295        SL_LOGV("buffering more.");
296
297        if (mStateFlags & kFlagPlaying) {
298            pauseAudioSink();
299        }
300        mStateFlags |= kFlagBuffering;
301        (new AMessage(kWhatCheckCache, id()))->post(100000);
302        return;
303    }
304
305    if (!(mStateFlags & (kFlagPlaying | kFlagBuffering | kFlagPreparing))) {
306        // don't decode if we're not buffering, prefetching or playing
307        //SL_LOGV("don't decode: not buffering, prefetching or playing");
308        return;
309    }
310
311    //-------------------------------- Decode
312    status_t err;
313    MediaSource::ReadOptions readOptions;
314    if (mStateFlags & kFlagSeeking) {
315        readOptions.setSeekTo(mSeekTimeMsec * 1000);
316    }
317
318    {
319        Mutex::Autolock _l(mDecodeBufferLock);
320        if (NULL != mDecodeBuffer) {
321            // the current decoded buffer hasn't been rendered, drop it
322            mDecodeBuffer->release();
323            mDecodeBuffer = NULL;
324        }
325        err = mAudioSource->read(&mDecodeBuffer, &readOptions);
326        if (err == OK) {
327            CHECK(mDecodeBuffer->meta_data()->findInt64(kKeyTime, &mLastDecodedPositionUs));
328        }
329    }
330
331    {
332        Mutex::Autolock _l(mSeekLock);
333        if (mStateFlags & kFlagSeeking) {
334            mStateFlags &= ~kFlagSeeking;
335        }
336    }
337
338    //-------------------------------- Handle return of decode
339    if (err != OK) {
340        bool continueDecoding = false;
341        switch(err) {
342            case ERROR_END_OF_STREAM:
343                if (0 < mDurationUsec) {
344                    mLastDecodedPositionUs = mDurationUsec;
345                }
346                // handle notification and looping at end of stream
347                if (mStateFlags & kFlagPlaying) {
348                    notify(PLAYEREVENT_ENDOFSTREAM, 1, true);
349                }
350                if (mStateFlags & kFlagLooping) {
351                    seek(0);
352                    // kick-off decoding again
353                    continueDecoding = true;
354                }
355                break;
356            case INFO_FORMAT_CHANGED:
357                SL_LOGD("MediaSource::read encountered INFO_FORMAT_CHANGED");
358                // reconfigure output
359                updateAudioSink();
360                continueDecoding = true;
361                break;
362            case INFO_DISCONTINUITY:
363                SL_LOGD("MediaSource::read encountered INFO_DISCONTINUITY");
364                continueDecoding = true;
365                break;
366            default:
367                SL_LOGE("MediaSource::read returned error %d", err);
368                break;
369        }
370        if (continueDecoding) {
371            if (NULL == mDecodeBuffer) {
372                (new AMessage(kWhatDecode, id()))->post();
373                return;
374            }
375        } else {
376            return;
377        }
378    }
379
380    //-------------------------------- Render
381    sp<AMessage> msg = new AMessage(kWhatRender, id());
382    msg->post();
383}
384
385
386void AudioSfDecoder::onRender() {
387    //SL_LOGV("AudioSfDecoder::onRender");
388
389    Mutex::Autolock _l(mDecodeBufferLock);
390
391    if (NULL == mDecodeBuffer) {
392        // nothing to render, move along
393        SL_LOGV("AudioSfDecoder::onRender NULL buffer, exiting");
394        return;
395    }
396
397    mDecodeBuffer->release();
398    mDecodeBuffer = NULL;
399
400}
401
402
403void AudioSfDecoder::onMessageReceived(const sp<AMessage> &msg) {
404    switch (msg->what()) {
405        case kWhatPrepare:
406            onPrepare();
407            break;
408
409        case kWhatDecode:
410            onDecode();
411            break;
412
413        case kWhatRender:
414            onRender();
415            break;
416
417        case kWhatCheckCache:
418            onCheckCache(msg);
419            break;
420
421        case kWhatNotif:
422            onNotify(msg);
423            break;
424
425        case kWhatPlay:
426            onPlay();
427            break;
428
429        case kWhatPause:
430            onPause();
431            break;
432/*
433        case kWhatSeek:
434            onSeek(msg);
435            break;
436
437        case kWhatLoop:
438            onLoop(msg);
439            break;
440*/
441        default:
442            GenericPlayer::onMessageReceived(msg);
443            break;
444    }
445}
446
447//--------------------------------------------------
448// Prepared state, prefetch status notifications
449void AudioSfDecoder::notifyPrepared(status_t prepareRes) {
450    notify(PLAYEREVENT_PREPARED, (int32_t)prepareRes, true);
451
452}
453
454
455void AudioSfDecoder::onNotify(const sp<AMessage> &msg) {
456    if (NULL == mNotifyClient) {
457        return;
458    }
459    int32_t val;
460    if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val)) {
461        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val);
462        mNotifyClient(kEventPrefetchStatusChange, val, 0, mNotifyUser);
463    }
464    else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val)) {
465        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val);
466        mNotifyClient(kEventPrefetchFillLevelUpdate, val, 0, mNotifyUser);
467    }
468    else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val)) {
469        SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val);
470        mNotifyClient(kEventEndOfStream, val, 0, mNotifyUser);
471    }
472    else {
473        GenericPlayer::onNotify(msg);
474    }
475}
476
477
478//--------------------------------------------------
479// Private utility functions
480
481bool AudioSfDecoder::wantPrefetch() {
482    return (mDataSource->flags() & DataSource::kWantsPrefetching);
483}
484
485
486int64_t AudioSfDecoder::getPositionUsec() {
487    Mutex::Autolock _l(mSeekLock);
488    if (mStateFlags & kFlagSeeking) {
489        return mSeekTimeMsec * 1000;
490    } else {
491        if (mLastDecodedPositionUs < 0) {
492            return 0;
493        } else {
494            return mLastDecodedPositionUs;
495        }
496    }
497}
498
499
500CacheStatus_t AudioSfDecoder::getCacheRemaining(bool *eos) {
501    sp<NuCachedSource2> cachedSource =
502        static_cast<NuCachedSource2 *>(mDataSource.get());
503
504    CacheStatus_t oldStatus = mCacheStatus;
505
506    status_t finalStatus;
507    size_t dataRemaining = cachedSource->approxDataRemaining(&finalStatus);
508    *eos = (finalStatus != OK);
509
510    CHECK_GE(mBitrate, 0);
511
512    int64_t dataRemainingUs = dataRemaining * 8000000ll / mBitrate;
513    //SL_LOGV("AudioSfDecoder::getCacheRemaining: approx %.2f secs remaining (eos=%d)",
514    //       dataRemainingUs / 1E6, *eos);
515
516    if (*eos) {
517        // data is buffered up to the end of the stream, it can't get any better than this
518        mCacheStatus = kStatusHigh;
519        mCacheFill = 1000;
520
521    } else {
522        if (mDurationUsec > 0) {
523            // known duration:
524
525            //   fill level is ratio of how much has been played + how much is
526            //   cached, divided by total duration
527            uint32_t currentPositionUsec = getPositionUsec();
528            mCacheFill = (int16_t) ((1000.0
529                    * (double)(currentPositionUsec + dataRemainingUs) / mDurationUsec));
530            //SL_LOGV("cacheFill = %d", mCacheFill);
531
532            //   cache status is evaluated against duration thresholds
533            if (dataRemainingUs > DURATION_CACHED_HIGH_MS*1000) {
534                mCacheStatus = kStatusHigh;
535                //LOGV("high");
536            } else if (dataRemainingUs > DURATION_CACHED_MED_MS*1000) {
537                //LOGV("enough");
538                mCacheStatus = kStatusEnough;
539            } else if (dataRemainingUs < DURATION_CACHED_LOW_MS*1000) {
540                //LOGV("low");
541                mCacheStatus = kStatusLow;
542            } else {
543                mCacheStatus = kStatusIntermediate;
544            }
545
546        } else {
547            // unknown duration:
548
549            //   cache status is evaluated against cache amount thresholds
550            //   (no duration so we don't have the bitrate either, could be derived from format?)
551            if (dataRemaining > SIZE_CACHED_HIGH_BYTES) {
552                mCacheStatus = kStatusHigh;
553            } else if (dataRemaining > SIZE_CACHED_MED_BYTES) {
554                mCacheStatus = kStatusEnough;
555            } else if (dataRemaining < SIZE_CACHED_LOW_BYTES) {
556                mCacheStatus = kStatusLow;
557            } else {
558                mCacheStatus = kStatusIntermediate;
559            }
560        }
561
562    }
563
564    if (oldStatus != mCacheStatus) {
565        notifyStatus();
566    }
567
568    if (abs(mCacheFill - mLastNotifiedCacheFill) > mCacheFillNotifThreshold) {
569        notifyCacheFill();
570    }
571
572    return mCacheStatus;
573}
574
575} // namespace android
576