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