Home | History | Annotate | Download | only in libstagefright
      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 #undef DEBUG_HDCP
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "AwesomePlayer"
     21 #include <utils/Log.h>
     22 
     23 #include <dlfcn.h>
     24 
     25 #include "include/AwesomePlayer.h"
     26 #include "include/DRMExtractor.h"
     27 #include "include/SoftwareRenderer.h"
     28 #include "include/NuCachedSource2.h"
     29 #include "include/ThrottledSource.h"
     30 #include "include/MPEG2TSExtractor.h"
     31 #include "include/WVMExtractor.h"
     32 
     33 #include "timedtext/TimedTextPlayer.h"
     34 
     35 #include <binder/IPCThreadState.h>
     36 #include <binder/IServiceManager.h>
     37 #include <media/IMediaPlayerService.h>
     38 #include <media/stagefright/foundation/hexdump.h>
     39 #include <media/stagefright/foundation/ADebug.h>
     40 #include <media/stagefright/AudioPlayer.h>
     41 #include <media/stagefright/DataSource.h>
     42 #include <media/stagefright/FileSource.h>
     43 #include <media/stagefright/MediaBuffer.h>
     44 #include <media/stagefright/MediaDefs.h>
     45 #include <media/stagefright/MediaExtractor.h>
     46 #include <media/stagefright/MediaSource.h>
     47 #include <media/stagefright/MetaData.h>
     48 #include <media/stagefright/OMXCodec.h>
     49 
     50 #include <surfaceflinger/Surface.h>
     51 #include <gui/ISurfaceTexture.h>
     52 #include <gui/SurfaceTextureClient.h>
     53 #include <surfaceflinger/ISurfaceComposer.h>
     54 
     55 #include <media/stagefright/foundation/AMessage.h>
     56 
     57 #include <cutils/properties.h>
     58 
     59 #define USE_SURFACE_ALLOC 1
     60 #define FRAME_DROP_FREQ 0
     61 
     62 namespace android {
     63 
     64 static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
     65 static int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
     66 static const size_t kLowWaterMarkBytes = 40000;
     67 static const size_t kHighWaterMarkBytes = 200000;
     68 
     69 struct AwesomeEvent : public TimedEventQueue::Event {
     70     AwesomeEvent(
     71             AwesomePlayer *player,
     72             void (AwesomePlayer::*method)())
     73         : mPlayer(player),
     74           mMethod(method) {
     75     }
     76 
     77 protected:
     78     virtual ~AwesomeEvent() {}
     79 
     80     virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
     81         (mPlayer->*mMethod)();
     82     }
     83 
     84 private:
     85     AwesomePlayer *mPlayer;
     86     void (AwesomePlayer::*mMethod)();
     87 
     88     AwesomeEvent(const AwesomeEvent &);
     89     AwesomeEvent &operator=(const AwesomeEvent &);
     90 };
     91 
     92 struct AwesomeLocalRenderer : public AwesomeRenderer {
     93     AwesomeLocalRenderer(
     94             const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
     95         : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
     96     }
     97 
     98     virtual void render(MediaBuffer *buffer) {
     99         render((const uint8_t *)buffer->data() + buffer->range_offset(),
    100                buffer->range_length());
    101     }
    102 
    103     void render(const void *data, size_t size) {
    104         mTarget->render(data, size, NULL);
    105     }
    106 
    107 protected:
    108     virtual ~AwesomeLocalRenderer() {
    109         delete mTarget;
    110         mTarget = NULL;
    111     }
    112 
    113 private:
    114     SoftwareRenderer *mTarget;
    115 
    116     AwesomeLocalRenderer(const AwesomeLocalRenderer &);
    117     AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
    118 };
    119 
    120 struct AwesomeNativeWindowRenderer : public AwesomeRenderer {
    121     AwesomeNativeWindowRenderer(
    122             const sp<ANativeWindow> &nativeWindow,
    123             int32_t rotationDegrees)
    124         : mNativeWindow(nativeWindow) {
    125         applyRotation(rotationDegrees);
    126     }
    127 
    128     virtual void render(MediaBuffer *buffer) {
    129         int64_t timeUs;
    130         CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
    131         native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
    132         status_t err = mNativeWindow->queueBuffer(
    133                 mNativeWindow.get(), buffer->graphicBuffer().get());
    134         if (err != 0) {
    135             LOGE("queueBuffer failed with error %s (%d)", strerror(-err),
    136                     -err);
    137             return;
    138         }
    139 
    140         sp<MetaData> metaData = buffer->meta_data();
    141         metaData->setInt32(kKeyRendered, 1);
    142     }
    143 
    144 protected:
    145     virtual ~AwesomeNativeWindowRenderer() {}
    146 
    147 private:
    148     sp<ANativeWindow> mNativeWindow;
    149 
    150     void applyRotation(int32_t rotationDegrees) {
    151         uint32_t transform;
    152         switch (rotationDegrees) {
    153             case 0: transform = 0; break;
    154             case 90: transform = HAL_TRANSFORM_ROT_90; break;
    155             case 180: transform = HAL_TRANSFORM_ROT_180; break;
    156             case 270: transform = HAL_TRANSFORM_ROT_270; break;
    157             default: transform = 0; break;
    158         }
    159 
    160         if (transform) {
    161             CHECK_EQ(0, native_window_set_buffers_transform(
    162                         mNativeWindow.get(), transform));
    163         }
    164     }
    165 
    166     AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
    167     AwesomeNativeWindowRenderer &operator=(
    168             const AwesomeNativeWindowRenderer &);
    169 };
    170 
    171 // To collect the decoder usage
    172 void addBatteryData(uint32_t params) {
    173     sp<IBinder> binder =
    174         defaultServiceManager()->getService(String16("media.player"));
    175     sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
    176     CHECK(service.get() != NULL);
    177 
    178     service->addBatteryData(params);
    179 }
    180 
    181 ////////////////////////////////////////////////////////////////////////////////
    182 AwesomePlayer::AwesomePlayer()
    183     : mQueueStarted(false),
    184       mUIDValid(false),
    185       mTimeSource(NULL),
    186       mVideoRendererIsPreview(false),
    187       mAudioPlayer(NULL),
    188       mDisplayWidth(0),
    189       mDisplayHeight(0),
    190       mFlags(0),
    191       mExtractorFlags(0),
    192       mVideoBuffer(NULL),
    193       mDecryptHandle(NULL),
    194       mLastVideoTimeUs(-1),
    195       mTextPlayer(NULL) {
    196     CHECK_EQ(mClient.connect(), (status_t)OK);
    197 
    198     DataSource::RegisterDefaultSniffers();
    199 
    200     mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
    201     mVideoEventPending = false;
    202     mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
    203     mStreamDoneEventPending = false;
    204     mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
    205     mBufferingEventPending = false;
    206     mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
    207     mVideoEventPending = false;
    208 
    209     mCheckAudioStatusEvent = new AwesomeEvent(
    210             this, &AwesomePlayer::onCheckAudioStatus);
    211 
    212     mAudioStatusEventPending = false;
    213 
    214     reset();
    215 }
    216 
    217 AwesomePlayer::~AwesomePlayer() {
    218     if (mQueueStarted) {
    219         mQueue.stop();
    220     }
    221 
    222     reset();
    223 
    224     mClient.disconnect();
    225 }
    226 
    227 void AwesomePlayer::cancelPlayerEvents(bool keepNotifications) {
    228     mQueue.cancelEvent(mVideoEvent->eventID());
    229     mVideoEventPending = false;
    230     mQueue.cancelEvent(mVideoLagEvent->eventID());
    231     mVideoLagEventPending = false;
    232 
    233     if (!keepNotifications) {
    234         mQueue.cancelEvent(mStreamDoneEvent->eventID());
    235         mStreamDoneEventPending = false;
    236         mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
    237         mAudioStatusEventPending = false;
    238 
    239         mQueue.cancelEvent(mBufferingEvent->eventID());
    240         mBufferingEventPending = false;
    241     }
    242 }
    243 
    244 void AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
    245     Mutex::Autolock autoLock(mLock);
    246     mListener = listener;
    247 }
    248 
    249 void AwesomePlayer::setUID(uid_t uid) {
    250     LOGV("AwesomePlayer running on behalf of uid %d", uid);
    251 
    252     mUID = uid;
    253     mUIDValid = true;
    254 }
    255 
    256 status_t AwesomePlayer::setDataSource(
    257         const char *uri, const KeyedVector<String8, String8> *headers) {
    258     Mutex::Autolock autoLock(mLock);
    259     return setDataSource_l(uri, headers);
    260 }
    261 
    262 status_t AwesomePlayer::setDataSource_l(
    263         const char *uri, const KeyedVector<String8, String8> *headers) {
    264     reset_l();
    265 
    266     mUri = uri;
    267 
    268     if (headers) {
    269         mUriHeaders = *headers;
    270 
    271         ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
    272         if (index >= 0) {
    273             // Browser is in "incognito" mode, suppress logging URLs.
    274 
    275             // This isn't something that should be passed to the server.
    276             mUriHeaders.removeItemsAt(index);
    277 
    278             modifyFlags(INCOGNITO, SET);
    279         }
    280     }
    281 
    282     if (!(mFlags & INCOGNITO)) {
    283         LOGI("setDataSource_l('%s')", mUri.string());
    284     } else {
    285         LOGI("setDataSource_l(URL suppressed)");
    286     }
    287 
    288     // The actual work will be done during preparation in the call to
    289     // ::finishSetDataSource_l to avoid blocking the calling thread in
    290     // setDataSource for any significant time.
    291 
    292     {
    293         Mutex::Autolock autoLock(mStatsLock);
    294         mStats.mFd = -1;
    295         mStats.mURI = mUri;
    296     }
    297 
    298     return OK;
    299 }
    300 
    301 status_t AwesomePlayer::setDataSource(
    302         int fd, int64_t offset, int64_t length) {
    303     Mutex::Autolock autoLock(mLock);
    304 
    305     reset_l();
    306 
    307     sp<DataSource> dataSource = new FileSource(fd, offset, length);
    308 
    309     status_t err = dataSource->initCheck();
    310 
    311     if (err != OK) {
    312         return err;
    313     }
    314 
    315     mFileSource = dataSource;
    316 
    317     {
    318         Mutex::Autolock autoLock(mStatsLock);
    319         mStats.mFd = fd;
    320         mStats.mURI = String8();
    321     }
    322 
    323     return setDataSource_l(dataSource);
    324 }
    325 
    326 status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
    327     return INVALID_OPERATION;
    328 }
    329 
    330 status_t AwesomePlayer::setDataSource_l(
    331         const sp<DataSource> &dataSource) {
    332     sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
    333 
    334     if (extractor == NULL) {
    335         return UNKNOWN_ERROR;
    336     }
    337 
    338     dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
    339     if (mDecryptHandle != NULL) {
    340         CHECK(mDrmManagerClient);
    341         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
    342             notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
    343         }
    344     }
    345 
    346     return setDataSource_l(extractor);
    347 }
    348 
    349 status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
    350     // Attempt to approximate overall stream bitrate by summing all
    351     // tracks' individual bitrates, if not all of them advertise bitrate,
    352     // we have to fail.
    353 
    354     int64_t totalBitRate = 0;
    355 
    356     for (size_t i = 0; i < extractor->countTracks(); ++i) {
    357         sp<MetaData> meta = extractor->getTrackMetaData(i);
    358 
    359         int32_t bitrate;
    360         if (!meta->findInt32(kKeyBitRate, &bitrate)) {
    361             const char *mime;
    362             CHECK(meta->findCString(kKeyMIMEType, &mime));
    363             LOGV("track of type '%s' does not publish bitrate", mime);
    364 
    365             totalBitRate = -1;
    366             break;
    367         }
    368 
    369         totalBitRate += bitrate;
    370     }
    371 
    372     mBitrate = totalBitRate;
    373 
    374     LOGV("mBitrate = %lld bits/sec", mBitrate);
    375 
    376     {
    377         Mutex::Autolock autoLock(mStatsLock);
    378         mStats.mBitrate = mBitrate;
    379         mStats.mTracks.clear();
    380         mStats.mAudioTrackIndex = -1;
    381         mStats.mVideoTrackIndex = -1;
    382     }
    383 
    384     bool haveAudio = false;
    385     bool haveVideo = false;
    386     for (size_t i = 0; i < extractor->countTracks(); ++i) {
    387         sp<MetaData> meta = extractor->getTrackMetaData(i);
    388 
    389         const char *_mime;
    390         CHECK(meta->findCString(kKeyMIMEType, &_mime));
    391 
    392         String8 mime = String8(_mime);
    393 
    394         if (!haveVideo && !strncasecmp(mime.string(), "video/", 6)) {
    395             setVideoSource(extractor->getTrack(i));
    396             haveVideo = true;
    397 
    398             // Set the presentation/display size
    399             int32_t displayWidth, displayHeight;
    400             bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
    401             if (success) {
    402                 success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
    403             }
    404             if (success) {
    405                 mDisplayWidth = displayWidth;
    406                 mDisplayHeight = displayHeight;
    407             }
    408 
    409             {
    410                 Mutex::Autolock autoLock(mStatsLock);
    411                 mStats.mVideoTrackIndex = mStats.mTracks.size();
    412                 mStats.mTracks.push();
    413                 TrackStat *stat =
    414                     &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
    415                 stat->mMIME = mime.string();
    416             }
    417         } else if (!haveAudio && !strncasecmp(mime.string(), "audio/", 6)) {
    418             setAudioSource(extractor->getTrack(i));
    419             haveAudio = true;
    420 
    421             {
    422                 Mutex::Autolock autoLock(mStatsLock);
    423                 mStats.mAudioTrackIndex = mStats.mTracks.size();
    424                 mStats.mTracks.push();
    425                 TrackStat *stat =
    426                     &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
    427                 stat->mMIME = mime.string();
    428             }
    429 
    430             if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_AUDIO_VORBIS)) {
    431                 // Only do this for vorbis audio, none of the other audio
    432                 // formats even support this ringtone specific hack and
    433                 // retrieving the metadata on some extractors may turn out
    434                 // to be very expensive.
    435                 sp<MetaData> fileMeta = extractor->getMetaData();
    436                 int32_t loop;
    437                 if (fileMeta != NULL
    438                         && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
    439                     modifyFlags(AUTO_LOOPING, SET);
    440                 }
    441             }
    442         } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
    443             addTextSource(extractor->getTrack(i));
    444         }
    445     }
    446 
    447     if (!haveAudio && !haveVideo) {
    448         return UNKNOWN_ERROR;
    449     }
    450 
    451     mExtractorFlags = extractor->flags();
    452 
    453     return OK;
    454 }
    455 
    456 void AwesomePlayer::reset() {
    457     Mutex::Autolock autoLock(mLock);
    458     reset_l();
    459 }
    460 
    461 void AwesomePlayer::reset_l() {
    462     mDisplayWidth = 0;
    463     mDisplayHeight = 0;
    464 
    465     if (mDecryptHandle != NULL) {
    466             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
    467                     Playback::STOP, 0);
    468             mDecryptHandle = NULL;
    469             mDrmManagerClient = NULL;
    470     }
    471 
    472     if (mFlags & PLAYING) {
    473         uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
    474         if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
    475             params |= IMediaPlayerService::kBatteryDataTrackAudio;
    476         }
    477         if (mVideoSource != NULL) {
    478             params |= IMediaPlayerService::kBatteryDataTrackVideo;
    479         }
    480         addBatteryData(params);
    481     }
    482 
    483     if (mFlags & PREPARING) {
    484         modifyFlags(PREPARE_CANCELLED, SET);
    485         if (mConnectingDataSource != NULL) {
    486             LOGI("interrupting the connection process");
    487             mConnectingDataSource->disconnect();
    488         }
    489 
    490         if (mFlags & PREPARING_CONNECTED) {
    491             // We are basically done preparing, we're just buffering
    492             // enough data to start playback, we can safely interrupt that.
    493             finishAsyncPrepare_l();
    494         }
    495     }
    496 
    497     while (mFlags & PREPARING) {
    498         mPreparedCondition.wait(mLock);
    499     }
    500 
    501     cancelPlayerEvents();
    502 
    503     mWVMExtractor.clear();
    504     mCachedSource.clear();
    505     mAudioTrack.clear();
    506     mVideoTrack.clear();
    507 
    508     // Shutdown audio first, so that the respone to the reset request
    509     // appears to happen instantaneously as far as the user is concerned
    510     // If we did this later, audio would continue playing while we
    511     // shutdown the video-related resources and the player appear to
    512     // not be as responsive to a reset request.
    513     if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
    514             && mAudioSource != NULL) {
    515         // If we had an audio player, it would have effectively
    516         // taken possession of the audio source and stopped it when
    517         // _it_ is stopped. Otherwise this is still our responsibility.
    518         mAudioSource->stop();
    519     }
    520     mAudioSource.clear();
    521 
    522     mTimeSource = NULL;
    523 
    524     delete mAudioPlayer;
    525     mAudioPlayer = NULL;
    526 
    527     if (mTextPlayer != NULL) {
    528         delete mTextPlayer;
    529         mTextPlayer = NULL;
    530     }
    531 
    532     mVideoRenderer.clear();
    533 
    534     if (mVideoSource != NULL) {
    535         shutdownVideoDecoder_l();
    536     }
    537 
    538     mDurationUs = -1;
    539     modifyFlags(0, ASSIGN);
    540     mExtractorFlags = 0;
    541     mTimeSourceDeltaUs = 0;
    542     mVideoTimeUs = 0;
    543 
    544     mSeeking = NO_SEEK;
    545     mSeekNotificationSent = true;
    546     mSeekTimeUs = 0;
    547 
    548     mUri.setTo("");
    549     mUriHeaders.clear();
    550 
    551     mFileSource.clear();
    552 
    553     mBitrate = -1;
    554     mLastVideoTimeUs = -1;
    555 
    556     {
    557         Mutex::Autolock autoLock(mStatsLock);
    558         mStats.mFd = -1;
    559         mStats.mURI = String8();
    560         mStats.mBitrate = -1;
    561         mStats.mAudioTrackIndex = -1;
    562         mStats.mVideoTrackIndex = -1;
    563         mStats.mNumVideoFramesDecoded = 0;
    564         mStats.mNumVideoFramesDropped = 0;
    565         mStats.mVideoWidth = -1;
    566         mStats.mVideoHeight = -1;
    567         mStats.mFlags = 0;
    568         mStats.mTracks.clear();
    569     }
    570 
    571     mWatchForAudioSeekComplete = false;
    572     mWatchForAudioEOS = false;
    573 }
    574 
    575 void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
    576     if (mListener != NULL) {
    577         sp<MediaPlayerBase> listener = mListener.promote();
    578 
    579         if (listener != NULL) {
    580             listener->sendEvent(msg, ext1, ext2);
    581         }
    582     }
    583 }
    584 
    585 bool AwesomePlayer::getBitrate(int64_t *bitrate) {
    586     off64_t size;
    587     if (mDurationUs >= 0 && mCachedSource != NULL
    588             && mCachedSource->getSize(&size) == OK) {
    589         *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
    590         return true;
    591     }
    592 
    593     if (mBitrate >= 0) {
    594         *bitrate = mBitrate;
    595         return true;
    596     }
    597 
    598     *bitrate = 0;
    599 
    600     return false;
    601 }
    602 
    603 // Returns true iff cached duration is available/applicable.
    604 bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
    605     int64_t bitrate;
    606 
    607     if (mCachedSource != NULL && getBitrate(&bitrate)) {
    608         status_t finalStatus;
    609         size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
    610         *durationUs = cachedDataRemaining * 8000000ll / bitrate;
    611         *eos = (finalStatus != OK);
    612         return true;
    613     } else if (mWVMExtractor != NULL) {
    614         status_t finalStatus;
    615         *durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
    616         *eos = (finalStatus != OK);
    617         return true;
    618     }
    619 
    620     return false;
    621 }
    622 
    623 void AwesomePlayer::ensureCacheIsFetching_l() {
    624     if (mCachedSource != NULL) {
    625         mCachedSource->resumeFetchingIfNecessary();
    626     }
    627 }
    628 
    629 void AwesomePlayer::onVideoLagUpdate() {
    630     Mutex::Autolock autoLock(mLock);
    631     if (!mVideoLagEventPending) {
    632         return;
    633     }
    634     mVideoLagEventPending = false;
    635 
    636     int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
    637     int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
    638 
    639     if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
    640         LOGV("video late by %lld ms.", videoLateByUs / 1000ll);
    641 
    642         notifyListener_l(
    643                 MEDIA_INFO,
    644                 MEDIA_INFO_VIDEO_TRACK_LAGGING,
    645                 videoLateByUs / 1000ll);
    646     }
    647 
    648     postVideoLagEvent_l();
    649 }
    650 
    651 void AwesomePlayer::onBufferingUpdate() {
    652     Mutex::Autolock autoLock(mLock);
    653     if (!mBufferingEventPending) {
    654         return;
    655     }
    656     mBufferingEventPending = false;
    657 
    658     if (mCachedSource != NULL) {
    659         status_t finalStatus;
    660         size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
    661         bool eos = (finalStatus != OK);
    662 
    663         if (eos) {
    664             if (finalStatus == ERROR_END_OF_STREAM) {
    665                 notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
    666             }
    667             if (mFlags & PREPARING) {
    668                 LOGV("cache has reached EOS, prepare is done.");
    669                 finishAsyncPrepare_l();
    670             }
    671         } else {
    672             int64_t bitrate;
    673             if (getBitrate(&bitrate)) {
    674                 size_t cachedSize = mCachedSource->cachedSize();
    675                 int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
    676 
    677                 int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
    678                 if (percentage > 100) {
    679                     percentage = 100;
    680                 }
    681 
    682                 notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
    683             } else {
    684                 // We don't know the bitrate of the stream, use absolute size
    685                 // limits to maintain the cache.
    686 
    687                 if ((mFlags & PLAYING) && !eos
    688                         && (cachedDataRemaining < kLowWaterMarkBytes)) {
    689                     LOGI("cache is running low (< %d) , pausing.",
    690                          kLowWaterMarkBytes);
    691                     modifyFlags(CACHE_UNDERRUN, SET);
    692                     pause_l();
    693                     ensureCacheIsFetching_l();
    694                     sendCacheStats();
    695                     notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
    696                 } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
    697                     if (mFlags & CACHE_UNDERRUN) {
    698                         LOGI("cache has filled up (> %d), resuming.",
    699                              kHighWaterMarkBytes);
    700                         modifyFlags(CACHE_UNDERRUN, CLEAR);
    701                         play_l();
    702                         notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
    703                     } else if (mFlags & PREPARING) {
    704                         LOGV("cache has filled up (> %d), prepare is done",
    705                              kHighWaterMarkBytes);
    706                         finishAsyncPrepare_l();
    707                     }
    708                 }
    709             }
    710         }
    711     } else if (mWVMExtractor != NULL) {
    712         status_t finalStatus;
    713 
    714         int64_t cachedDurationUs
    715             = mWVMExtractor->getCachedDurationUs(&finalStatus);
    716 
    717         bool eos = (finalStatus != OK);
    718 
    719         if (eos) {
    720             if (finalStatus == ERROR_END_OF_STREAM) {
    721                 notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
    722             }
    723             if (mFlags & PREPARING) {
    724                 LOGV("cache has reached EOS, prepare is done.");
    725                 finishAsyncPrepare_l();
    726             }
    727         } else {
    728             int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
    729             if (percentage > 100) {
    730                 percentage = 100;
    731             }
    732 
    733             notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
    734         }
    735     }
    736 
    737     int64_t cachedDurationUs;
    738     bool eos;
    739     if (getCachedDuration_l(&cachedDurationUs, &eos)) {
    740         LOGV("cachedDurationUs = %.2f secs, eos=%d",
    741              cachedDurationUs / 1E6, eos);
    742 
    743         if ((mFlags & PLAYING) && !eos
    744                 && (cachedDurationUs < kLowWaterMarkUs)) {
    745             LOGI("cache is running low (%.2f secs) , pausing.",
    746                  cachedDurationUs / 1E6);
    747             modifyFlags(CACHE_UNDERRUN, SET);
    748             pause_l();
    749             ensureCacheIsFetching_l();
    750             sendCacheStats();
    751             notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
    752         } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
    753             if (mFlags & CACHE_UNDERRUN) {
    754                 LOGI("cache has filled up (%.2f secs), resuming.",
    755                      cachedDurationUs / 1E6);
    756                 modifyFlags(CACHE_UNDERRUN, CLEAR);
    757                 play_l();
    758                 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
    759             } else if (mFlags & PREPARING) {
    760                 LOGV("cache has filled up (%.2f secs), prepare is done",
    761                      cachedDurationUs / 1E6);
    762                 finishAsyncPrepare_l();
    763             }
    764         }
    765     }
    766 
    767     postBufferingEvent_l();
    768 }
    769 
    770 void AwesomePlayer::sendCacheStats() {
    771     sp<MediaPlayerBase> listener = mListener.promote();
    772     if (listener != NULL && mCachedSource != NULL) {
    773         int32_t kbps = 0;
    774         status_t err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
    775         if (err == OK) {
    776             listener->sendEvent(
    777                 MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
    778         }
    779     }
    780 }
    781 
    782 void AwesomePlayer::onStreamDone() {
    783     // Posted whenever any stream finishes playing.
    784 
    785     Mutex::Autolock autoLock(mLock);
    786     if (!mStreamDoneEventPending) {
    787         return;
    788     }
    789     mStreamDoneEventPending = false;
    790 
    791     if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
    792         LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
    793 
    794         notifyListener_l(
    795                 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
    796 
    797         pause_l(true /* at eos */);
    798 
    799         modifyFlags(AT_EOS, SET);
    800         return;
    801     }
    802 
    803     const bool allDone =
    804         (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
    805             && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
    806 
    807     if (!allDone) {
    808         return;
    809     }
    810 
    811     if ((mFlags & LOOPING)
    812             || ((mFlags & AUTO_LOOPING)
    813                 && (mAudioSink == NULL || mAudioSink->realtime()))) {
    814         // Don't AUTO_LOOP if we're being recorded, since that cannot be
    815         // turned off and recording would go on indefinitely.
    816 
    817         seekTo_l(0);
    818 
    819         if (mVideoSource != NULL) {
    820             postVideoEvent_l();
    821         }
    822     } else {
    823         LOGV("MEDIA_PLAYBACK_COMPLETE");
    824         notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
    825 
    826         pause_l(true /* at eos */);
    827 
    828         modifyFlags(AT_EOS, SET);
    829     }
    830 }
    831 
    832 status_t AwesomePlayer::play() {
    833     Mutex::Autolock autoLock(mLock);
    834 
    835     modifyFlags(CACHE_UNDERRUN, CLEAR);
    836 
    837     return play_l();
    838 }
    839 
    840 status_t AwesomePlayer::play_l() {
    841     modifyFlags(SEEK_PREVIEW, CLEAR);
    842 
    843     if (mFlags & PLAYING) {
    844         return OK;
    845     }
    846 
    847     if (!(mFlags & PREPARED)) {
    848         status_t err = prepare_l();
    849 
    850         if (err != OK) {
    851             return err;
    852         }
    853     }
    854 
    855     modifyFlags(PLAYING, SET);
    856     modifyFlags(FIRST_FRAME, SET);
    857 
    858     if (mDecryptHandle != NULL) {
    859         int64_t position;
    860         getPosition(&position);
    861         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
    862                 Playback::START, position / 1000);
    863     }
    864 
    865     if (mAudioSource != NULL) {
    866         if (mAudioPlayer == NULL) {
    867             if (mAudioSink != NULL) {
    868                 mAudioPlayer = new AudioPlayer(mAudioSink, this);
    869                 mAudioPlayer->setSource(mAudioSource);
    870 
    871                 mTimeSource = mAudioPlayer;
    872 
    873                 // If there was a seek request before we ever started,
    874                 // honor the request now.
    875                 // Make sure to do this before starting the audio player
    876                 // to avoid a race condition.
    877                 seekAudioIfNecessary_l();
    878             }
    879         }
    880 
    881         CHECK(!(mFlags & AUDIO_RUNNING));
    882 
    883         if (mVideoSource == NULL) {
    884             // We don't want to post an error notification at this point,
    885             // the error returned from MediaPlayer::start() will suffice.
    886 
    887             status_t err = startAudioPlayer_l(
    888                     false /* sendErrorNotification */);
    889 
    890             if (err != OK) {
    891                 delete mAudioPlayer;
    892                 mAudioPlayer = NULL;
    893 
    894                 modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
    895 
    896                 if (mDecryptHandle != NULL) {
    897                     mDrmManagerClient->setPlaybackStatus(
    898                             mDecryptHandle, Playback::STOP, 0);
    899                 }
    900 
    901                 return err;
    902             }
    903         }
    904     }
    905 
    906     if (mTimeSource == NULL && mAudioPlayer == NULL) {
    907         mTimeSource = &mSystemTimeSource;
    908     }
    909 
    910     if (mVideoSource != NULL) {
    911         // Kick off video playback
    912         postVideoEvent_l();
    913 
    914         if (mAudioSource != NULL && mVideoSource != NULL) {
    915             postVideoLagEvent_l();
    916         }
    917     }
    918 
    919     if (mFlags & AT_EOS) {
    920         // Legacy behaviour, if a stream finishes playing and then
    921         // is started again, we play from the start...
    922         seekTo_l(0);
    923     }
    924 
    925     uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
    926         | IMediaPlayerService::kBatteryDataTrackDecoder;
    927     if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
    928         params |= IMediaPlayerService::kBatteryDataTrackAudio;
    929     }
    930     if (mVideoSource != NULL) {
    931         params |= IMediaPlayerService::kBatteryDataTrackVideo;
    932     }
    933     addBatteryData(params);
    934 
    935     return OK;
    936 }
    937 
    938 status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
    939     CHECK(!(mFlags & AUDIO_RUNNING));
    940 
    941     if (mAudioSource == NULL || mAudioPlayer == NULL) {
    942         return OK;
    943     }
    944 
    945     if (!(mFlags & AUDIOPLAYER_STARTED)) {
    946         modifyFlags(AUDIOPLAYER_STARTED, SET);
    947 
    948         bool wasSeeking = mAudioPlayer->isSeeking();
    949 
    950         // We've already started the MediaSource in order to enable
    951         // the prefetcher to read its data.
    952         status_t err = mAudioPlayer->start(
    953                 true /* sourceAlreadyStarted */);
    954 
    955         if (err != OK) {
    956             if (sendErrorNotification) {
    957                 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
    958             }
    959 
    960             return err;
    961         }
    962 
    963         if (wasSeeking) {
    964             CHECK(!mAudioPlayer->isSeeking());
    965 
    966             // We will have finished the seek while starting the audio player.
    967             postAudioSeekComplete();
    968         }
    969     } else {
    970         mAudioPlayer->resume();
    971     }
    972 
    973     modifyFlags(AUDIO_RUNNING, SET);
    974 
    975     mWatchForAudioEOS = true;
    976 
    977     return OK;
    978 }
    979 
    980 void AwesomePlayer::notifyVideoSize_l() {
    981     sp<MetaData> meta = mVideoSource->getFormat();
    982 
    983     int32_t cropLeft, cropTop, cropRight, cropBottom;
    984     if (!meta->findRect(
    985                 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
    986         int32_t width, height;
    987         CHECK(meta->findInt32(kKeyWidth, &width));
    988         CHECK(meta->findInt32(kKeyHeight, &height));
    989 
    990         cropLeft = cropTop = 0;
    991         cropRight = width - 1;
    992         cropBottom = height - 1;
    993 
    994         LOGV("got dimensions only %d x %d", width, height);
    995     } else {
    996         LOGV("got crop rect %d, %d, %d, %d",
    997              cropLeft, cropTop, cropRight, cropBottom);
    998     }
    999 
   1000     int32_t displayWidth;
   1001     if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
   1002         LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
   1003         mDisplayWidth = displayWidth;
   1004     }
   1005     int32_t displayHeight;
   1006     if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
   1007         LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
   1008         mDisplayHeight = displayHeight;
   1009     }
   1010 
   1011     int32_t usableWidth = cropRight - cropLeft + 1;
   1012     int32_t usableHeight = cropBottom - cropTop + 1;
   1013     if (mDisplayWidth != 0) {
   1014         usableWidth = mDisplayWidth;
   1015     }
   1016     if (mDisplayHeight != 0) {
   1017         usableHeight = mDisplayHeight;
   1018     }
   1019 
   1020     {
   1021         Mutex::Autolock autoLock(mStatsLock);
   1022         mStats.mVideoWidth = usableWidth;
   1023         mStats.mVideoHeight = usableHeight;
   1024     }
   1025 
   1026     int32_t rotationDegrees;
   1027     if (!mVideoTrack->getFormat()->findInt32(
   1028                 kKeyRotation, &rotationDegrees)) {
   1029         rotationDegrees = 0;
   1030     }
   1031 
   1032     if (rotationDegrees == 90 || rotationDegrees == 270) {
   1033         notifyListener_l(
   1034                 MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
   1035     } else {
   1036         notifyListener_l(
   1037                 MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
   1038     }
   1039 }
   1040 
   1041 void AwesomePlayer::initRenderer_l() {
   1042     if (mNativeWindow == NULL) {
   1043         return;
   1044     }
   1045 
   1046     sp<MetaData> meta = mVideoSource->getFormat();
   1047 
   1048     int32_t format;
   1049     const char *component;
   1050     int32_t decodedWidth, decodedHeight;
   1051     CHECK(meta->findInt32(kKeyColorFormat, &format));
   1052     CHECK(meta->findCString(kKeyDecoderComponent, &component));
   1053     CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
   1054     CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
   1055 
   1056     int32_t rotationDegrees;
   1057     if (!mVideoTrack->getFormat()->findInt32(
   1058                 kKeyRotation, &rotationDegrees)) {
   1059         rotationDegrees = 0;
   1060     }
   1061 
   1062     mVideoRenderer.clear();
   1063 
   1064     // Must ensure that mVideoRenderer's destructor is actually executed
   1065     // before creating a new one.
   1066     IPCThreadState::self()->flushCommands();
   1067 
   1068     if (USE_SURFACE_ALLOC
   1069             && !strncmp(component, "OMX.", 4)
   1070             && strncmp(component, "OMX.google.", 11)
   1071             && strcmp(component, "OMX.Nvidia.mpeg2v.decode")) {
   1072         // Hardware decoders avoid the CPU color conversion by decoding
   1073         // directly to ANativeBuffers, so we must use a renderer that
   1074         // just pushes those buffers to the ANativeWindow.
   1075         mVideoRenderer =
   1076             new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
   1077     } else {
   1078         // Other decoders are instantiated locally and as a consequence
   1079         // allocate their buffers in local address space.  This renderer
   1080         // then performs a color conversion and copy to get the data
   1081         // into the ANativeBuffer.
   1082         mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
   1083     }
   1084 }
   1085 
   1086 status_t AwesomePlayer::pause() {
   1087     Mutex::Autolock autoLock(mLock);
   1088 
   1089     modifyFlags(CACHE_UNDERRUN, CLEAR);
   1090 
   1091     return pause_l();
   1092 }
   1093 
   1094 status_t AwesomePlayer::pause_l(bool at_eos) {
   1095     if (!(mFlags & PLAYING)) {
   1096         return OK;
   1097     }
   1098 
   1099     cancelPlayerEvents(true /* keepNotifications */);
   1100 
   1101     if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
   1102         if (at_eos) {
   1103             // If we played the audio stream to completion we
   1104             // want to make sure that all samples remaining in the audio
   1105             // track's queue are played out.
   1106             mAudioPlayer->pause(true /* playPendingSamples */);
   1107         } else {
   1108             mAudioPlayer->pause();
   1109         }
   1110 
   1111         modifyFlags(AUDIO_RUNNING, CLEAR);
   1112     }
   1113 
   1114     if (mFlags & TEXTPLAYER_STARTED) {
   1115         mTextPlayer->pause();
   1116         modifyFlags(TEXT_RUNNING, CLEAR);
   1117     }
   1118 
   1119     modifyFlags(PLAYING, CLEAR);
   1120 
   1121     if (mDecryptHandle != NULL) {
   1122         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1123                 Playback::PAUSE, 0);
   1124     }
   1125 
   1126     uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
   1127     if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
   1128         params |= IMediaPlayerService::kBatteryDataTrackAudio;
   1129     }
   1130     if (mVideoSource != NULL) {
   1131         params |= IMediaPlayerService::kBatteryDataTrackVideo;
   1132     }
   1133 
   1134     addBatteryData(params);
   1135 
   1136     return OK;
   1137 }
   1138 
   1139 bool AwesomePlayer::isPlaying() const {
   1140     return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
   1141 }
   1142 
   1143 status_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
   1144     Mutex::Autolock autoLock(mLock);
   1145 
   1146     status_t err;
   1147     if (surfaceTexture != NULL) {
   1148         err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
   1149     } else {
   1150         err = setNativeWindow_l(NULL);
   1151     }
   1152 
   1153     return err;
   1154 }
   1155 
   1156 void AwesomePlayer::shutdownVideoDecoder_l() {
   1157     if (mVideoBuffer) {
   1158         mVideoBuffer->release();
   1159         mVideoBuffer = NULL;
   1160     }
   1161 
   1162     mVideoSource->stop();
   1163 
   1164     // The following hack is necessary to ensure that the OMX
   1165     // component is completely released by the time we may try
   1166     // to instantiate it again.
   1167     wp<MediaSource> tmp = mVideoSource;
   1168     mVideoSource.clear();
   1169     while (tmp.promote() != NULL) {
   1170         usleep(1000);
   1171     }
   1172     IPCThreadState::self()->flushCommands();
   1173     LOGV("video decoder shutdown completed");
   1174 }
   1175 
   1176 status_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
   1177     mNativeWindow = native;
   1178 
   1179     if (mVideoSource == NULL) {
   1180         return OK;
   1181     }
   1182 
   1183     LOGV("attempting to reconfigure to use new surface");
   1184 
   1185     bool wasPlaying = (mFlags & PLAYING) != 0;
   1186 
   1187     pause_l();
   1188     mVideoRenderer.clear();
   1189 
   1190     shutdownVideoDecoder_l();
   1191 
   1192     status_t err = initVideoDecoder();
   1193 
   1194     if (err != OK) {
   1195         LOGE("failed to reinstantiate video decoder after surface change.");
   1196         return err;
   1197     }
   1198 
   1199     if (mLastVideoTimeUs >= 0) {
   1200         mSeeking = SEEK;
   1201         mSeekTimeUs = mLastVideoTimeUs;
   1202         modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
   1203     }
   1204 
   1205     if (wasPlaying) {
   1206         play_l();
   1207     }
   1208 
   1209     return OK;
   1210 }
   1211 
   1212 void AwesomePlayer::setAudioSink(
   1213         const sp<MediaPlayerBase::AudioSink> &audioSink) {
   1214     Mutex::Autolock autoLock(mLock);
   1215 
   1216     mAudioSink = audioSink;
   1217 }
   1218 
   1219 status_t AwesomePlayer::setLooping(bool shouldLoop) {
   1220     Mutex::Autolock autoLock(mLock);
   1221 
   1222     modifyFlags(LOOPING, CLEAR);
   1223 
   1224     if (shouldLoop) {
   1225         modifyFlags(LOOPING, SET);
   1226     }
   1227 
   1228     return OK;
   1229 }
   1230 
   1231 status_t AwesomePlayer::getDuration(int64_t *durationUs) {
   1232     Mutex::Autolock autoLock(mMiscStateLock);
   1233 
   1234     if (mDurationUs < 0) {
   1235         return UNKNOWN_ERROR;
   1236     }
   1237 
   1238     *durationUs = mDurationUs;
   1239 
   1240     return OK;
   1241 }
   1242 
   1243 status_t AwesomePlayer::getPosition(int64_t *positionUs) {
   1244     if (mSeeking != NO_SEEK) {
   1245         *positionUs = mSeekTimeUs;
   1246     } else if (mVideoSource != NULL
   1247             && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
   1248         Mutex::Autolock autoLock(mMiscStateLock);
   1249         *positionUs = mVideoTimeUs;
   1250     } else if (mAudioPlayer != NULL) {
   1251         *positionUs = mAudioPlayer->getMediaTimeUs();
   1252     } else {
   1253         *positionUs = 0;
   1254     }
   1255 
   1256     return OK;
   1257 }
   1258 
   1259 status_t AwesomePlayer::seekTo(int64_t timeUs) {
   1260     if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
   1261         Mutex::Autolock autoLock(mLock);
   1262         return seekTo_l(timeUs);
   1263     }
   1264 
   1265     return OK;
   1266 }
   1267 
   1268 status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
   1269     if (mTextPlayer != NULL) {
   1270         if (index >= 0) { // to turn on a text track
   1271             status_t err = mTextPlayer->setTimedTextTrackIndex(index);
   1272             if (err != OK) {
   1273                 return err;
   1274             }
   1275 
   1276             modifyFlags(TEXT_RUNNING, SET);
   1277             modifyFlags(TEXTPLAYER_STARTED, SET);
   1278             return OK;
   1279         } else { // to turn off the text track display
   1280             if (mFlags  & TEXT_RUNNING) {
   1281                 modifyFlags(TEXT_RUNNING, CLEAR);
   1282             }
   1283             if (mFlags  & TEXTPLAYER_STARTED) {
   1284                 modifyFlags(TEXTPLAYER_STARTED, CLEAR);
   1285             }
   1286 
   1287             return mTextPlayer->setTimedTextTrackIndex(index);
   1288         }
   1289     } else {
   1290         return INVALID_OPERATION;
   1291     }
   1292 }
   1293 
   1294 status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
   1295     if (mFlags & CACHE_UNDERRUN) {
   1296         modifyFlags(CACHE_UNDERRUN, CLEAR);
   1297         play_l();
   1298     }
   1299 
   1300     if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
   1301         // Video playback completed before, there's no pending
   1302         // video event right now. In order for this new seek
   1303         // to be honored, we need to post one.
   1304 
   1305         postVideoEvent_l();
   1306     }
   1307 
   1308     mSeeking = SEEK;
   1309     mSeekNotificationSent = false;
   1310     mSeekTimeUs = timeUs;
   1311     modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
   1312 
   1313     seekAudioIfNecessary_l();
   1314 
   1315     if (mFlags & TEXTPLAYER_STARTED) {
   1316         mTextPlayer->seekTo(mSeekTimeUs);
   1317     }
   1318 
   1319     if (!(mFlags & PLAYING)) {
   1320         LOGV("seeking while paused, sending SEEK_COMPLETE notification"
   1321              " immediately.");
   1322 
   1323         notifyListener_l(MEDIA_SEEK_COMPLETE);
   1324         mSeekNotificationSent = true;
   1325 
   1326         if ((mFlags & PREPARED) && mVideoSource != NULL) {
   1327             modifyFlags(SEEK_PREVIEW, SET);
   1328             postVideoEvent_l();
   1329         }
   1330     }
   1331 
   1332     return OK;
   1333 }
   1334 
   1335 void AwesomePlayer::seekAudioIfNecessary_l() {
   1336     if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
   1337         mAudioPlayer->seekTo(mSeekTimeUs);
   1338 
   1339         mWatchForAudioSeekComplete = true;
   1340         mWatchForAudioEOS = true;
   1341 
   1342         if (mDecryptHandle != NULL) {
   1343             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1344                     Playback::PAUSE, 0);
   1345             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1346                     Playback::START, mSeekTimeUs / 1000);
   1347         }
   1348     }
   1349 }
   1350 
   1351 void AwesomePlayer::setAudioSource(sp<MediaSource> source) {
   1352     CHECK(source != NULL);
   1353 
   1354     mAudioTrack = source;
   1355 }
   1356 
   1357 void AwesomePlayer::addTextSource(sp<MediaSource> source) {
   1358     Mutex::Autolock autoLock(mTimedTextLock);
   1359     CHECK(source != NULL);
   1360 
   1361     if (mTextPlayer == NULL) {
   1362         mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
   1363     }
   1364 
   1365     mTextPlayer->addTextSource(source);
   1366 }
   1367 
   1368 status_t AwesomePlayer::initAudioDecoder() {
   1369     sp<MetaData> meta = mAudioTrack->getFormat();
   1370 
   1371     const char *mime;
   1372     CHECK(meta->findCString(kKeyMIMEType, &mime));
   1373 
   1374     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
   1375         mAudioSource = mAudioTrack;
   1376     } else {
   1377         mAudioSource = OMXCodec::Create(
   1378                 mClient.interface(), mAudioTrack->getFormat(),
   1379                 false, // createEncoder
   1380                 mAudioTrack);
   1381     }
   1382 
   1383     if (mAudioSource != NULL) {
   1384         int64_t durationUs;
   1385         if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
   1386             Mutex::Autolock autoLock(mMiscStateLock);
   1387             if (mDurationUs < 0 || durationUs > mDurationUs) {
   1388                 mDurationUs = durationUs;
   1389             }
   1390         }
   1391 
   1392         status_t err = mAudioSource->start();
   1393 
   1394         if (err != OK) {
   1395             mAudioSource.clear();
   1396             return err;
   1397         }
   1398     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
   1399         // For legacy reasons we're simply going to ignore the absence
   1400         // of an audio decoder for QCELP instead of aborting playback
   1401         // altogether.
   1402         return OK;
   1403     }
   1404 
   1405     if (mAudioSource != NULL) {
   1406         Mutex::Autolock autoLock(mStatsLock);
   1407         TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
   1408 
   1409         const char *component;
   1410         if (!mAudioSource->getFormat()
   1411                 ->findCString(kKeyDecoderComponent, &component)) {
   1412             component = "none";
   1413         }
   1414 
   1415         stat->mDecoderName = component;
   1416     }
   1417 
   1418     return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
   1419 }
   1420 
   1421 void AwesomePlayer::setVideoSource(sp<MediaSource> source) {
   1422     CHECK(source != NULL);
   1423 
   1424     mVideoTrack = source;
   1425 }
   1426 
   1427 status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
   1428 
   1429     // Either the application or the DRM system can independently say
   1430     // that there must be a hardware-protected path to an external video sink.
   1431     // For now we always require a hardware-protected path to external video sink
   1432     // if content is DRMed, but eventually this could be optional per DRM agent.
   1433     // When the application wants protection, then
   1434     //   (USE_SURFACE_ALLOC && (mSurface != 0) &&
   1435     //   (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
   1436     // will be true, but that part is already handled by SurfaceFlinger.
   1437 
   1438 #ifdef DEBUG_HDCP
   1439     // For debugging, we allow a system property to control the protected usage.
   1440     // In case of uninitialized or unexpected property, we default to "DRM only".
   1441     bool setProtectionBit = false;
   1442     char value[PROPERTY_VALUE_MAX];
   1443     if (property_get("persist.sys.hdcp_checking", value, NULL)) {
   1444         if (!strcmp(value, "never")) {
   1445             // nop
   1446         } else if (!strcmp(value, "always")) {
   1447             setProtectionBit = true;
   1448         } else if (!strcmp(value, "drm-only")) {
   1449             if (mDecryptHandle != NULL) {
   1450                 setProtectionBit = true;
   1451             }
   1452         // property value is empty, or unexpected value
   1453         } else {
   1454             if (mDecryptHandle != NULL) {
   1455                 setProtectionBit = true;
   1456             }
   1457         }
   1458     // can' read property value
   1459     } else {
   1460         if (mDecryptHandle != NULL) {
   1461             setProtectionBit = true;
   1462         }
   1463     }
   1464     // note that usage bit is already cleared, so no need to clear it in the "else" case
   1465     if (setProtectionBit) {
   1466         flags |= OMXCodec::kEnableGrallocUsageProtected;
   1467     }
   1468 #else
   1469     if (mDecryptHandle != NULL) {
   1470         flags |= OMXCodec::kEnableGrallocUsageProtected;
   1471     }
   1472 #endif
   1473     LOGV("initVideoDecoder flags=0x%x", flags);
   1474     mVideoSource = OMXCodec::Create(
   1475             mClient.interface(), mVideoTrack->getFormat(),
   1476             false, // createEncoder
   1477             mVideoTrack,
   1478             NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
   1479 
   1480     if (mVideoSource != NULL) {
   1481         int64_t durationUs;
   1482         if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
   1483             Mutex::Autolock autoLock(mMiscStateLock);
   1484             if (mDurationUs < 0 || durationUs > mDurationUs) {
   1485                 mDurationUs = durationUs;
   1486             }
   1487         }
   1488 
   1489         status_t err = mVideoSource->start();
   1490 
   1491         if (err != OK) {
   1492             mVideoSource.clear();
   1493             return err;
   1494         }
   1495     }
   1496 
   1497     if (mVideoSource != NULL) {
   1498         const char *componentName;
   1499         CHECK(mVideoSource->getFormat()
   1500                 ->findCString(kKeyDecoderComponent, &componentName));
   1501 
   1502         {
   1503             Mutex::Autolock autoLock(mStatsLock);
   1504             TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
   1505 
   1506             stat->mDecoderName = componentName;
   1507         }
   1508 
   1509         static const char *kPrefix = "OMX.Nvidia.";
   1510         static const char *kSuffix = ".decode";
   1511         static const size_t kSuffixLength = strlen(kSuffix);
   1512 
   1513         size_t componentNameLength = strlen(componentName);
   1514 
   1515         if (!strncmp(componentName, kPrefix, strlen(kPrefix))
   1516                 && componentNameLength >= kSuffixLength
   1517                 && !strcmp(&componentName[
   1518                     componentNameLength - kSuffixLength], kSuffix)) {
   1519             modifyFlags(SLOW_DECODER_HACK, SET);
   1520         }
   1521     }
   1522 
   1523     return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
   1524 }
   1525 
   1526 void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
   1527     if (mSeeking == SEEK_VIDEO_ONLY) {
   1528         mSeeking = NO_SEEK;
   1529         return;
   1530     }
   1531 
   1532     if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
   1533         return;
   1534     }
   1535 
   1536     if (mAudioPlayer != NULL) {
   1537         LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
   1538 
   1539         // If we don't have a video time, seek audio to the originally
   1540         // requested seek time instead.
   1541 
   1542         mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
   1543         mWatchForAudioSeekComplete = true;
   1544         mWatchForAudioEOS = true;
   1545     } else if (!mSeekNotificationSent) {
   1546         // If we're playing video only, report seek complete now,
   1547         // otherwise audio player will notify us later.
   1548         notifyListener_l(MEDIA_SEEK_COMPLETE);
   1549         mSeekNotificationSent = true;
   1550     }
   1551 
   1552     modifyFlags(FIRST_FRAME, SET);
   1553     mSeeking = NO_SEEK;
   1554 
   1555     if (mDecryptHandle != NULL) {
   1556         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1557                 Playback::PAUSE, 0);
   1558         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1559                 Playback::START, videoTimeUs / 1000);
   1560     }
   1561 }
   1562 
   1563 void AwesomePlayer::onVideoEvent() {
   1564     Mutex::Autolock autoLock(mLock);
   1565     if (!mVideoEventPending) {
   1566         // The event has been cancelled in reset_l() but had already
   1567         // been scheduled for execution at that time.
   1568         return;
   1569     }
   1570     mVideoEventPending = false;
   1571 
   1572     if (mSeeking != NO_SEEK) {
   1573         if (mVideoBuffer) {
   1574             mVideoBuffer->release();
   1575             mVideoBuffer = NULL;
   1576         }
   1577 
   1578         if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
   1579                 && !(mFlags & SEEK_PREVIEW)) {
   1580             // We're going to seek the video source first, followed by
   1581             // the audio source.
   1582             // In order to avoid jumps in the DataSource offset caused by
   1583             // the audio codec prefetching data from the old locations
   1584             // while the video codec is already reading data from the new
   1585             // locations, we'll "pause" the audio source, causing it to
   1586             // stop reading input data until a subsequent seek.
   1587 
   1588             if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
   1589                 mAudioPlayer->pause();
   1590 
   1591                 modifyFlags(AUDIO_RUNNING, CLEAR);
   1592             }
   1593             mAudioSource->pause();
   1594         }
   1595     }
   1596 
   1597     if (!mVideoBuffer) {
   1598         MediaSource::ReadOptions options;
   1599         if (mSeeking != NO_SEEK) {
   1600             LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
   1601 
   1602             options.setSeekTo(
   1603                     mSeekTimeUs,
   1604                     mSeeking == SEEK_VIDEO_ONLY
   1605                         ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
   1606                         : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
   1607         }
   1608         for (;;) {
   1609             status_t err = mVideoSource->read(&mVideoBuffer, &options);
   1610             options.clearSeekTo();
   1611 
   1612             if (err != OK) {
   1613                 CHECK(mVideoBuffer == NULL);
   1614 
   1615                 if (err == INFO_FORMAT_CHANGED) {
   1616                     LOGV("VideoSource signalled format change.");
   1617 
   1618                     notifyVideoSize_l();
   1619 
   1620                     if (mVideoRenderer != NULL) {
   1621                         mVideoRendererIsPreview = false;
   1622                         initRenderer_l();
   1623                     }
   1624                     continue;
   1625                 }
   1626 
   1627                 // So video playback is complete, but we may still have
   1628                 // a seek request pending that needs to be applied
   1629                 // to the audio track.
   1630                 if (mSeeking != NO_SEEK) {
   1631                     LOGV("video stream ended while seeking!");
   1632                 }
   1633                 finishSeekIfNecessary(-1);
   1634 
   1635                 if (mAudioPlayer != NULL
   1636                         && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
   1637                     startAudioPlayer_l();
   1638                 }
   1639 
   1640                 modifyFlags(VIDEO_AT_EOS, SET);
   1641                 postStreamDoneEvent_l(err);
   1642                 return;
   1643             }
   1644 
   1645             if (mVideoBuffer->range_length() == 0) {
   1646                 // Some decoders, notably the PV AVC software decoder
   1647                 // return spurious empty buffers that we just want to ignore.
   1648 
   1649                 mVideoBuffer->release();
   1650                 mVideoBuffer = NULL;
   1651                 continue;
   1652             }
   1653 
   1654             break;
   1655         }
   1656 
   1657         {
   1658             Mutex::Autolock autoLock(mStatsLock);
   1659             ++mStats.mNumVideoFramesDecoded;
   1660         }
   1661     }
   1662 
   1663     int64_t timeUs;
   1664     CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
   1665 
   1666     mLastVideoTimeUs = timeUs;
   1667 
   1668     if (mSeeking == SEEK_VIDEO_ONLY) {
   1669         if (mSeekTimeUs > timeUs) {
   1670             LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
   1671                  mSeekTimeUs, timeUs);
   1672         }
   1673     }
   1674 
   1675     {
   1676         Mutex::Autolock autoLock(mMiscStateLock);
   1677         mVideoTimeUs = timeUs;
   1678     }
   1679 
   1680     SeekType wasSeeking = mSeeking;
   1681     finishSeekIfNecessary(timeUs);
   1682 
   1683     if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
   1684         status_t err = startAudioPlayer_l();
   1685         if (err != OK) {
   1686             LOGE("Starting the audio player failed w/ err %d", err);
   1687             return;
   1688         }
   1689     }
   1690 
   1691     if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
   1692         mTextPlayer->resume();
   1693         modifyFlags(TEXT_RUNNING, SET);
   1694     }
   1695 
   1696     TimeSource *ts =
   1697         ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
   1698             ? &mSystemTimeSource : mTimeSource;
   1699 
   1700     if (mFlags & FIRST_FRAME) {
   1701         modifyFlags(FIRST_FRAME, CLEAR);
   1702         mSinceLastDropped = 0;
   1703         mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
   1704     }
   1705 
   1706     int64_t realTimeUs, mediaTimeUs;
   1707     if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
   1708         && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
   1709         mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
   1710     }
   1711 
   1712     if (wasSeeking == SEEK_VIDEO_ONLY) {
   1713         int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
   1714 
   1715         int64_t latenessUs = nowUs - timeUs;
   1716 
   1717         if (latenessUs > 0) {
   1718             LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
   1719         }
   1720     }
   1721 
   1722     if (wasSeeking == NO_SEEK) {
   1723         // Let's display the first frame after seeking right away.
   1724 
   1725         int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
   1726 
   1727         int64_t latenessUs = nowUs - timeUs;
   1728 
   1729         if (latenessUs > 500000ll
   1730                 && mAudioPlayer != NULL
   1731                 && mAudioPlayer->getMediaTimeMapping(
   1732                     &realTimeUs, &mediaTimeUs)) {
   1733             LOGI("we're much too late (%.2f secs), video skipping ahead",
   1734                  latenessUs / 1E6);
   1735 
   1736             mVideoBuffer->release();
   1737             mVideoBuffer = NULL;
   1738 
   1739             mSeeking = SEEK_VIDEO_ONLY;
   1740             mSeekTimeUs = mediaTimeUs;
   1741 
   1742             postVideoEvent_l();
   1743             return;
   1744         }
   1745 
   1746         if (latenessUs > 40000) {
   1747             // We're more than 40ms late.
   1748             LOGV("we're late by %lld us (%.2f secs)",
   1749                  latenessUs, latenessUs / 1E6);
   1750 
   1751             if (!(mFlags & SLOW_DECODER_HACK)
   1752                     || mSinceLastDropped > FRAME_DROP_FREQ)
   1753             {
   1754                 LOGV("we're late by %lld us (%.2f secs) dropping "
   1755                      "one after %d frames",
   1756                      latenessUs, latenessUs / 1E6, mSinceLastDropped);
   1757 
   1758                 mSinceLastDropped = 0;
   1759                 mVideoBuffer->release();
   1760                 mVideoBuffer = NULL;
   1761 
   1762                 {
   1763                     Mutex::Autolock autoLock(mStatsLock);
   1764                     ++mStats.mNumVideoFramesDropped;
   1765                 }
   1766 
   1767                 postVideoEvent_l();
   1768                 return;
   1769             }
   1770         }
   1771 
   1772         if (latenessUs < -10000) {
   1773             // We're more than 10ms early.
   1774 
   1775             postVideoEvent_l(10000);
   1776             return;
   1777         }
   1778     }
   1779 
   1780     if ((mNativeWindow != NULL)
   1781             && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {
   1782         mVideoRendererIsPreview = false;
   1783 
   1784         initRenderer_l();
   1785     }
   1786 
   1787     if (mVideoRenderer != NULL) {
   1788         mSinceLastDropped++;
   1789         mVideoRenderer->render(mVideoBuffer);
   1790     }
   1791 
   1792     mVideoBuffer->release();
   1793     mVideoBuffer = NULL;
   1794 
   1795     if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
   1796         modifyFlags(SEEK_PREVIEW, CLEAR);
   1797         return;
   1798     }
   1799 
   1800     postVideoEvent_l();
   1801 }
   1802 
   1803 void AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
   1804     if (mVideoEventPending) {
   1805         return;
   1806     }
   1807 
   1808     mVideoEventPending = true;
   1809     mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
   1810 }
   1811 
   1812 void AwesomePlayer::postStreamDoneEvent_l(status_t status) {
   1813     if (mStreamDoneEventPending) {
   1814         return;
   1815     }
   1816     mStreamDoneEventPending = true;
   1817 
   1818     mStreamDoneStatus = status;
   1819     mQueue.postEvent(mStreamDoneEvent);
   1820 }
   1821 
   1822 void AwesomePlayer::postBufferingEvent_l() {
   1823     if (mBufferingEventPending) {
   1824         return;
   1825     }
   1826     mBufferingEventPending = true;
   1827     mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
   1828 }
   1829 
   1830 void AwesomePlayer::postVideoLagEvent_l() {
   1831     if (mVideoLagEventPending) {
   1832         return;
   1833     }
   1834     mVideoLagEventPending = true;
   1835     mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
   1836 }
   1837 
   1838 void AwesomePlayer::postCheckAudioStatusEvent(int64_t delayUs) {
   1839     Mutex::Autolock autoLock(mAudioLock);
   1840     if (mAudioStatusEventPending) {
   1841         return;
   1842     }
   1843     mAudioStatusEventPending = true;
   1844     // Do not honor delay when looping in order to limit audio gap
   1845     if (mFlags & (LOOPING | AUTO_LOOPING)) {
   1846         delayUs = 0;
   1847     }
   1848     mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
   1849 }
   1850 
   1851 void AwesomePlayer::onCheckAudioStatus() {
   1852     {
   1853         Mutex::Autolock autoLock(mAudioLock);
   1854         if (!mAudioStatusEventPending) {
   1855             // Event was dispatched and while we were blocking on the mutex,
   1856             // has already been cancelled.
   1857             return;
   1858         }
   1859 
   1860         mAudioStatusEventPending = false;
   1861     }
   1862 
   1863     Mutex::Autolock autoLock(mLock);
   1864 
   1865     if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
   1866         mWatchForAudioSeekComplete = false;
   1867 
   1868         if (!mSeekNotificationSent) {
   1869             notifyListener_l(MEDIA_SEEK_COMPLETE);
   1870             mSeekNotificationSent = true;
   1871         }
   1872 
   1873         mSeeking = NO_SEEK;
   1874     }
   1875 
   1876     status_t finalStatus;
   1877     if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
   1878         mWatchForAudioEOS = false;
   1879         modifyFlags(AUDIO_AT_EOS, SET);
   1880         modifyFlags(FIRST_FRAME, SET);
   1881         postStreamDoneEvent_l(finalStatus);
   1882     }
   1883 }
   1884 
   1885 status_t AwesomePlayer::prepare() {
   1886     Mutex::Autolock autoLock(mLock);
   1887     return prepare_l();
   1888 }
   1889 
   1890 status_t AwesomePlayer::prepare_l() {
   1891     if (mFlags & PREPARED) {
   1892         return OK;
   1893     }
   1894 
   1895     if (mFlags & PREPARING) {
   1896         return UNKNOWN_ERROR;
   1897     }
   1898 
   1899     mIsAsyncPrepare = false;
   1900     status_t err = prepareAsync_l();
   1901 
   1902     if (err != OK) {
   1903         return err;
   1904     }
   1905 
   1906     while (mFlags & PREPARING) {
   1907         mPreparedCondition.wait(mLock);
   1908     }
   1909 
   1910     return mPrepareResult;
   1911 }
   1912 
   1913 status_t AwesomePlayer::prepareAsync() {
   1914     Mutex::Autolock autoLock(mLock);
   1915 
   1916     if (mFlags & PREPARING) {
   1917         return UNKNOWN_ERROR;  // async prepare already pending
   1918     }
   1919 
   1920     mIsAsyncPrepare = true;
   1921     return prepareAsync_l();
   1922 }
   1923 
   1924 status_t AwesomePlayer::prepareAsync_l() {
   1925     if (mFlags & PREPARING) {
   1926         return UNKNOWN_ERROR;  // async prepare already pending
   1927     }
   1928 
   1929     if (!mQueueStarted) {
   1930         mQueue.start();
   1931         mQueueStarted = true;
   1932     }
   1933 
   1934     modifyFlags(PREPARING, SET);
   1935     mAsyncPrepareEvent = new AwesomeEvent(
   1936             this, &AwesomePlayer::onPrepareAsyncEvent);
   1937 
   1938     mQueue.postEvent(mAsyncPrepareEvent);
   1939 
   1940     return OK;
   1941 }
   1942 
   1943 status_t AwesomePlayer::finishSetDataSource_l() {
   1944     sp<DataSource> dataSource;
   1945 
   1946     bool isWidevineStreaming = false;
   1947     if (!strncasecmp("widevine://", mUri.string(), 11)) {
   1948         isWidevineStreaming = true;
   1949 
   1950         String8 newURI = String8("http://");
   1951         newURI.append(mUri.string() + 11);
   1952 
   1953         mUri = newURI;
   1954     }
   1955 
   1956     AString sniffedMIME;
   1957 
   1958     if (!strncasecmp("http://", mUri.string(), 7)
   1959             || !strncasecmp("https://", mUri.string(), 8)
   1960             || isWidevineStreaming) {
   1961         mConnectingDataSource = HTTPBase::Create(
   1962                 (mFlags & INCOGNITO)
   1963                     ? HTTPBase::kFlagIncognito
   1964                     : 0);
   1965 
   1966         if (mUIDValid) {
   1967             mConnectingDataSource->setUID(mUID);
   1968         }
   1969 
   1970         String8 cacheConfig;
   1971         bool disconnectAtHighwatermark;
   1972         NuCachedSource2::RemoveCacheSpecificHeaders(
   1973                 &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
   1974 
   1975         mLock.unlock();
   1976         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
   1977         mLock.lock();
   1978 
   1979         if (err != OK) {
   1980             mConnectingDataSource.clear();
   1981 
   1982             LOGI("mConnectingDataSource->connect() returned %d", err);
   1983             return err;
   1984         }
   1985 
   1986         if (!isWidevineStreaming) {
   1987             // The widevine extractor does its own caching.
   1988 
   1989 #if 0
   1990             mCachedSource = new NuCachedSource2(
   1991                     new ThrottledSource(
   1992                         mConnectingDataSource, 50 * 1024 /* bytes/sec */));
   1993 #else
   1994             mCachedSource = new NuCachedSource2(
   1995                     mConnectingDataSource,
   1996                     cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
   1997                     disconnectAtHighwatermark);
   1998 #endif
   1999 
   2000             dataSource = mCachedSource;
   2001         } else {
   2002             dataSource = mConnectingDataSource;
   2003         }
   2004 
   2005         mConnectingDataSource.clear();
   2006 
   2007         String8 contentType = dataSource->getMIMEType();
   2008 
   2009         if (strncasecmp(contentType.string(), "audio/", 6)) {
   2010             // We're not doing this for streams that appear to be audio-only
   2011             // streams to ensure that even low bandwidth streams start
   2012             // playing back fairly instantly.
   2013 
   2014             // We're going to prefill the cache before trying to instantiate
   2015             // the extractor below, as the latter is an operation that otherwise
   2016             // could block on the datasource for a significant amount of time.
   2017             // During that time we'd be unable to abort the preparation phase
   2018             // without this prefill.
   2019             if (mCachedSource != NULL) {
   2020                 // We're going to prefill the cache before trying to instantiate
   2021                 // the extractor below, as the latter is an operation that otherwise
   2022                 // could block on the datasource for a significant amount of time.
   2023                 // During that time we'd be unable to abort the preparation phase
   2024                 // without this prefill.
   2025 
   2026                 mLock.unlock();
   2027 
   2028                 // Initially make sure we have at least 192 KB for the sniff
   2029                 // to complete without blocking.
   2030                 static const size_t kMinBytesForSniffing = 192 * 1024;
   2031 
   2032                 off64_t metaDataSize = -1ll;
   2033                 for (;;) {
   2034                     status_t finalStatus;
   2035                     size_t cachedDataRemaining =
   2036                         mCachedSource->approxDataRemaining(&finalStatus);
   2037 
   2038                     if (finalStatus != OK
   2039                             || (metaDataSize >= 0
   2040                                 && cachedDataRemaining >= metaDataSize)
   2041                             || (mFlags & PREPARE_CANCELLED)) {
   2042                         break;
   2043                     }
   2044 
   2045                     LOGV("now cached %d bytes of data", cachedDataRemaining);
   2046 
   2047                     if (metaDataSize < 0
   2048                             && cachedDataRemaining >= kMinBytesForSniffing) {
   2049                         String8 tmp;
   2050                         float confidence;
   2051                         sp<AMessage> meta;
   2052                         if (!dataSource->sniff(&tmp, &confidence, &meta)) {
   2053                             mLock.lock();
   2054                             return UNKNOWN_ERROR;
   2055                         }
   2056 
   2057                         // We successfully identified the file's extractor to
   2058                         // be, remember this mime type so we don't have to
   2059                         // sniff it again when we call MediaExtractor::Create()
   2060                         // below.
   2061                         sniffedMIME = tmp.string();
   2062 
   2063                         if (meta == NULL
   2064                                 || !meta->findInt64(
   2065                                     "meta-data-size", &metaDataSize)) {
   2066                             metaDataSize = kHighWaterMarkBytes;
   2067                         }
   2068 
   2069                         CHECK_GE(metaDataSize, 0ll);
   2070                         LOGV("metaDataSize = %lld bytes", metaDataSize);
   2071                     }
   2072 
   2073                     usleep(200000);
   2074                 }
   2075 
   2076                 mLock.lock();
   2077             }
   2078 
   2079             if (mFlags & PREPARE_CANCELLED) {
   2080                 LOGI("Prepare cancelled while waiting for initial cache fill.");
   2081                 return UNKNOWN_ERROR;
   2082             }
   2083         }
   2084     } else {
   2085         dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
   2086     }
   2087 
   2088     if (dataSource == NULL) {
   2089         return UNKNOWN_ERROR;
   2090     }
   2091 
   2092     sp<MediaExtractor> extractor;
   2093 
   2094     if (isWidevineStreaming) {
   2095         String8 mimeType;
   2096         float confidence;
   2097         sp<AMessage> dummy;
   2098         bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
   2099 
   2100         if (!success
   2101                 || strcasecmp(
   2102                     mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
   2103             return ERROR_UNSUPPORTED;
   2104         }
   2105 
   2106         mWVMExtractor = new WVMExtractor(dataSource);
   2107         mWVMExtractor->setAdaptiveStreamingMode(true);
   2108         extractor = mWVMExtractor;
   2109     } else {
   2110         extractor = MediaExtractor::Create(
   2111                 dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
   2112 
   2113         if (extractor == NULL) {
   2114             return UNKNOWN_ERROR;
   2115         }
   2116     }
   2117 
   2118     dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
   2119 
   2120     if (mDecryptHandle != NULL) {
   2121         CHECK(mDrmManagerClient);
   2122         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
   2123             notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
   2124         }
   2125     }
   2126 
   2127     status_t err = setDataSource_l(extractor);
   2128 
   2129     if (err != OK) {
   2130         mWVMExtractor.clear();
   2131 
   2132         return err;
   2133     }
   2134 
   2135     return OK;
   2136 }
   2137 
   2138 void AwesomePlayer::abortPrepare(status_t err) {
   2139     CHECK(err != OK);
   2140 
   2141     if (mIsAsyncPrepare) {
   2142         notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
   2143     }
   2144 
   2145     mPrepareResult = err;
   2146     modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
   2147     mAsyncPrepareEvent = NULL;
   2148     mPreparedCondition.broadcast();
   2149 }
   2150 
   2151 // static
   2152 bool AwesomePlayer::ContinuePreparation(void *cookie) {
   2153     AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
   2154 
   2155     return (me->mFlags & PREPARE_CANCELLED) == 0;
   2156 }
   2157 
   2158 void AwesomePlayer::onPrepareAsyncEvent() {
   2159     Mutex::Autolock autoLock(mLock);
   2160 
   2161     if (mFlags & PREPARE_CANCELLED) {
   2162         LOGI("prepare was cancelled before doing anything");
   2163         abortPrepare(UNKNOWN_ERROR);
   2164         return;
   2165     }
   2166 
   2167     if (mUri.size() > 0) {
   2168         status_t err = finishSetDataSource_l();
   2169 
   2170         if (err != OK) {
   2171             abortPrepare(err);
   2172             return;
   2173         }
   2174     }
   2175 
   2176     if (mVideoTrack != NULL && mVideoSource == NULL) {
   2177         status_t err = initVideoDecoder();
   2178 
   2179         if (err != OK) {
   2180             abortPrepare(err);
   2181             return;
   2182         }
   2183     }
   2184 
   2185     if (mAudioTrack != NULL && mAudioSource == NULL) {
   2186         status_t err = initAudioDecoder();
   2187 
   2188         if (err != OK) {
   2189             abortPrepare(err);
   2190             return;
   2191         }
   2192     }
   2193 
   2194     modifyFlags(PREPARING_CONNECTED, SET);
   2195 
   2196     if (isStreamingHTTP()) {
   2197         postBufferingEvent_l();
   2198     } else {
   2199         finishAsyncPrepare_l();
   2200     }
   2201 }
   2202 
   2203 void AwesomePlayer::finishAsyncPrepare_l() {
   2204     if (mIsAsyncPrepare) {
   2205         if (mVideoSource == NULL) {
   2206             notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
   2207         } else {
   2208             notifyVideoSize_l();
   2209         }
   2210 
   2211         notifyListener_l(MEDIA_PREPARED);
   2212     }
   2213 
   2214     mPrepareResult = OK;
   2215     modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
   2216     modifyFlags(PREPARED, SET);
   2217     mAsyncPrepareEvent = NULL;
   2218     mPreparedCondition.broadcast();
   2219 }
   2220 
   2221 uint32_t AwesomePlayer::flags() const {
   2222     return mExtractorFlags;
   2223 }
   2224 
   2225 void AwesomePlayer::postAudioEOS(int64_t delayUs) {
   2226     postCheckAudioStatusEvent(delayUs);
   2227 }
   2228 
   2229 void AwesomePlayer::postAudioSeekComplete() {
   2230     postCheckAudioStatusEvent(0);
   2231 }
   2232 
   2233 status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
   2234     switch (key) {
   2235         case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX:
   2236         {
   2237             Mutex::Autolock autoLock(mTimedTextLock);
   2238             return setTimedTextTrackIndex(request.readInt32());
   2239         }
   2240         case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
   2241         {
   2242             Mutex::Autolock autoLock(mTimedTextLock);
   2243             if (mTextPlayer == NULL) {
   2244                 mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
   2245             }
   2246 
   2247             return mTextPlayer->setParameter(key, request);
   2248         }
   2249         case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
   2250         {
   2251             return setCacheStatCollectFreq(request);
   2252         }
   2253         default:
   2254         {
   2255             return ERROR_UNSUPPORTED;
   2256         }
   2257     }
   2258 }
   2259 
   2260 status_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
   2261     if (mCachedSource != NULL) {
   2262         int32_t freqMs = request.readInt32();
   2263         LOGD("Request to keep cache stats in the past %d ms",
   2264             freqMs);
   2265         return mCachedSource->setCacheStatCollectFreq(freqMs);
   2266     }
   2267     return ERROR_UNSUPPORTED;
   2268 }
   2269 
   2270 status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
   2271     switch (key) {
   2272     case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
   2273         {
   2274             int32_t channelCount;
   2275             if (mAudioTrack == 0 ||
   2276                     !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
   2277                 channelCount = 0;
   2278             }
   2279             reply->writeInt32(channelCount);
   2280         }
   2281         return OK;
   2282     default:
   2283         {
   2284             return ERROR_UNSUPPORTED;
   2285         }
   2286     }
   2287 }
   2288 
   2289 bool AwesomePlayer::isStreamingHTTP() const {
   2290     return mCachedSource != NULL || mWVMExtractor != NULL;
   2291 }
   2292 
   2293 status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
   2294     Mutex::Autolock autoLock(mStatsLock);
   2295 
   2296     FILE *out = fdopen(dup(fd), "w");
   2297 
   2298     fprintf(out, " AwesomePlayer\n");
   2299     if (mStats.mFd < 0) {
   2300         fprintf(out, "  URI(%s)", mStats.mURI.string());
   2301     } else {
   2302         fprintf(out, "  fd(%d)", mStats.mFd);
   2303     }
   2304 
   2305     fprintf(out, ", flags(0x%08x)", mStats.mFlags);
   2306 
   2307     if (mStats.mBitrate >= 0) {
   2308         fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
   2309     }
   2310 
   2311     fprintf(out, "\n");
   2312 
   2313     for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
   2314         const TrackStat &stat = mStats.mTracks.itemAt(i);
   2315 
   2316         fprintf(out, "  Track %d\n", i + 1);
   2317         fprintf(out, "   MIME(%s)", stat.mMIME.string());
   2318 
   2319         if (!stat.mDecoderName.isEmpty()) {
   2320             fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
   2321         }
   2322 
   2323         fprintf(out, "\n");
   2324 
   2325         if ((ssize_t)i == mStats.mVideoTrackIndex) {
   2326             fprintf(out,
   2327                     "   videoDimensions(%d x %d), "
   2328                     "numVideoFramesDecoded(%lld), "
   2329                     "numVideoFramesDropped(%lld)\n",
   2330                     mStats.mVideoWidth,
   2331                     mStats.mVideoHeight,
   2332                     mStats.mNumVideoFramesDecoded,
   2333                     mStats.mNumVideoFramesDropped);
   2334         }
   2335     }
   2336 
   2337     fclose(out);
   2338     out = NULL;
   2339 
   2340     return OK;
   2341 }
   2342 
   2343 void AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
   2344     switch (mode) {
   2345         case SET:
   2346             mFlags |= value;
   2347             break;
   2348         case CLEAR:
   2349             mFlags &= ~value;
   2350             break;
   2351         case ASSIGN:
   2352             mFlags = value;
   2353             break;
   2354         default:
   2355             TRESPASS();
   2356     }
   2357 
   2358     {
   2359         Mutex::Autolock autoLock(mStatsLock);
   2360         mStats.mFlags = mFlags;
   2361     }
   2362 }
   2363 
   2364 }  // namespace android
   2365