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