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