Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #undef DEBUG_HDCP
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "AwesomePlayer"
     21 #define ATRACE_TAG ATRACE_TAG_VIDEO
     22 
     23 #include <inttypes.h>
     24 
     25 #include <utils/Log.h>
     26 #include <utils/Trace.h>
     27 
     28 #include <dlfcn.h>
     29 
     30 #include "include/AwesomePlayer.h"
     31 #include "include/DRMExtractor.h"
     32 #include "include/SoftwareRenderer.h"
     33 #include "include/NuCachedSource2.h"
     34 #include "include/ThrottledSource.h"
     35 #include "include/MPEG2TSExtractor.h"
     36 #include "include/WVMExtractor.h"
     37 
     38 #include <binder/IPCThreadState.h>
     39 #include <binder/IServiceManager.h>
     40 #include <media/IMediaHTTPConnection.h>
     41 #include <media/IMediaHTTPService.h>
     42 #include <media/IMediaPlayerService.h>
     43 #include <media/stagefright/foundation/hexdump.h>
     44 #include <media/stagefright/foundation/ADebug.h>
     45 #include <media/stagefright/timedtext/TimedTextDriver.h>
     46 #include <media/stagefright/AudioPlayer.h>
     47 #include <media/stagefright/ClockEstimator.h>
     48 #include <media/stagefright/DataSource.h>
     49 #include <media/stagefright/FileSource.h>
     50 #include <media/stagefright/MediaBuffer.h>
     51 #include <media/stagefright/MediaDefs.h>
     52 #include <media/stagefright/MediaExtractor.h>
     53 #include <media/stagefright/MediaHTTP.h>
     54 #include <media/stagefright/MediaSource.h>
     55 #include <media/stagefright/MetaData.h>
     56 #include <media/stagefright/OMXCodec.h>
     57 #include <media/stagefright/Utils.h>
     58 
     59 #include <gui/IGraphicBufferProducer.h>
     60 #include <gui/Surface.h>
     61 
     62 #include <media/stagefright/foundation/AMessage.h>
     63 
     64 #include <cutils/properties.h>
     65 
     66 #define USE_SURFACE_ALLOC 1
     67 #define FRAME_DROP_FREQ 0
     68 
     69 namespace android {
     70 
     71 static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
     72 static int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
     73 static const size_t kLowWaterMarkBytes = 40000;
     74 static const size_t kHighWaterMarkBytes = 200000;
     75 
     76 // maximum time in paused state when offloading audio decompression. When elapsed, the AudioPlayer
     77 // is destroyed to allow the audio DSP to power down.
     78 static int64_t kOffloadPauseMaxUs = 10000000ll;
     79 
     80 
     81 struct AwesomeEvent : public TimedEventQueue::Event {
     82     AwesomeEvent(
     83             AwesomePlayer *player,
     84             void (AwesomePlayer::*method)())
     85         : mPlayer(player),
     86           mMethod(method) {
     87     }
     88 
     89 protected:
     90     virtual ~AwesomeEvent() {}
     91 
     92     virtual void fire(TimedEventQueue * /* queue */, int64_t /* now_us */) {
     93         (mPlayer->*mMethod)();
     94     }
     95 
     96 private:
     97     AwesomePlayer *mPlayer;
     98     void (AwesomePlayer::*mMethod)();
     99 
    100     AwesomeEvent(const AwesomeEvent &);
    101     AwesomeEvent &operator=(const AwesomeEvent &);
    102 };
    103 
    104 struct AwesomeLocalRenderer : public AwesomeRenderer {
    105     AwesomeLocalRenderer(
    106             const sp<ANativeWindow> &nativeWindow, const sp<AMessage> &format)
    107         : mFormat(format),
    108           mTarget(new SoftwareRenderer(nativeWindow)) {
    109     }
    110 
    111     virtual void render(MediaBuffer *buffer) {
    112         int64_t timeUs;
    113         CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
    114 
    115         render((const uint8_t *)buffer->data() + buffer->range_offset(),
    116                buffer->range_length(), timeUs * 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 & AUTO_LOOPING) {
    882         audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
    883         if (mAudioSink != NULL) {
    884             streamType = mAudioSink->getAudioStreamType();
    885         }
    886         if (streamType == AUDIO_STREAM_NOTIFICATION) {
    887             ALOGW("disabling auto-loop for notification");
    888             modifyFlags(AUTO_LOOPING, CLEAR);
    889         }
    890     }
    891     if ((mFlags & LOOPING)
    892             || ((mFlags & AUTO_LOOPING)
    893                 && (mAudioSink == NULL || mAudioSink->realtime()))) {
    894         // Don't AUTO_LOOP if we're being recorded, since that cannot be
    895         // turned off and recording would go on indefinitely.
    896 
    897         seekTo_l(0);
    898 
    899         if (mVideoSource != NULL) {
    900             postVideoEvent_l();
    901         }
    902     } else {
    903         ALOGV("MEDIA_PLAYBACK_COMPLETE");
    904         notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
    905 
    906         pause_l(true /* at eos */);
    907 
    908         // If audio hasn't completed MEDIA_SEEK_COMPLETE yet,
    909         // notify MEDIA_SEEK_COMPLETE to observer immediately for state persistence.
    910         if (mWatchForAudioSeekComplete) {
    911             notifyListener_l(MEDIA_SEEK_COMPLETE);
    912             mWatchForAudioSeekComplete = false;
    913         }
    914 
    915         modifyFlags(AT_EOS, SET);
    916     }
    917 }
    918 
    919 status_t AwesomePlayer::play() {
    920     ATRACE_CALL();
    921 
    922     Mutex::Autolock autoLock(mLock);
    923 
    924     modifyFlags(CACHE_UNDERRUN, CLEAR);
    925 
    926     return play_l();
    927 }
    928 
    929 status_t AwesomePlayer::play_l() {
    930     modifyFlags(SEEK_PREVIEW, CLEAR);
    931 
    932     if (mFlags & PLAYING) {
    933         return OK;
    934     }
    935 
    936     mMediaRenderingStartGeneration = ++mStartGeneration;
    937 
    938     if (!(mFlags & PREPARED)) {
    939         status_t err = prepare_l();
    940 
    941         if (err != OK) {
    942             return err;
    943         }
    944     }
    945 
    946     modifyFlags(PLAYING, SET);
    947     modifyFlags(FIRST_FRAME, SET);
    948 
    949     if (mDecryptHandle != NULL) {
    950         int64_t position;
    951         getPosition(&position);
    952         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
    953                 Playback::START, position / 1000);
    954     }
    955 
    956     if (mAudioSource != NULL) {
    957         if (mAudioPlayer == NULL) {
    958             createAudioPlayer_l();
    959         }
    960 
    961         CHECK(!(mFlags & AUDIO_RUNNING));
    962 
    963         if (mVideoSource == NULL) {
    964 
    965             // We don't want to post an error notification at this point,
    966             // the error returned from MediaPlayer::start() will suffice.
    967 
    968             status_t err = startAudioPlayer_l(
    969                     false /* sendErrorNotification */);
    970 
    971             if ((err != OK) && mOffloadAudio) {
    972                 ALOGI("play_l() cannot create offload output, fallback to sw decode");
    973                 int64_t curTimeUs;
    974                 getPosition(&curTimeUs);
    975 
    976                 delete mAudioPlayer;
    977                 mAudioPlayer = NULL;
    978                 // if the player was started it will take care of stopping the source when destroyed
    979                 if (!(mFlags & AUDIOPLAYER_STARTED)) {
    980                     mAudioSource->stop();
    981                 }
    982                 modifyFlags((AUDIO_RUNNING | AUDIOPLAYER_STARTED), CLEAR);
    983                 mOffloadAudio = false;
    984                 mAudioSource = mOmxSource;
    985                 if (mAudioSource != NULL) {
    986                     err = mAudioSource->start();
    987 
    988                     if (err != OK) {
    989                         mAudioSource.clear();
    990                     } else {
    991                         mSeekNotificationSent = true;
    992                         if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
    993                             seekTo_l(curTimeUs);
    994                         }
    995                         createAudioPlayer_l();
    996                         err = startAudioPlayer_l(false);
    997                     }
    998                 }
    999             }
   1000 
   1001             if (err != OK) {
   1002                 delete mAudioPlayer;
   1003                 mAudioPlayer = NULL;
   1004 
   1005                 modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
   1006 
   1007                 if (mDecryptHandle != NULL) {
   1008                     mDrmManagerClient->setPlaybackStatus(
   1009                             mDecryptHandle, Playback::STOP, 0);
   1010                 }
   1011 
   1012                 return err;
   1013             }
   1014         }
   1015     }
   1016 
   1017     if (mTimeSource == NULL && mAudioPlayer == NULL) {
   1018         mTimeSource = &mSystemTimeSource;
   1019     }
   1020 
   1021     if (mVideoSource != NULL) {
   1022         // Kick off video playback
   1023         postVideoEvent_l();
   1024 
   1025         if (mAudioSource != NULL && mVideoSource != NULL) {
   1026             postVideoLagEvent_l();
   1027         }
   1028     }
   1029 
   1030     if (mFlags & AT_EOS) {
   1031         // Legacy behaviour, if a stream finishes playing and then
   1032         // is started again, we play from the start...
   1033         seekTo_l(0);
   1034     }
   1035 
   1036     uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
   1037         | IMediaPlayerService::kBatteryDataTrackDecoder;
   1038     if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
   1039         params |= IMediaPlayerService::kBatteryDataTrackAudio;
   1040     }
   1041     if (mVideoSource != NULL) {
   1042         params |= IMediaPlayerService::kBatteryDataTrackVideo;
   1043     }
   1044     addBatteryData(params);
   1045 
   1046     if (isStreamingHTTP()) {
   1047         postBufferingEvent_l();
   1048     }
   1049 
   1050     return OK;
   1051 }
   1052 
   1053 void AwesomePlayer::createAudioPlayer_l()
   1054 {
   1055     uint32_t flags = 0;
   1056     int64_t cachedDurationUs;
   1057     bool eos;
   1058 
   1059     if (mOffloadAudio) {
   1060         flags |= AudioPlayer::USE_OFFLOAD;
   1061     } else if (mVideoSource == NULL
   1062             && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US ||
   1063             (getCachedDuration_l(&cachedDurationUs, &eos) &&
   1064             cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US))) {
   1065         flags |= AudioPlayer::ALLOW_DEEP_BUFFERING;
   1066     }
   1067     if (isStreamingHTTP()) {
   1068         flags |= AudioPlayer::IS_STREAMING;
   1069     }
   1070     if (mVideoSource != NULL) {
   1071         flags |= AudioPlayer::HAS_VIDEO;
   1072     }
   1073 
   1074     mAudioPlayer = new AudioPlayer(mAudioSink, flags, this);
   1075     mAudioPlayer->setSource(mAudioSource);
   1076 
   1077     mTimeSource = mAudioPlayer;
   1078 
   1079     // If there was a seek request before we ever started,
   1080     // honor the request now.
   1081     // Make sure to do this before starting the audio player
   1082     // to avoid a race condition.
   1083     seekAudioIfNecessary_l();
   1084 }
   1085 
   1086 void AwesomePlayer::notifyIfMediaStarted_l() {
   1087     if (mMediaRenderingStartGeneration == mStartGeneration) {
   1088         mMediaRenderingStartGeneration = -1;
   1089         notifyListener_l(MEDIA_STARTED);
   1090     }
   1091 }
   1092 
   1093 status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
   1094     CHECK(!(mFlags & AUDIO_RUNNING));
   1095     status_t err = OK;
   1096 
   1097     if (mAudioSource == NULL || mAudioPlayer == NULL) {
   1098         return OK;
   1099     }
   1100 
   1101     if (mOffloadAudio) {
   1102         mQueue.cancelEvent(mAudioTearDownEvent->eventID());
   1103         mAudioTearDownEventPending = false;
   1104     }
   1105 
   1106     if (!(mFlags & AUDIOPLAYER_STARTED)) {
   1107         bool wasSeeking = mAudioPlayer->isSeeking();
   1108 
   1109         // We've already started the MediaSource in order to enable
   1110         // the prefetcher to read its data.
   1111         err = mAudioPlayer->start(
   1112                 true /* sourceAlreadyStarted */);
   1113 
   1114         if (err != OK) {
   1115             if (sendErrorNotification) {
   1116                 notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
   1117             }
   1118 
   1119             return err;
   1120         }
   1121 
   1122         modifyFlags(AUDIOPLAYER_STARTED, SET);
   1123 
   1124         if (wasSeeking) {
   1125             CHECK(!mAudioPlayer->isSeeking());
   1126 
   1127             // We will have finished the seek while starting the audio player.
   1128             postAudioSeekComplete();
   1129         } else {
   1130             notifyIfMediaStarted_l();
   1131         }
   1132     } else {
   1133         err = mAudioPlayer->resume();
   1134     }
   1135 
   1136     if (err == OK) {
   1137         modifyFlags(AUDIO_RUNNING, SET);
   1138 
   1139         mWatchForAudioEOS = true;
   1140     }
   1141 
   1142     return err;
   1143 }
   1144 
   1145 void AwesomePlayer::notifyVideoSize_l() {
   1146     ATRACE_CALL();
   1147     sp<MetaData> meta = mVideoSource->getFormat();
   1148 
   1149     int32_t cropLeft, cropTop, cropRight, cropBottom;
   1150     if (!meta->findRect(
   1151                 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
   1152         int32_t width, height;
   1153         CHECK(meta->findInt32(kKeyWidth, &width));
   1154         CHECK(meta->findInt32(kKeyHeight, &height));
   1155 
   1156         cropLeft = cropTop = 0;
   1157         cropRight = width - 1;
   1158         cropBottom = height - 1;
   1159 
   1160         ALOGV("got dimensions only %d x %d", width, height);
   1161     } else {
   1162         ALOGV("got crop rect %d, %d, %d, %d",
   1163              cropLeft, cropTop, cropRight, cropBottom);
   1164     }
   1165 
   1166     int32_t displayWidth;
   1167     if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
   1168         ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
   1169         mDisplayWidth = displayWidth;
   1170     }
   1171     int32_t displayHeight;
   1172     if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
   1173         ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
   1174         mDisplayHeight = displayHeight;
   1175     }
   1176 
   1177     int32_t usableWidth = cropRight - cropLeft + 1;
   1178     int32_t usableHeight = cropBottom - cropTop + 1;
   1179     if (mDisplayWidth != 0) {
   1180         usableWidth = mDisplayWidth;
   1181     }
   1182     if (mDisplayHeight != 0) {
   1183         usableHeight = mDisplayHeight;
   1184     }
   1185 
   1186     {
   1187         Mutex::Autolock autoLock(mStatsLock);
   1188         mStats.mVideoWidth = usableWidth;
   1189         mStats.mVideoHeight = usableHeight;
   1190     }
   1191 
   1192     int32_t rotationDegrees;
   1193     if (!mVideoTrack->getFormat()->findInt32(
   1194                 kKeyRotation, &rotationDegrees)) {
   1195         rotationDegrees = 0;
   1196     }
   1197 
   1198     if (rotationDegrees == 90 || rotationDegrees == 270) {
   1199         notifyListener_l(
   1200                 MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
   1201     } else {
   1202         notifyListener_l(
   1203                 MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
   1204     }
   1205 }
   1206 
   1207 void AwesomePlayer::initRenderer_l() {
   1208     ATRACE_CALL();
   1209 
   1210     if (mNativeWindow == NULL) {
   1211         return;
   1212     }
   1213 
   1214     sp<MetaData> meta = mVideoSource->getFormat();
   1215 
   1216     int32_t format;
   1217     const char *component;
   1218     int32_t decodedWidth, decodedHeight;
   1219     CHECK(meta->findInt32(kKeyColorFormat, &format));
   1220     CHECK(meta->findCString(kKeyDecoderComponent, &component));
   1221     CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
   1222     CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
   1223 
   1224     int32_t rotationDegrees;
   1225     if (!mVideoTrack->getFormat()->findInt32(
   1226                 kKeyRotation, &rotationDegrees)) {
   1227         rotationDegrees = 0;
   1228     }
   1229 
   1230     mVideoRenderer.clear();
   1231 
   1232     // Must ensure that mVideoRenderer's destructor is actually executed
   1233     // before creating a new one.
   1234     IPCThreadState::self()->flushCommands();
   1235 
   1236     // Even if set scaling mode fails, we will continue anyway
   1237     setVideoScalingMode_l(mVideoScalingMode);
   1238     if (USE_SURFACE_ALLOC
   1239             && !strncmp(component, "OMX.", 4)
   1240             && strncmp(component, "OMX.google.", 11)) {
   1241         // Hardware decoders avoid the CPU color conversion by decoding
   1242         // directly to ANativeBuffers, so we must use a renderer that
   1243         // just pushes those buffers to the ANativeWindow.
   1244         mVideoRenderer =
   1245             new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
   1246     } else {
   1247         // Other decoders are instantiated locally and as a consequence
   1248         // allocate their buffers in local address space.  This renderer
   1249         // then performs a color conversion and copy to get the data
   1250         // into the ANativeBuffer.
   1251         sp<AMessage> format;
   1252         convertMetaDataToMessage(meta, &format);
   1253         mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, format);
   1254     }
   1255 }
   1256 
   1257 status_t AwesomePlayer::pause() {
   1258     ATRACE_CALL();
   1259 
   1260     Mutex::Autolock autoLock(mLock);
   1261 
   1262     modifyFlags(CACHE_UNDERRUN, CLEAR);
   1263 
   1264     return pause_l();
   1265 }
   1266 
   1267 status_t AwesomePlayer::pause_l(bool at_eos) {
   1268     if (!(mFlags & PLAYING)) {
   1269         if (mAudioTearDown && mAudioTearDownWasPlaying) {
   1270             ALOGV("pause_l() during teardown and finishSetDataSource_l() mFlags %x" , mFlags);
   1271             mAudioTearDownWasPlaying = false;
   1272             notifyListener_l(MEDIA_PAUSED);
   1273             mMediaRenderingStartGeneration = ++mStartGeneration;
   1274         }
   1275         return OK;
   1276     }
   1277 
   1278     notifyListener_l(MEDIA_PAUSED);
   1279     mMediaRenderingStartGeneration = ++mStartGeneration;
   1280 
   1281     cancelPlayerEvents(true /* keepNotifications */);
   1282 
   1283     if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
   1284         // If we played the audio stream to completion we
   1285         // want to make sure that all samples remaining in the audio
   1286         // track's queue are played out.
   1287         mAudioPlayer->pause(at_eos /* playPendingSamples */);
   1288         // send us a reminder to tear down the AudioPlayer if paused for too long.
   1289         if (mOffloadAudio) {
   1290             postAudioTearDownEvent(kOffloadPauseMaxUs);
   1291         }
   1292         modifyFlags(AUDIO_RUNNING, CLEAR);
   1293     }
   1294 
   1295     if (mFlags & TEXTPLAYER_INITIALIZED) {
   1296         mTextDriver->pause();
   1297         modifyFlags(TEXT_RUNNING, CLEAR);
   1298     }
   1299 
   1300     modifyFlags(PLAYING, CLEAR);
   1301 
   1302     if (mDecryptHandle != NULL) {
   1303         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1304                 Playback::PAUSE, 0);
   1305     }
   1306 
   1307     uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
   1308     if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
   1309         params |= IMediaPlayerService::kBatteryDataTrackAudio;
   1310     }
   1311     if (mVideoSource != NULL) {
   1312         params |= IMediaPlayerService::kBatteryDataTrackVideo;
   1313     }
   1314 
   1315     addBatteryData(params);
   1316 
   1317     return OK;
   1318 }
   1319 
   1320 bool AwesomePlayer::isPlaying() const {
   1321     return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
   1322 }
   1323 
   1324 status_t AwesomePlayer::setSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {
   1325     Mutex::Autolock autoLock(mLock);
   1326 
   1327     status_t err;
   1328     if (bufferProducer != NULL) {
   1329         err = setNativeWindow_l(new Surface(bufferProducer));
   1330     } else {
   1331         err = setNativeWindow_l(NULL);
   1332     }
   1333 
   1334     return err;
   1335 }
   1336 
   1337 void AwesomePlayer::shutdownVideoDecoder_l() {
   1338     if (mVideoBuffer) {
   1339         mVideoBuffer->release();
   1340         mVideoBuffer = NULL;
   1341     }
   1342 
   1343     mVideoSource->stop();
   1344 
   1345     // The following hack is necessary to ensure that the OMX
   1346     // component is completely released by the time we may try
   1347     // to instantiate it again.
   1348     wp<MediaSource> tmp = mVideoSource;
   1349     mVideoSource.clear();
   1350     while (tmp.promote() != NULL) {
   1351         usleep(1000);
   1352     }
   1353     IPCThreadState::self()->flushCommands();
   1354     ALOGV("video decoder shutdown completed");
   1355 }
   1356 
   1357 status_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
   1358     mNativeWindow = native;
   1359 
   1360     if (mVideoSource == NULL) {
   1361         return OK;
   1362     }
   1363 
   1364     ALOGV("attempting to reconfigure to use new surface");
   1365 
   1366     bool wasPlaying = (mFlags & PLAYING) != 0;
   1367 
   1368     pause_l();
   1369     mVideoRenderer.clear();
   1370 
   1371     shutdownVideoDecoder_l();
   1372 
   1373     status_t err = initVideoDecoder();
   1374 
   1375     if (err != OK) {
   1376         ALOGE("failed to reinstantiate video decoder after surface change.");
   1377         return err;
   1378     }
   1379 
   1380     if (mLastVideoTimeUs >= 0) {
   1381         mSeeking = SEEK;
   1382         mSeekTimeUs = mLastVideoTimeUs;
   1383         modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
   1384     }
   1385 
   1386     if (wasPlaying) {
   1387         play_l();
   1388     }
   1389 
   1390     return OK;
   1391 }
   1392 
   1393 void AwesomePlayer::setAudioSink(
   1394         const sp<MediaPlayerBase::AudioSink> &audioSink) {
   1395     Mutex::Autolock autoLock(mLock);
   1396 
   1397     mAudioSink = audioSink;
   1398 }
   1399 
   1400 status_t AwesomePlayer::setLooping(bool shouldLoop) {
   1401     Mutex::Autolock autoLock(mLock);
   1402 
   1403     modifyFlags(LOOPING, CLEAR);
   1404 
   1405     if (shouldLoop) {
   1406         modifyFlags(LOOPING, SET);
   1407     }
   1408 
   1409     return OK;
   1410 }
   1411 
   1412 status_t AwesomePlayer::getDuration(int64_t *durationUs) {
   1413     Mutex::Autolock autoLock(mMiscStateLock);
   1414 
   1415     if (mDurationUs < 0) {
   1416         return UNKNOWN_ERROR;
   1417     }
   1418 
   1419     *durationUs = mDurationUs;
   1420 
   1421     return OK;
   1422 }
   1423 
   1424 status_t AwesomePlayer::getPosition(int64_t *positionUs) {
   1425     if (mSeeking != NO_SEEK) {
   1426         *positionUs = mSeekTimeUs;
   1427     } else if (mVideoSource != NULL
   1428             && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
   1429         Mutex::Autolock autoLock(mMiscStateLock);
   1430         *positionUs = mVideoTimeUs;
   1431     } else if (mAudioPlayer != NULL) {
   1432         *positionUs = mAudioPlayer->getMediaTimeUs();
   1433     } else {
   1434         *positionUs = 0;
   1435     }
   1436     return OK;
   1437 }
   1438 
   1439 status_t AwesomePlayer::seekTo(int64_t timeUs) {
   1440     ATRACE_CALL();
   1441 
   1442     if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
   1443         Mutex::Autolock autoLock(mLock);
   1444         return seekTo_l(timeUs);
   1445     }
   1446 
   1447     return OK;
   1448 }
   1449 
   1450 status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
   1451     if (mFlags & CACHE_UNDERRUN) {
   1452         modifyFlags(CACHE_UNDERRUN, CLEAR);
   1453         play_l();
   1454     }
   1455 
   1456     if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
   1457         // Video playback completed before, there's no pending
   1458         // video event right now. In order for this new seek
   1459         // to be honored, we need to post one.
   1460 
   1461         postVideoEvent_l();
   1462     }
   1463 
   1464     mSeeking = SEEK;
   1465     mSeekNotificationSent = false;
   1466     mSeekTimeUs = timeUs;
   1467     modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
   1468 
   1469     if (mFlags & PLAYING) {
   1470         notifyListener_l(MEDIA_PAUSED);
   1471         mMediaRenderingStartGeneration = ++mStartGeneration;
   1472     }
   1473 
   1474     seekAudioIfNecessary_l();
   1475 
   1476     if (mFlags & TEXTPLAYER_INITIALIZED) {
   1477         mTextDriver->seekToAsync(mSeekTimeUs);
   1478     }
   1479 
   1480     if (!(mFlags & PLAYING)) {
   1481         ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
   1482              " immediately.");
   1483 
   1484         notifyListener_l(MEDIA_SEEK_COMPLETE);
   1485         mSeekNotificationSent = true;
   1486 
   1487         if ((mFlags & PREPARED) && mVideoSource != NULL) {
   1488             modifyFlags(SEEK_PREVIEW, SET);
   1489             postVideoEvent_l();
   1490         }
   1491     }
   1492 
   1493     return OK;
   1494 }
   1495 
   1496 void AwesomePlayer::seekAudioIfNecessary_l() {
   1497     if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
   1498         mAudioPlayer->seekTo(mSeekTimeUs);
   1499 
   1500         mWatchForAudioSeekComplete = true;
   1501         mWatchForAudioEOS = true;
   1502 
   1503         if (mDecryptHandle != NULL) {
   1504             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1505                     Playback::PAUSE, 0);
   1506             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1507                     Playback::START, mSeekTimeUs / 1000);
   1508         }
   1509     }
   1510 }
   1511 
   1512 void AwesomePlayer::setAudioSource(sp<MediaSource> source) {
   1513     CHECK(source != NULL);
   1514 
   1515     mAudioTrack = source;
   1516 }
   1517 
   1518 void AwesomePlayer::addTextSource_l(size_t trackIndex, const sp<MediaSource>& source) {
   1519     CHECK(source != NULL);
   1520 
   1521     if (mTextDriver == NULL) {
   1522         mTextDriver = new TimedTextDriver(mListener, mHTTPService);
   1523     }
   1524 
   1525     mTextDriver->addInBandTextSource(trackIndex, source);
   1526 }
   1527 
   1528 status_t AwesomePlayer::initAudioDecoder() {
   1529     ATRACE_CALL();
   1530 
   1531     sp<MetaData> meta = mAudioTrack->getFormat();
   1532 
   1533     const char *mime;
   1534     CHECK(meta->findCString(kKeyMIMEType, &mime));
   1535     // Check whether there is a hardware codec for this stream
   1536     // This doesn't guarantee that the hardware has a free stream
   1537     // but it avoids us attempting to open (and re-open) an offload
   1538     // stream to hardware that doesn't have the necessary codec
   1539     audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
   1540     if (mAudioSink != NULL) {
   1541         streamType = mAudioSink->getAudioStreamType();
   1542     }
   1543 
   1544     mOffloadAudio = canOffloadStream(meta, (mVideoSource != NULL),
   1545                                      isStreamingHTTP(), streamType);
   1546 
   1547     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
   1548         ALOGV("createAudioPlayer: bypass OMX (raw)");
   1549         mAudioSource = mAudioTrack;
   1550     } else {
   1551         // If offloading we still create a OMX decoder as a fall-back
   1552         // but we don't start it
   1553         mOmxSource = OMXCodec::Create(
   1554                 mClient.interface(), mAudioTrack->getFormat(),
   1555                 false, // createEncoder
   1556                 mAudioTrack);
   1557 
   1558         if (mOffloadAudio) {
   1559             ALOGV("createAudioPlayer: bypass OMX (offload)");
   1560             mAudioSource = mAudioTrack;
   1561         } else {
   1562             mAudioSource = mOmxSource;
   1563         }
   1564     }
   1565 
   1566     if (mAudioSource != NULL) {
   1567         int64_t durationUs;
   1568         if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
   1569             Mutex::Autolock autoLock(mMiscStateLock);
   1570             if (mDurationUs < 0 || durationUs > mDurationUs) {
   1571                 mDurationUs = durationUs;
   1572             }
   1573         }
   1574 
   1575         status_t err = mAudioSource->start();
   1576 
   1577         if (err != OK) {
   1578             mAudioSource.clear();
   1579             mOmxSource.clear();
   1580             return err;
   1581         }
   1582     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
   1583         // For legacy reasons we're simply going to ignore the absence
   1584         // of an audio decoder for QCELP instead of aborting playback
   1585         // altogether.
   1586         return OK;
   1587     }
   1588 
   1589     if (mAudioSource != NULL) {
   1590         Mutex::Autolock autoLock(mStatsLock);
   1591         TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
   1592         const char *component;
   1593         if (!mAudioSource->getFormat()
   1594                 ->findCString(kKeyDecoderComponent, &component)) {
   1595             component = "none";
   1596         }
   1597 
   1598         stat->mDecoderName = component;
   1599     }
   1600 
   1601     return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
   1602 }
   1603 
   1604 void AwesomePlayer::setVideoSource(sp<MediaSource> source) {
   1605     CHECK(source != NULL);
   1606 
   1607     mVideoTrack = source;
   1608 }
   1609 
   1610 status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
   1611     ATRACE_CALL();
   1612 
   1613     // Either the application or the DRM system can independently say
   1614     // that there must be a hardware-protected path to an external video sink.
   1615     // For now we always require a hardware-protected path to external video sink
   1616     // if content is DRMed, but eventually this could be optional per DRM agent.
   1617     // When the application wants protection, then
   1618     //   (USE_SURFACE_ALLOC && (mSurface != 0) &&
   1619     //   (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
   1620     // will be true, but that part is already handled by SurfaceFlinger.
   1621 
   1622 #ifdef DEBUG_HDCP
   1623     // For debugging, we allow a system property to control the protected usage.
   1624     // In case of uninitialized or unexpected property, we default to "DRM only".
   1625     bool setProtectionBit = false;
   1626     char value[PROPERTY_VALUE_MAX];
   1627     if (property_get("persist.sys.hdcp_checking", value, NULL)) {
   1628         if (!strcmp(value, "never")) {
   1629             // nop
   1630         } else if (!strcmp(value, "always")) {
   1631             setProtectionBit = true;
   1632         } else if (!strcmp(value, "drm-only")) {
   1633             if (mDecryptHandle != NULL) {
   1634                 setProtectionBit = true;
   1635             }
   1636         // property value is empty, or unexpected value
   1637         } else {
   1638             if (mDecryptHandle != NULL) {
   1639                 setProtectionBit = true;
   1640             }
   1641         }
   1642     // can' read property value
   1643     } else {
   1644         if (mDecryptHandle != NULL) {
   1645             setProtectionBit = true;
   1646         }
   1647     }
   1648     // note that usage bit is already cleared, so no need to clear it in the "else" case
   1649     if (setProtectionBit) {
   1650         flags |= OMXCodec::kEnableGrallocUsageProtected;
   1651     }
   1652 #else
   1653     if (mDecryptHandle != NULL) {
   1654         flags |= OMXCodec::kEnableGrallocUsageProtected;
   1655     }
   1656 #endif
   1657     ALOGV("initVideoDecoder flags=0x%x", flags);
   1658     mVideoSource = OMXCodec::Create(
   1659             mClient.interface(), mVideoTrack->getFormat(),
   1660             false, // createEncoder
   1661             mVideoTrack,
   1662             NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
   1663 
   1664     if (mVideoSource != NULL) {
   1665         int64_t durationUs;
   1666         if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
   1667             Mutex::Autolock autoLock(mMiscStateLock);
   1668             if (mDurationUs < 0 || durationUs > mDurationUs) {
   1669                 mDurationUs = durationUs;
   1670             }
   1671         }
   1672 
   1673         status_t err = mVideoSource->start();
   1674 
   1675         if (err != OK) {
   1676             ALOGE("failed to start video source");
   1677             mVideoSource.clear();
   1678             return err;
   1679         }
   1680     }
   1681 
   1682     if (mVideoSource != NULL) {
   1683         const char *componentName;
   1684         CHECK(mVideoSource->getFormat()
   1685                 ->findCString(kKeyDecoderComponent, &componentName));
   1686 
   1687         {
   1688             Mutex::Autolock autoLock(mStatsLock);
   1689             TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
   1690 
   1691             stat->mDecoderName = componentName;
   1692         }
   1693 
   1694         static const char *kPrefix = "OMX.Nvidia.";
   1695         static const char *kSuffix = ".decode";
   1696         static const size_t kSuffixLength = strlen(kSuffix);
   1697 
   1698         size_t componentNameLength = strlen(componentName);
   1699 
   1700         if (!strncmp(componentName, kPrefix, strlen(kPrefix))
   1701                 && componentNameLength >= kSuffixLength
   1702                 && !strcmp(&componentName[
   1703                     componentNameLength - kSuffixLength], kSuffix)) {
   1704             modifyFlags(SLOW_DECODER_HACK, SET);
   1705         }
   1706     }
   1707 
   1708     return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
   1709 }
   1710 
   1711 void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
   1712     ATRACE_CALL();
   1713 
   1714     if (mSeeking == SEEK_VIDEO_ONLY) {
   1715         mSeeking = NO_SEEK;
   1716         return;
   1717     }
   1718 
   1719     if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
   1720         return;
   1721     }
   1722 
   1723     // If we paused, then seeked, then resumed, it is possible that we have
   1724     // signaled SEEK_COMPLETE at a copmletely different media time than where
   1725     // we are now resuming.  Signal new position to media time provider.
   1726     // Cannot signal another SEEK_COMPLETE, as existing clients may not expect
   1727     // multiple SEEK_COMPLETE responses to a single seek() request.
   1728     if (mSeekNotificationSent && abs(mSeekTimeUs - videoTimeUs) > 10000) {
   1729         // notify if we are resuming more than 10ms away from desired seek time
   1730         notifyListener_l(MEDIA_SKIPPED);
   1731     }
   1732 
   1733     if (mAudioPlayer != NULL) {
   1734         ALOGV("seeking audio to %" PRId64 " us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
   1735 
   1736         // If we don't have a video time, seek audio to the originally
   1737         // requested seek time instead.
   1738 
   1739         mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
   1740         mWatchForAudioSeekComplete = true;
   1741         mWatchForAudioEOS = true;
   1742     } else if (!mSeekNotificationSent) {
   1743         // If we're playing video only, report seek complete now,
   1744         // otherwise audio player will notify us later.
   1745         notifyListener_l(MEDIA_SEEK_COMPLETE);
   1746         mSeekNotificationSent = true;
   1747     }
   1748 
   1749     modifyFlags(FIRST_FRAME, SET);
   1750     mSeeking = NO_SEEK;
   1751 
   1752     if (mDecryptHandle != NULL) {
   1753         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1754                 Playback::PAUSE, 0);
   1755         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
   1756                 Playback::START, videoTimeUs / 1000);
   1757     }
   1758 }
   1759 
   1760 void AwesomePlayer::onVideoEvent() {
   1761     ATRACE_CALL();
   1762     Mutex::Autolock autoLock(mLock);
   1763     if (!mVideoEventPending) {
   1764         // The event has been cancelled in reset_l() but had already
   1765         // been scheduled for execution at that time.
   1766         return;
   1767     }
   1768     mVideoEventPending = false;
   1769 
   1770     if (mSeeking != NO_SEEK) {
   1771         if (mVideoBuffer) {
   1772             mVideoBuffer->release();
   1773             mVideoBuffer = NULL;
   1774         }
   1775 
   1776         if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
   1777                 && !(mFlags & SEEK_PREVIEW)) {
   1778             // We're going to seek the video source first, followed by
   1779             // the audio source.
   1780             // In order to avoid jumps in the DataSource offset caused by
   1781             // the audio codec prefetching data from the old locations
   1782             // while the video codec is already reading data from the new
   1783             // locations, we'll "pause" the audio source, causing it to
   1784             // stop reading input data until a subsequent seek.
   1785 
   1786             if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
   1787                 mAudioPlayer->pause();
   1788 
   1789                 modifyFlags(AUDIO_RUNNING, CLEAR);
   1790             }
   1791             mAudioSource->pause();
   1792         }
   1793     }
   1794 
   1795     if (!mVideoBuffer) {
   1796         MediaSource::ReadOptions options;
   1797         if (mSeeking != NO_SEEK) {
   1798             ALOGV("seeking to %" PRId64 " us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
   1799 
   1800             options.setSeekTo(
   1801                     mSeekTimeUs,
   1802                     mSeeking == SEEK_VIDEO_ONLY
   1803                         ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
   1804                         : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
   1805         }
   1806         for (;;) {
   1807             status_t err = mVideoSource->read(&mVideoBuffer, &options);
   1808             options.clearSeekTo();
   1809 
   1810             if (err != OK) {
   1811                 CHECK(mVideoBuffer == NULL);
   1812 
   1813                 if (err == INFO_FORMAT_CHANGED) {
   1814                     ALOGV("VideoSource signalled format change.");
   1815 
   1816                     notifyVideoSize_l();
   1817 
   1818                     if (mVideoRenderer != NULL) {
   1819                         mVideoRendererIsPreview = false;
   1820                         initRenderer_l();
   1821                     }
   1822                     continue;
   1823                 }
   1824 
   1825                 // So video playback is complete, but we may still have
   1826                 // a seek request pending that needs to be applied
   1827                 // to the audio track.
   1828                 if (mSeeking != NO_SEEK) {
   1829                     ALOGV("video stream ended while seeking!");
   1830                 }
   1831                 finishSeekIfNecessary(-1);
   1832 
   1833                 if (mAudioPlayer != NULL
   1834                         && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
   1835                     startAudioPlayer_l();
   1836                 }
   1837 
   1838                 modifyFlags(VIDEO_AT_EOS, SET);
   1839                 postStreamDoneEvent_l(err);
   1840                 return;
   1841             }
   1842 
   1843             if (mVideoBuffer->range_length() == 0) {
   1844                 // Some decoders, notably the PV AVC software decoder
   1845                 // return spurious empty buffers that we just want to ignore.
   1846 
   1847                 mVideoBuffer->release();
   1848                 mVideoBuffer = NULL;
   1849                 continue;
   1850             }
   1851 
   1852             break;
   1853         }
   1854 
   1855         {
   1856             Mutex::Autolock autoLock(mStatsLock);
   1857             ++mStats.mNumVideoFramesDecoded;
   1858         }
   1859     }
   1860 
   1861     int64_t timeUs;
   1862     CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
   1863 
   1864     mLastVideoTimeUs = timeUs;
   1865 
   1866     if (mSeeking == SEEK_VIDEO_ONLY) {
   1867         if (mSeekTimeUs > timeUs) {
   1868             ALOGI("XXX mSeekTimeUs = %" PRId64 " us, timeUs = %" PRId64 " us",
   1869                  mSeekTimeUs, timeUs);
   1870         }
   1871     }
   1872 
   1873     {
   1874         Mutex::Autolock autoLock(mMiscStateLock);
   1875         mVideoTimeUs = timeUs;
   1876     }
   1877 
   1878     SeekType wasSeeking = mSeeking;
   1879     finishSeekIfNecessary(timeUs);
   1880 
   1881     if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
   1882         status_t err = startAudioPlayer_l();
   1883         if (err != OK) {
   1884             ALOGE("Starting the audio player failed w/ err %d", err);
   1885             return;
   1886         }
   1887     }
   1888 
   1889     if ((mFlags & TEXTPLAYER_INITIALIZED)
   1890             && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
   1891         mTextDriver->start();
   1892         modifyFlags(TEXT_RUNNING, SET);
   1893     }
   1894 
   1895     TimeSource *ts =
   1896         ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
   1897             ? &mSystemTimeSource : mTimeSource;
   1898     int64_t systemTimeUs = mSystemTimeSource.getRealTimeUs();
   1899     int64_t looperTimeUs = ALooper::GetNowUs();
   1900 
   1901     if (mFlags & FIRST_FRAME) {
   1902         modifyFlags(FIRST_FRAME, CLEAR);
   1903         mSinceLastDropped = 0;
   1904         mClockEstimator->reset();
   1905         mTimeSourceDeltaUs = estimateRealTimeUs(ts, systemTimeUs) - timeUs;
   1906     }
   1907 
   1908     int64_t realTimeUs, mediaTimeUs;
   1909     if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
   1910         && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
   1911         ALOGV("updating TSdelta (%" PRId64 " => %" PRId64 " change %" PRId64 ")",
   1912               mTimeSourceDeltaUs, realTimeUs - mediaTimeUs,
   1913               mTimeSourceDeltaUs - (realTimeUs - mediaTimeUs));
   1914         ATRACE_INT("TS delta change (ms)", (mTimeSourceDeltaUs - (realTimeUs - mediaTimeUs)) / 1E3);
   1915         mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
   1916     }
   1917 
   1918     if (wasSeeking == SEEK_VIDEO_ONLY) {
   1919         int64_t nowUs = estimateRealTimeUs(ts, systemTimeUs) - mTimeSourceDeltaUs;
   1920 
   1921         int64_t latenessUs = nowUs - timeUs;
   1922 
   1923         ATRACE_INT("Video Lateness (ms)", latenessUs / 1E3);
   1924 
   1925         if (latenessUs > 0) {
   1926             ALOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
   1927         }
   1928     }
   1929 
   1930     int64_t latenessUs = 0;
   1931     if (wasSeeking == NO_SEEK) {
   1932         // Let's display the first frame after seeking right away.
   1933 
   1934         int64_t nowUs = estimateRealTimeUs(ts, systemTimeUs) - mTimeSourceDeltaUs;
   1935 
   1936         latenessUs = nowUs - timeUs;
   1937 
   1938         ATRACE_INT("Video Lateness (ms)", latenessUs / 1E3);
   1939 
   1940         if (latenessUs > 500000ll
   1941                 && mAudioPlayer != NULL
   1942                 && mAudioPlayer->getMediaTimeMapping(
   1943                     &realTimeUs, &mediaTimeUs)) {
   1944             if (mWVMExtractor == NULL) {
   1945                 ALOGI("we're much too late (%.2f secs), video skipping ahead",
   1946                      latenessUs / 1E6);
   1947 
   1948                 mVideoBuffer->release();
   1949                 mVideoBuffer = NULL;
   1950 
   1951                 mSeeking = SEEK_VIDEO_ONLY;
   1952                 mSeekTimeUs = mediaTimeUs;
   1953 
   1954                 postVideoEvent_l();
   1955                 return;
   1956             } else {
   1957                 // The widevine extractor doesn't deal well with seeking
   1958                 // audio and video independently. We'll just have to wait
   1959                 // until the decoder catches up, which won't be long at all.
   1960                 ALOGI("we're very late (%.2f secs)", latenessUs / 1E6);
   1961             }
   1962         }
   1963 
   1964         if (latenessUs > 40000) {
   1965             // We're more than 40ms late.
   1966             ALOGV("we're late by %" PRId64 " us (%.2f secs)",
   1967                  latenessUs, latenessUs / 1E6);
   1968 
   1969             if (!(mFlags & SLOW_DECODER_HACK)
   1970                     || mSinceLastDropped > FRAME_DROP_FREQ)
   1971             {
   1972                 ALOGV("we're late by %" PRId64 " us (%.2f secs) dropping "
   1973                      "one after %d frames",
   1974                      latenessUs, latenessUs / 1E6, mSinceLastDropped);
   1975 
   1976                 mSinceLastDropped = 0;
   1977                 mVideoBuffer->release();
   1978                 mVideoBuffer = NULL;
   1979 
   1980                 {
   1981                     Mutex::Autolock autoLock(mStatsLock);
   1982                     ++mStats.mNumVideoFramesDropped;
   1983                 }
   1984 
   1985                 postVideoEvent_l(0);
   1986                 return;
   1987             }
   1988         }
   1989 
   1990         if (latenessUs < -30000) {
   1991             // We're more than 30ms early, schedule at most 20 ms before time due
   1992             postVideoEvent_l(latenessUs < -60000 ? 30000 : -latenessUs - 20000);
   1993             return;
   1994         }
   1995     }
   1996 
   1997     if ((mNativeWindow != NULL)
   1998             && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {
   1999         mVideoRendererIsPreview = false;
   2000 
   2001         initRenderer_l();
   2002     }
   2003 
   2004     if (mVideoRenderer != NULL) {
   2005         mSinceLastDropped++;
   2006         mVideoBuffer->meta_data()->setInt64(kKeyTime, looperTimeUs - latenessUs);
   2007 
   2008         mVideoRenderer->render(mVideoBuffer);
   2009         if (!mVideoRenderingStarted) {
   2010             mVideoRenderingStarted = true;
   2011             notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START);
   2012         }
   2013 
   2014         if (mFlags & PLAYING) {
   2015             notifyIfMediaStarted_l();
   2016         }
   2017     }
   2018 
   2019     mVideoBuffer->release();
   2020     mVideoBuffer = NULL;
   2021 
   2022     if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
   2023         modifyFlags(SEEK_PREVIEW, CLEAR);
   2024         return;
   2025     }
   2026 
   2027     /* get next frame time */
   2028     if (wasSeeking == NO_SEEK) {
   2029         MediaSource::ReadOptions options;
   2030         for (;;) {
   2031             status_t err = mVideoSource->read(&mVideoBuffer, &options);
   2032             if (err != OK) {
   2033                 // deal with any errors next time
   2034                 CHECK(mVideoBuffer == NULL);
   2035                 postVideoEvent_l(0);
   2036                 return;
   2037             }
   2038 
   2039             if (mVideoBuffer->range_length() != 0) {
   2040                 break;
   2041             }
   2042 
   2043             // Some decoders, notably the PV AVC software decoder
   2044             // return spurious empty buffers that we just want to ignore.
   2045 
   2046             mVideoBuffer->release();
   2047             mVideoBuffer = NULL;
   2048         }
   2049 
   2050         {
   2051             Mutex::Autolock autoLock(mStatsLock);
   2052             ++mStats.mNumVideoFramesDecoded;
   2053         }
   2054 
   2055         int64_t nextTimeUs;
   2056         CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &nextTimeUs));
   2057         systemTimeUs = mSystemTimeSource.getRealTimeUs();
   2058         int64_t delayUs = nextTimeUs - estimateRealTimeUs(ts, systemTimeUs) + mTimeSourceDeltaUs;
   2059         ATRACE_INT("Frame delta (ms)", (nextTimeUs - timeUs) / 1E3);
   2060         ALOGV("next frame in %" PRId64, delayUs);
   2061         // try to schedule 30ms before time due
   2062         postVideoEvent_l(delayUs > 60000 ? 30000 : (delayUs < 30000 ? 0 : delayUs - 30000));
   2063         return;
   2064     }
   2065 
   2066     postVideoEvent_l();
   2067 }
   2068 
   2069 int64_t AwesomePlayer::estimateRealTimeUs(TimeSource *ts, int64_t systemTimeUs) {
   2070     if (ts == &mSystemTimeSource) {
   2071         return systemTimeUs;
   2072     } else {
   2073         return (int64_t)mClockEstimator->estimate(systemTimeUs, ts->getRealTimeUs());
   2074     }
   2075 }
   2076 
   2077 void AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
   2078     ATRACE_CALL();
   2079 
   2080     if (mVideoEventPending) {
   2081         return;
   2082     }
   2083 
   2084     mVideoEventPending = true;
   2085     mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
   2086 }
   2087 
   2088 void AwesomePlayer::postStreamDoneEvent_l(status_t status) {
   2089     if (mStreamDoneEventPending) {
   2090         return;
   2091     }
   2092     mStreamDoneEventPending = true;
   2093 
   2094     mStreamDoneStatus = status;
   2095     mQueue.postEvent(mStreamDoneEvent);
   2096 }
   2097 
   2098 void AwesomePlayer::postBufferingEvent_l() {
   2099     if (mBufferingEventPending) {
   2100         return;
   2101     }
   2102     mBufferingEventPending = true;
   2103     mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
   2104 }
   2105 
   2106 void AwesomePlayer::postVideoLagEvent_l() {
   2107     if (mVideoLagEventPending) {
   2108         return;
   2109     }
   2110     mVideoLagEventPending = true;
   2111     mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
   2112 }
   2113 
   2114 void AwesomePlayer::postCheckAudioStatusEvent(int64_t delayUs) {
   2115     Mutex::Autolock autoLock(mAudioLock);
   2116     if (mAudioStatusEventPending) {
   2117         return;
   2118     }
   2119     mAudioStatusEventPending = true;
   2120     // Do not honor delay when looping in order to limit audio gap
   2121     if (mFlags & (LOOPING | AUTO_LOOPING)) {
   2122         delayUs = 0;
   2123     }
   2124     mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
   2125 }
   2126 
   2127 void AwesomePlayer::postAudioTearDownEvent(int64_t delayUs) {
   2128     Mutex::Autolock autoLock(mAudioLock);
   2129     if (mAudioTearDownEventPending) {
   2130         return;
   2131     }
   2132     mAudioTearDownEventPending = true;
   2133     mQueue.postEventWithDelay(mAudioTearDownEvent, delayUs);
   2134 }
   2135 
   2136 void AwesomePlayer::onCheckAudioStatus() {
   2137     {
   2138         Mutex::Autolock autoLock(mAudioLock);
   2139         if (!mAudioStatusEventPending) {
   2140             // Event was dispatched and while we were blocking on the mutex,
   2141             // has already been cancelled.
   2142             return;
   2143         }
   2144 
   2145         mAudioStatusEventPending = false;
   2146     }
   2147 
   2148     Mutex::Autolock autoLock(mLock);
   2149 
   2150     if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
   2151         mWatchForAudioSeekComplete = false;
   2152 
   2153         if (!mSeekNotificationSent) {
   2154             notifyListener_l(MEDIA_SEEK_COMPLETE);
   2155             mSeekNotificationSent = true;
   2156         }
   2157 
   2158         if (mVideoSource == NULL) {
   2159             // For video the mSeeking flag is always reset in finishSeekIfNecessary
   2160             mSeeking = NO_SEEK;
   2161         }
   2162 
   2163         notifyIfMediaStarted_l();
   2164     }
   2165 
   2166     status_t finalStatus;
   2167     if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
   2168         mWatchForAudioEOS = false;
   2169         modifyFlags(AUDIO_AT_EOS, SET);
   2170         modifyFlags(FIRST_FRAME, SET);
   2171         postStreamDoneEvent_l(finalStatus);
   2172     }
   2173 }
   2174 
   2175 status_t AwesomePlayer::prepare() {
   2176     ATRACE_CALL();
   2177     Mutex::Autolock autoLock(mLock);
   2178     return prepare_l();
   2179 }
   2180 
   2181 status_t AwesomePlayer::prepare_l() {
   2182     if (mFlags & PREPARED) {
   2183         return OK;
   2184     }
   2185 
   2186     if (mFlags & PREPARING) {
   2187         return UNKNOWN_ERROR;
   2188     }
   2189 
   2190     mIsAsyncPrepare = false;
   2191     status_t err = prepareAsync_l();
   2192 
   2193     if (err != OK) {
   2194         return err;
   2195     }
   2196 
   2197     while (mFlags & PREPARING) {
   2198         mPreparedCondition.wait(mLock);
   2199     }
   2200 
   2201     return mPrepareResult;
   2202 }
   2203 
   2204 status_t AwesomePlayer::prepareAsync() {
   2205     ATRACE_CALL();
   2206     Mutex::Autolock autoLock(mLock);
   2207 
   2208     if (mFlags & PREPARING) {
   2209         return UNKNOWN_ERROR;  // async prepare already pending
   2210     }
   2211 
   2212     mIsAsyncPrepare = true;
   2213     return prepareAsync_l();
   2214 }
   2215 
   2216 status_t AwesomePlayer::prepareAsync_l() {
   2217     if (mFlags & PREPARING) {
   2218         return UNKNOWN_ERROR;  // async prepare already pending
   2219     }
   2220 
   2221     if (!mQueueStarted) {
   2222         mQueue.start();
   2223         mQueueStarted = true;
   2224     }
   2225 
   2226     modifyFlags(PREPARING, SET);
   2227     mAsyncPrepareEvent = new AwesomeEvent(
   2228             this, &AwesomePlayer::onPrepareAsyncEvent);
   2229 
   2230     mQueue.postEvent(mAsyncPrepareEvent);
   2231 
   2232     return OK;
   2233 }
   2234 
   2235 status_t AwesomePlayer::finishSetDataSource_l() {
   2236     ATRACE_CALL();
   2237     sp<DataSource> dataSource;
   2238 
   2239     bool isWidevineStreaming = false;
   2240     if (!strncasecmp("widevine://", mUri.string(), 11)) {
   2241         isWidevineStreaming = true;
   2242 
   2243         String8 newURI = String8("http://");
   2244         newURI.append(mUri.string() + 11);
   2245 
   2246         mUri = newURI;
   2247     }
   2248 
   2249     AString sniffedMIME;
   2250 
   2251     if (!strncasecmp("http://", mUri.string(), 7)
   2252             || !strncasecmp("https://", mUri.string(), 8)
   2253             || isWidevineStreaming) {
   2254         if (mHTTPService == NULL) {
   2255             ALOGE("Attempt to play media from http URI without HTTP service.");
   2256             return UNKNOWN_ERROR;
   2257         }
   2258 
   2259         sp<IMediaHTTPConnection> conn = mHTTPService->makeHTTPConnection();
   2260         mConnectingDataSource = new MediaHTTP(conn);
   2261 
   2262         String8 cacheConfig;
   2263         bool disconnectAtHighwatermark;
   2264         NuCachedSource2::RemoveCacheSpecificHeaders(
   2265                 &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
   2266 
   2267         mLock.unlock();
   2268         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
   2269         // force connection at this point, to avoid a race condition between getMIMEType and the
   2270         // caching datasource constructed below, which could result in multiple requests to the
   2271         // server, and/or failed connections.
   2272         String8 contentType = mConnectingDataSource->getMIMEType();
   2273         mLock.lock();
   2274 
   2275         if (err != OK) {
   2276             mConnectingDataSource.clear();
   2277 
   2278             ALOGI("mConnectingDataSource->connect() returned %d", err);
   2279             return err;
   2280         }
   2281 
   2282         if (!isWidevineStreaming) {
   2283             // The widevine extractor does its own caching.
   2284 
   2285 #if 0
   2286             mCachedSource = new NuCachedSource2(
   2287                     new ThrottledSource(
   2288                         mConnectingDataSource, 50 * 1024 /* bytes/sec */));
   2289 #else
   2290             mCachedSource = new NuCachedSource2(
   2291                     mConnectingDataSource,
   2292                     cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
   2293                     disconnectAtHighwatermark);
   2294 #endif
   2295 
   2296             dataSource = mCachedSource;
   2297         } else {
   2298             dataSource = mConnectingDataSource;
   2299         }
   2300 
   2301         mConnectingDataSource.clear();
   2302 
   2303         if (strncasecmp(contentType.string(), "audio/", 6)) {
   2304             // We're not doing this for streams that appear to be audio-only
   2305             // streams to ensure that even low bandwidth streams start
   2306             // playing back fairly instantly.
   2307 
   2308             // We're going to prefill the cache before trying to instantiate
   2309             // the extractor below, as the latter is an operation that otherwise
   2310             // could block on the datasource for a significant amount of time.
   2311             // During that time we'd be unable to abort the preparation phase
   2312             // without this prefill.
   2313             if (mCachedSource != NULL) {
   2314                 // We're going to prefill the cache before trying to instantiate
   2315                 // the extractor below, as the latter is an operation that otherwise
   2316                 // could block on the datasource for a significant amount of time.
   2317                 // During that time we'd be unable to abort the preparation phase
   2318                 // without this prefill.
   2319 
   2320                 mLock.unlock();
   2321 
   2322                 // Initially make sure we have at least 192 KB for the sniff
   2323                 // to complete without blocking.
   2324                 static const size_t kMinBytesForSniffing = 192 * 1024;
   2325 
   2326                 off64_t metaDataSize = -1ll;
   2327                 for (;;) {
   2328                     status_t finalStatus;
   2329                     size_t cachedDataRemaining =
   2330                         mCachedSource->approxDataRemaining(&finalStatus);
   2331 
   2332                     if (finalStatus != OK
   2333                             || (metaDataSize >= 0
   2334                                 && (off64_t)cachedDataRemaining >= metaDataSize)
   2335                             || (mFlags & PREPARE_CANCELLED)) {
   2336                         break;
   2337                     }
   2338 
   2339                     ALOGV("now cached %zu bytes of data", cachedDataRemaining);
   2340 
   2341                     if (metaDataSize < 0
   2342                             && cachedDataRemaining >= kMinBytesForSniffing) {
   2343                         String8 tmp;
   2344                         float confidence;
   2345                         sp<AMessage> meta;
   2346                         if (!dataSource->sniff(&tmp, &confidence, &meta)) {
   2347                             mLock.lock();
   2348                             return UNKNOWN_ERROR;
   2349                         }
   2350 
   2351                         // We successfully identified the file's extractor to
   2352                         // be, remember this mime type so we don't have to
   2353                         // sniff it again when we call MediaExtractor::Create()
   2354                         // below.
   2355                         sniffedMIME = tmp.string();
   2356 
   2357                         if (meta == NULL
   2358                                 || !meta->findInt64("meta-data-size",
   2359                                      reinterpret_cast<int64_t*>(&metaDataSize))) {
   2360                             metaDataSize = kHighWaterMarkBytes;
   2361                         }
   2362 
   2363                         CHECK_GE(metaDataSize, 0ll);
   2364                         ALOGV("metaDataSize = %lld bytes", metaDataSize);
   2365                     }
   2366 
   2367                     usleep(200000);
   2368                 }
   2369 
   2370                 mLock.lock();
   2371             }
   2372 
   2373             if (mFlags & PREPARE_CANCELLED) {
   2374                 ALOGI("Prepare cancelled while waiting for initial cache fill.");
   2375                 return UNKNOWN_ERROR;
   2376             }
   2377         }
   2378     } else {
   2379         dataSource = DataSource::CreateFromURI(
   2380                 mHTTPService, mUri.string(), &mUriHeaders);
   2381     }
   2382 
   2383     if (dataSource == NULL) {
   2384         return UNKNOWN_ERROR;
   2385     }
   2386 
   2387     sp<MediaExtractor> extractor;
   2388 
   2389     if (isWidevineStreaming) {
   2390         String8 mimeType;
   2391         float confidence;
   2392         sp<AMessage> dummy;
   2393         bool success;
   2394 
   2395         // SniffWVM is potentially blocking since it may require network access.
   2396         // Do not call it with mLock held.
   2397         mLock.unlock();
   2398         success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
   2399         mLock.lock();
   2400 
   2401         if (!success
   2402                 || strcasecmp(
   2403                     mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
   2404             return ERROR_UNSUPPORTED;
   2405         }
   2406 
   2407         mWVMExtractor = new WVMExtractor(dataSource);
   2408         mWVMExtractor->setAdaptiveStreamingMode(true);
   2409         if (mUIDValid)
   2410             mWVMExtractor->setUID(mUID);
   2411         extractor = mWVMExtractor;
   2412     } else {
   2413         extractor = MediaExtractor::Create(
   2414                 dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
   2415 
   2416         if (extractor == NULL) {
   2417             return UNKNOWN_ERROR;
   2418         }
   2419     }
   2420 
   2421     if (extractor->getDrmFlag()) {
   2422         checkDrmStatus(dataSource);
   2423     }
   2424 
   2425     status_t err = setDataSource_l(extractor);
   2426 
   2427     if (err != OK) {
   2428         mWVMExtractor.clear();
   2429 
   2430         return err;
   2431     }
   2432 
   2433     return OK;
   2434 }
   2435 
   2436 void AwesomePlayer::abortPrepare(status_t err) {
   2437     CHECK(err != OK);
   2438 
   2439     if (mIsAsyncPrepare) {
   2440         notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
   2441     }
   2442 
   2443     mPrepareResult = err;
   2444     modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
   2445     mAsyncPrepareEvent = NULL;
   2446     mPreparedCondition.broadcast();
   2447     mAudioTearDown = false;
   2448 }
   2449 
   2450 // static
   2451 bool AwesomePlayer::ContinuePreparation(void *cookie) {
   2452     AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
   2453 
   2454     return (me->mFlags & PREPARE_CANCELLED) == 0;
   2455 }
   2456 
   2457 void AwesomePlayer::onPrepareAsyncEvent() {
   2458     Mutex::Autolock autoLock(mLock);
   2459     beginPrepareAsync_l();
   2460 }
   2461 
   2462 void AwesomePlayer::beginPrepareAsync_l() {
   2463     if (mFlags & PREPARE_CANCELLED) {
   2464         ALOGI("prepare was cancelled before doing anything");
   2465         abortPrepare(UNKNOWN_ERROR);
   2466         return;
   2467     }
   2468 
   2469     if (mUri.size() > 0) {
   2470         status_t err = finishSetDataSource_l();
   2471 
   2472         if (err != OK) {
   2473             abortPrepare(err);
   2474             return;
   2475         }
   2476     }
   2477 
   2478     if (mVideoTrack != NULL && mVideoSource == NULL) {
   2479         status_t err = initVideoDecoder();
   2480 
   2481         if (err != OK) {
   2482             abortPrepare(err);
   2483             return;
   2484         }
   2485     }
   2486 
   2487     if (mAudioTrack != NULL && mAudioSource == NULL) {
   2488         status_t err = initAudioDecoder();
   2489 
   2490         if (err != OK) {
   2491             abortPrepare(err);
   2492             return;
   2493         }
   2494     }
   2495 
   2496     modifyFlags(PREPARING_CONNECTED, SET);
   2497 
   2498     if (isStreamingHTTP()) {
   2499         postBufferingEvent_l();
   2500     } else {
   2501         finishAsyncPrepare_l();
   2502     }
   2503 }
   2504 
   2505 void AwesomePlayer::finishAsyncPrepare_l() {
   2506     if (mIsAsyncPrepare) {
   2507         if (mVideoSource == NULL) {
   2508             notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
   2509         } else {
   2510             notifyVideoSize_l();
   2511         }
   2512 
   2513         notifyListener_l(MEDIA_PREPARED);
   2514     }
   2515 
   2516     mPrepareResult = OK;
   2517     modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
   2518     modifyFlags(PREPARED, SET);
   2519     mAsyncPrepareEvent = NULL;
   2520     mPreparedCondition.broadcast();
   2521 
   2522     if (mAudioTearDown) {
   2523         if (mPrepareResult == OK) {
   2524             if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
   2525                 seekTo_l(mAudioTearDownPosition);
   2526             }
   2527 
   2528             if (mAudioTearDownWasPlaying) {
   2529                 modifyFlags(CACHE_UNDERRUN, CLEAR);
   2530                 play_l();
   2531             }
   2532         }
   2533         mAudioTearDown = false;
   2534     }
   2535 }
   2536 
   2537 uint32_t AwesomePlayer::flags() const {
   2538     return mExtractorFlags;
   2539 }
   2540 
   2541 void AwesomePlayer::postAudioEOS(int64_t delayUs) {
   2542     postCheckAudioStatusEvent(delayUs);
   2543 }
   2544 
   2545 void AwesomePlayer::postAudioSeekComplete() {
   2546     postCheckAudioStatusEvent(0);
   2547 }
   2548 
   2549 void AwesomePlayer::postAudioTearDown() {
   2550     postAudioTearDownEvent(0);
   2551 }
   2552 
   2553 status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
   2554     switch (key) {
   2555         case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
   2556         {
   2557             return setCacheStatCollectFreq(request);
   2558         }
   2559         case KEY_PARAMETER_PLAYBACK_RATE_PERMILLE:
   2560         {
   2561             if (mAudioPlayer != NULL) {
   2562                 return mAudioPlayer->setPlaybackRatePermille(request.readInt32());
   2563             } else {
   2564                 return NO_INIT;
   2565             }
   2566         }
   2567         default:
   2568         {
   2569             return ERROR_UNSUPPORTED;
   2570         }
   2571     }
   2572 }
   2573 
   2574 status_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
   2575     if (mCachedSource != NULL) {
   2576         int32_t freqMs = request.readInt32();
   2577         ALOGD("Request to keep cache stats in the past %d ms",
   2578             freqMs);
   2579         return mCachedSource->setCacheStatCollectFreq(freqMs);
   2580     }
   2581     return ERROR_UNSUPPORTED;
   2582 }
   2583 
   2584 status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
   2585     switch (key) {
   2586     case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
   2587         {
   2588             int32_t channelCount;
   2589             if (mAudioTrack == 0 ||
   2590                     !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
   2591                 channelCount = 0;
   2592             }
   2593             reply->writeInt32(channelCount);
   2594         }
   2595         return OK;
   2596     default:
   2597         {
   2598             return ERROR_UNSUPPORTED;
   2599         }
   2600     }
   2601 }
   2602 
   2603 status_t AwesomePlayer::getTrackInfo(Parcel *reply) const {
   2604     Mutex::Autolock autoLock(mLock);
   2605     size_t trackCount = mExtractor->countTracks();
   2606     if (mTextDriver != NULL) {
   2607         trackCount += mTextDriver->countExternalTracks();
   2608     }
   2609 
   2610     reply->writeInt32(trackCount);
   2611     for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
   2612         sp<MetaData> meta = mExtractor->getTrackMetaData(i);
   2613 
   2614         const char *_mime;
   2615         CHECK(meta->findCString(kKeyMIMEType, &_mime));
   2616 
   2617         String8 mime = String8(_mime);
   2618 
   2619         reply->writeInt32(2); // 2 fields
   2620 
   2621         if (!strncasecmp(mime.string(), "video/", 6)) {
   2622             reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO);
   2623         } else if (!strncasecmp(mime.string(), "audio/", 6)) {
   2624             reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO);
   2625         } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
   2626             reply->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
   2627         } else {
   2628             reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN);
   2629         }
   2630 
   2631         const char *lang;
   2632         if (!meta->findCString(kKeyMediaLanguage, &lang)) {
   2633             lang = "und";
   2634         }
   2635         reply->writeString16(String16(lang));
   2636     }
   2637 
   2638     if (mTextDriver != NULL) {
   2639         mTextDriver->getExternalTrackInfo(reply);
   2640     }
   2641     return OK;
   2642 }
   2643 
   2644 status_t AwesomePlayer::selectAudioTrack_l(
   2645         const sp<MediaSource>& source, size_t trackIndex) {
   2646 
   2647     ALOGI("selectAudioTrack_l: trackIndex=%zu, mFlags=0x%x", trackIndex, mFlags);
   2648 
   2649     {
   2650         Mutex::Autolock autoLock(mStatsLock);
   2651         if ((ssize_t)trackIndex == mActiveAudioTrackIndex) {
   2652             ALOGI("Track %zu is active. Does nothing.", trackIndex);
   2653             return OK;
   2654         }
   2655         //mStats.mFlags = mFlags;
   2656     }
   2657 
   2658     if (mSeeking != NO_SEEK) {
   2659         ALOGE("Selecting a track while seeking is not supported");
   2660         return ERROR_UNSUPPORTED;
   2661     }
   2662 
   2663     if ((mFlags & PREPARED) == 0) {
   2664         ALOGE("Data source has not finished preparation");
   2665         return ERROR_UNSUPPORTED;
   2666     }
   2667 
   2668     CHECK(source != NULL);
   2669     bool wasPlaying = (mFlags & PLAYING) != 0;
   2670 
   2671     pause_l();
   2672 
   2673     int64_t curTimeUs;
   2674     CHECK_EQ(getPosition(&curTimeUs), (status_t)OK);
   2675 
   2676     if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
   2677             && mAudioSource != NULL) {
   2678         // If we had an audio player, it would have effectively
   2679         // taken possession of the audio source and stopped it when
   2680         // _it_ is stopped. Otherwise this is still our responsibility.
   2681         mAudioSource->stop();
   2682     }
   2683     mAudioSource.clear();
   2684     mOmxSource.clear();
   2685 
   2686     mTimeSource = NULL;
   2687 
   2688     delete mAudioPlayer;
   2689     mAudioPlayer = NULL;
   2690 
   2691     modifyFlags(AUDIOPLAYER_STARTED, CLEAR);
   2692 
   2693     setAudioSource(source);
   2694 
   2695     modifyFlags(AUDIO_AT_EOS, CLEAR);
   2696     modifyFlags(AT_EOS, CLEAR);
   2697 
   2698     status_t err;
   2699     if ((err = initAudioDecoder()) != OK) {
   2700         ALOGE("Failed to init audio decoder: 0x%x", err);
   2701         return err;
   2702     }
   2703 
   2704     mSeekNotificationSent = true;
   2705     seekTo_l(curTimeUs);
   2706 
   2707     if (wasPlaying) {
   2708         play_l();
   2709     }
   2710 
   2711     mActiveAudioTrackIndex = trackIndex;
   2712 
   2713     return OK;
   2714 }
   2715 
   2716 status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
   2717     ATRACE_CALL();
   2718     ALOGV("selectTrack: trackIndex = %zu and select=%d", trackIndex, select);
   2719     Mutex::Autolock autoLock(mLock);
   2720     size_t trackCount = mExtractor->countTracks();
   2721     if (mTextDriver != NULL) {
   2722         trackCount += mTextDriver->countExternalTracks();
   2723     }
   2724     if (trackIndex >= trackCount) {
   2725         ALOGE("Track index (%zu) is out of range [0, %zu)", trackIndex, trackCount);
   2726         return ERROR_OUT_OF_RANGE;
   2727     }
   2728 
   2729     bool isAudioTrack = false;
   2730     if (trackIndex < mExtractor->countTracks()) {
   2731         sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex);
   2732         const char *mime;
   2733         CHECK(meta->findCString(kKeyMIMEType, &mime));
   2734         isAudioTrack = !strncasecmp(mime, "audio/", 6);
   2735 
   2736         if (!isAudioTrack && strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) != 0) {
   2737             ALOGE("Track %zu is not either audio or timed text", trackIndex);
   2738             return ERROR_UNSUPPORTED;
   2739         }
   2740     }
   2741 
   2742     if (isAudioTrack) {
   2743         if (!select) {
   2744             ALOGE("Deselect an audio track (%zu) is not supported", trackIndex);
   2745             return ERROR_UNSUPPORTED;
   2746         }
   2747         return selectAudioTrack_l(mExtractor->getTrack(trackIndex), trackIndex);
   2748     }
   2749 
   2750     // Timed text track handling
   2751     if (mTextDriver == NULL) {
   2752         return INVALID_OPERATION;
   2753     }
   2754 
   2755     status_t err = OK;
   2756     if (select) {
   2757         err = mTextDriver->selectTrack(trackIndex);
   2758         if (err == OK) {
   2759             modifyFlags(TEXTPLAYER_INITIALIZED, SET);
   2760             if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) {
   2761                 mTextDriver->start();
   2762                 modifyFlags(TEXT_RUNNING, SET);
   2763             }
   2764         }
   2765     } else {
   2766         err = mTextDriver->unselectTrack(trackIndex);
   2767         if (err == OK) {
   2768             modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR);
   2769             modifyFlags(TEXT_RUNNING, CLEAR);
   2770         }
   2771     }
   2772     return err;
   2773 }
   2774 
   2775 size_t AwesomePlayer::countTracks() const {
   2776     return mExtractor->countTracks() + mTextDriver->countExternalTracks();
   2777 }
   2778 
   2779 status_t AwesomePlayer::setVideoScalingMode(int32_t mode) {
   2780     Mutex::Autolock lock(mLock);
   2781     return setVideoScalingMode_l(mode);
   2782 }
   2783 
   2784 status_t AwesomePlayer::setVideoScalingMode_l(int32_t mode) {
   2785     mVideoScalingMode = mode;
   2786     if (mNativeWindow != NULL) {
   2787         status_t err = native_window_set_scaling_mode(
   2788                 mNativeWindow.get(), mVideoScalingMode);
   2789         if (err != OK) {
   2790             ALOGW("Failed to set scaling mode: %d", err);
   2791         }
   2792         return err;
   2793     }
   2794     return OK;
   2795 }
   2796 
   2797 status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
   2798     ATRACE_CALL();
   2799     if (NULL == reply) {
   2800         return android::BAD_VALUE;
   2801     }
   2802     int32_t methodId;
   2803     status_t ret = request.readInt32(&methodId);
   2804     if (ret != android::OK) {
   2805         return ret;
   2806     }
   2807     switch(methodId) {
   2808         case INVOKE_ID_SET_VIDEO_SCALING_MODE:
   2809         {
   2810             int mode = request.readInt32();
   2811             return setVideoScalingMode(mode);
   2812         }
   2813 
   2814         case INVOKE_ID_GET_TRACK_INFO:
   2815         {
   2816             return getTrackInfo(reply);
   2817         }
   2818         case INVOKE_ID_ADD_EXTERNAL_SOURCE:
   2819         {
   2820             Mutex::Autolock autoLock(mLock);
   2821             if (mTextDriver == NULL) {
   2822                 mTextDriver = new TimedTextDriver(mListener, mHTTPService);
   2823             }
   2824             // String values written in Parcel are UTF-16 values.
   2825             String8 uri(request.readString16());
   2826             String8 mimeType(request.readString16());
   2827             size_t nTracks = countTracks();
   2828             return mTextDriver->addOutOfBandTextSource(nTracks, uri, mimeType);
   2829         }
   2830         case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD:
   2831         {
   2832             Mutex::Autolock autoLock(mLock);
   2833             if (mTextDriver == NULL) {
   2834                 mTextDriver = new TimedTextDriver(mListener, mHTTPService);
   2835             }
   2836             int fd         = request.readFileDescriptor();
   2837             off64_t offset = request.readInt64();
   2838             off64_t length  = request.readInt64();
   2839             String8 mimeType(request.readString16());
   2840             size_t nTracks = countTracks();
   2841             return mTextDriver->addOutOfBandTextSource(
   2842                     nTracks, fd, offset, length, mimeType);
   2843         }
   2844         case INVOKE_ID_SELECT_TRACK:
   2845         {
   2846             int trackIndex = request.readInt32();
   2847             return selectTrack(trackIndex, true /* select */);
   2848         }
   2849         case INVOKE_ID_UNSELECT_TRACK:
   2850         {
   2851             int trackIndex = request.readInt32();
   2852             return selectTrack(trackIndex, false /* select */);
   2853         }
   2854         default:
   2855         {
   2856             return ERROR_UNSUPPORTED;
   2857         }
   2858     }
   2859     // It will not reach here.
   2860     return OK;
   2861 }
   2862 
   2863 bool AwesomePlayer::isStreamingHTTP() const {
   2864     return mCachedSource != NULL || mWVMExtractor != NULL;
   2865 }
   2866 
   2867 status_t AwesomePlayer::dump(
   2868         int fd, const Vector<String16> & /* args */) const {
   2869     Mutex::Autolock autoLock(mStatsLock);
   2870 
   2871     FILE *out = fdopen(dup(fd), "w");
   2872 
   2873     fprintf(out, " AwesomePlayer\n");
   2874     if (mStats.mFd < 0) {
   2875         fprintf(out, "  URI(%s)", uriDebugString(mUri, mFlags & INCOGNITO).c_str());
   2876     } else {
   2877         fprintf(out, "  fd(%d)", mStats.mFd);
   2878     }
   2879 
   2880     fprintf(out, ", flags(0x%08x)", mStats.mFlags);
   2881 
   2882     if (mStats.mBitrate >= 0) {
   2883         fprintf(out, ", bitrate(%" PRId64 " bps)", mStats.mBitrate);
   2884     }
   2885 
   2886     fprintf(out, "\n");
   2887 
   2888     for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
   2889         const TrackStat &stat = mStats.mTracks.itemAt(i);
   2890 
   2891         fprintf(out, "  Track %zu\n", i + 1);
   2892         fprintf(out, "   MIME(%s)", stat.mMIME.string());
   2893 
   2894         if (!stat.mDecoderName.isEmpty()) {
   2895             fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
   2896         }
   2897 
   2898         fprintf(out, "\n");
   2899 
   2900         if ((ssize_t)i == mStats.mVideoTrackIndex) {
   2901             fprintf(out,
   2902                     "   videoDimensions(%d x %d), "
   2903                     "numVideoFramesDecoded(%" PRId64 "), "
   2904                     "numVideoFramesDropped(%" PRId64 ")\n",
   2905                     mStats.mVideoWidth,
   2906                     mStats.mVideoHeight,
   2907                     mStats.mNumVideoFramesDecoded,
   2908                     mStats.mNumVideoFramesDropped);
   2909         }
   2910     }
   2911 
   2912     fclose(out);
   2913     out = NULL;
   2914 
   2915     return OK;
   2916 }
   2917 
   2918 void AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
   2919     switch (mode) {
   2920         case SET:
   2921             mFlags |= value;
   2922             break;
   2923         case CLEAR:
   2924             if ((value & CACHE_UNDERRUN) && (mFlags & CACHE_UNDERRUN)) {
   2925                 notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
   2926             }
   2927             mFlags &= ~value;
   2928             break;
   2929         case ASSIGN:
   2930             mFlags = value;
   2931             break;
   2932         default:
   2933             TRESPASS();
   2934     }
   2935 
   2936     {
   2937         Mutex::Autolock autoLock(mStatsLock);
   2938         mStats.mFlags = mFlags;
   2939     }
   2940 }
   2941 
   2942 void AwesomePlayer::onAudioTearDownEvent() {
   2943 
   2944     Mutex::Autolock autoLock(mLock);
   2945     if (!mAudioTearDownEventPending) {
   2946         return;
   2947     }
   2948     mAudioTearDownEventPending = false;
   2949 
   2950     ALOGV("onAudioTearDownEvent");
   2951 
   2952     // stream info is cleared by reset_l() so copy what we need
   2953     mAudioTearDownWasPlaying = (mFlags & PLAYING);
   2954     KeyedVector<String8, String8> uriHeaders(mUriHeaders);
   2955     sp<DataSource> fileSource(mFileSource);
   2956 
   2957     mStatsLock.lock();
   2958     String8 uri(mStats.mURI);
   2959     mStatsLock.unlock();
   2960 
   2961     // get current position so we can start recreated stream from here
   2962     getPosition(&mAudioTearDownPosition);
   2963 
   2964     sp<IMediaHTTPService> savedHTTPService = mHTTPService;
   2965 
   2966     bool wasLooping = mFlags & LOOPING;
   2967     // Reset and recreate
   2968     reset_l();
   2969 
   2970     status_t err;
   2971 
   2972     if (fileSource != NULL) {
   2973         mFileSource = fileSource;
   2974         err = setDataSource_l(fileSource);
   2975     } else {
   2976         err = setDataSource_l(savedHTTPService, uri, &uriHeaders);
   2977     }
   2978 
   2979     mFlags |= PREPARING;
   2980     if ( err != OK ) {
   2981         // This will force beingPrepareAsync_l() to notify
   2982         // a MEDIA_ERROR to the client and abort the prepare
   2983         mFlags |= PREPARE_CANCELLED;
   2984     }
   2985     if (wasLooping) {
   2986         mFlags |= LOOPING;
   2987     }
   2988 
   2989     mAudioTearDown = true;
   2990     mIsAsyncPrepare = true;
   2991 
   2992     // Call prepare for the host decoding
   2993     beginPrepareAsync_l();
   2994 }
   2995 
   2996 }  // namespace android
   2997