Home | History | Annotate | Download | only in nuplayer
      1 /*
      2  * Copyright (C) 2010 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 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "NuPlayer"
     19 #include <utils/Log.h>
     20 
     21 #include "NuPlayer.h"
     22 
     23 #include "HTTPLiveSource.h"
     24 #include "NuPlayerCCDecoder.h"
     25 #include "NuPlayerDecoder.h"
     26 #include "NuPlayerDecoderBase.h"
     27 #include "NuPlayerDecoderPassThrough.h"
     28 #include "NuPlayerDriver.h"
     29 #include "NuPlayerRenderer.h"
     30 #include "NuPlayerSource.h"
     31 #include "RTSPSource.h"
     32 #include "StreamingSource.h"
     33 #include "GenericSource.h"
     34 #include "TextDescriptions.h"
     35 
     36 #include "ATSParser.h"
     37 
     38 #include <cutils/properties.h>
     39 
     40 #include <media/stagefright/foundation/hexdump.h>
     41 #include <media/stagefright/foundation/ABuffer.h>
     42 #include <media/stagefright/foundation/ADebug.h>
     43 #include <media/stagefright/foundation/AMessage.h>
     44 #include <media/stagefright/MediaBuffer.h>
     45 #include <media/stagefright/MediaDefs.h>
     46 #include <media/stagefright/MediaErrors.h>
     47 #include <media/stagefright/MetaData.h>
     48 #include <gui/IGraphicBufferProducer.h>
     49 
     50 #include "avc_utils.h"
     51 
     52 #include "ESDS.h"
     53 #include <media/stagefright/Utils.h>
     54 
     55 namespace android {
     56 
     57 struct NuPlayer::Action : public RefBase {
     58     Action() {}
     59 
     60     virtual void execute(NuPlayer *player) = 0;
     61 
     62 private:
     63     DISALLOW_EVIL_CONSTRUCTORS(Action);
     64 };
     65 
     66 struct NuPlayer::SeekAction : public Action {
     67     SeekAction(int64_t seekTimeUs, bool needNotify)
     68         : mSeekTimeUs(seekTimeUs),
     69           mNeedNotify(needNotify) {
     70     }
     71 
     72     virtual void execute(NuPlayer *player) {
     73         player->performSeek(mSeekTimeUs, mNeedNotify);
     74     }
     75 
     76 private:
     77     int64_t mSeekTimeUs;
     78     bool mNeedNotify;
     79 
     80     DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
     81 };
     82 
     83 struct NuPlayer::ResumeDecoderAction : public Action {
     84     ResumeDecoderAction(bool needNotify)
     85         : mNeedNotify(needNotify) {
     86     }
     87 
     88     virtual void execute(NuPlayer *player) {
     89         player->performResumeDecoders(mNeedNotify);
     90     }
     91 
     92 private:
     93     bool mNeedNotify;
     94 
     95     DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
     96 };
     97 
     98 struct NuPlayer::SetSurfaceAction : public Action {
     99     SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
    100         : mWrapper(wrapper) {
    101     }
    102 
    103     virtual void execute(NuPlayer *player) {
    104         player->performSetSurface(mWrapper);
    105     }
    106 
    107 private:
    108     sp<NativeWindowWrapper> mWrapper;
    109 
    110     DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
    111 };
    112 
    113 struct NuPlayer::FlushDecoderAction : public Action {
    114     FlushDecoderAction(FlushCommand audio, FlushCommand video)
    115         : mAudio(audio),
    116           mVideo(video) {
    117     }
    118 
    119     virtual void execute(NuPlayer *player) {
    120         player->performDecoderFlush(mAudio, mVideo);
    121     }
    122 
    123 private:
    124     FlushCommand mAudio;
    125     FlushCommand mVideo;
    126 
    127     DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
    128 };
    129 
    130 struct NuPlayer::PostMessageAction : public Action {
    131     PostMessageAction(const sp<AMessage> &msg)
    132         : mMessage(msg) {
    133     }
    134 
    135     virtual void execute(NuPlayer *) {
    136         mMessage->post();
    137     }
    138 
    139 private:
    140     sp<AMessage> mMessage;
    141 
    142     DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
    143 };
    144 
    145 // Use this if there's no state necessary to save in order to execute
    146 // the action.
    147 struct NuPlayer::SimpleAction : public Action {
    148     typedef void (NuPlayer::*ActionFunc)();
    149 
    150     SimpleAction(ActionFunc func)
    151         : mFunc(func) {
    152     }
    153 
    154     virtual void execute(NuPlayer *player) {
    155         (player->*mFunc)();
    156     }
    157 
    158 private:
    159     ActionFunc mFunc;
    160 
    161     DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
    162 };
    163 
    164 ////////////////////////////////////////////////////////////////////////////////
    165 
    166 NuPlayer::NuPlayer()
    167     : mUIDValid(false),
    168       mSourceFlags(0),
    169       mOffloadAudio(false),
    170       mAudioDecoderGeneration(0),
    171       mVideoDecoderGeneration(0),
    172       mRendererGeneration(0),
    173       mAudioEOS(false),
    174       mVideoEOS(false),
    175       mScanSourcesPending(false),
    176       mScanSourcesGeneration(0),
    177       mPollDurationGeneration(0),
    178       mTimedTextGeneration(0),
    179       mFlushingAudio(NONE),
    180       mFlushingVideo(NONE),
    181       mResumePending(false),
    182       mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
    183       mStarted(false),
    184       mPaused(false),
    185       mPausedByClient(false) {
    186     clearFlushComplete();
    187 }
    188 
    189 NuPlayer::~NuPlayer() {
    190 }
    191 
    192 void NuPlayer::setUID(uid_t uid) {
    193     mUIDValid = true;
    194     mUID = uid;
    195 }
    196 
    197 void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
    198     mDriver = driver;
    199 }
    200 
    201 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
    202     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    203 
    204     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    205 
    206     msg->setObject("source", new StreamingSource(notify, source));
    207     msg->post();
    208 }
    209 
    210 static bool IsHTTPLiveURL(const char *url) {
    211     if (!strncasecmp("http://", url, 7)
    212             || !strncasecmp("https://", url, 8)
    213             || !strncasecmp("file://", url, 7)) {
    214         size_t len = strlen(url);
    215         if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
    216             return true;
    217         }
    218 
    219         if (strstr(url,"m3u8")) {
    220             return true;
    221         }
    222     }
    223 
    224     return false;
    225 }
    226 
    227 void NuPlayer::setDataSourceAsync(
    228         const sp<IMediaHTTPService> &httpService,
    229         const char *url,
    230         const KeyedVector<String8, String8> *headers) {
    231 
    232     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    233     size_t len = strlen(url);
    234 
    235     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    236 
    237     sp<Source> source;
    238     if (IsHTTPLiveURL(url)) {
    239         source = new HTTPLiveSource(notify, httpService, url, headers);
    240     } else if (!strncasecmp(url, "rtsp://", 7)) {
    241         source = new RTSPSource(
    242                 notify, httpService, url, headers, mUIDValid, mUID);
    243     } else if ((!strncasecmp(url, "http://", 7)
    244                 || !strncasecmp(url, "https://", 8))
    245                     && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
    246                     || strstr(url, ".sdp?"))) {
    247         source = new RTSPSource(
    248                 notify, httpService, url, headers, mUIDValid, mUID, true);
    249     } else {
    250         sp<GenericSource> genericSource =
    251                 new GenericSource(notify, mUIDValid, mUID);
    252         // Don't set FLAG_SECURE on mSourceFlags here for widevine.
    253         // The correct flags will be updated in Source::kWhatFlagsChanged
    254         // handler when  GenericSource is prepared.
    255 
    256         status_t err = genericSource->setDataSource(httpService, url, headers);
    257 
    258         if (err == OK) {
    259             source = genericSource;
    260         } else {
    261             ALOGE("Failed to set data source!");
    262         }
    263     }
    264     msg->setObject("source", source);
    265     msg->post();
    266 }
    267 
    268 void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
    269     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    270 
    271     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    272 
    273     sp<GenericSource> source =
    274             new GenericSource(notify, mUIDValid, mUID);
    275 
    276     status_t err = source->setDataSource(fd, offset, length);
    277 
    278     if (err != OK) {
    279         ALOGE("Failed to set data source!");
    280         source = NULL;
    281     }
    282 
    283     msg->setObject("source", source);
    284     msg->post();
    285 }
    286 
    287 void NuPlayer::prepareAsync() {
    288     (new AMessage(kWhatPrepare, id()))->post();
    289 }
    290 
    291 void NuPlayer::setVideoSurfaceTextureAsync(
    292         const sp<IGraphicBufferProducer> &bufferProducer) {
    293     sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
    294 
    295     if (bufferProducer == NULL) {
    296         msg->setObject("native-window", NULL);
    297     } else {
    298         msg->setObject(
    299                 "native-window",
    300                 new NativeWindowWrapper(
    301                     new Surface(bufferProducer, true /* controlledByApp */)));
    302     }
    303 
    304     msg->post();
    305 }
    306 
    307 void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
    308     sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
    309     msg->setObject("sink", sink);
    310     msg->post();
    311 }
    312 
    313 void NuPlayer::start() {
    314     (new AMessage(kWhatStart, id()))->post();
    315 }
    316 
    317 void NuPlayer::pause() {
    318     (new AMessage(kWhatPause, id()))->post();
    319 }
    320 
    321 void NuPlayer::resetAsync() {
    322     if (mSource != NULL) {
    323         // During a reset, the data source might be unresponsive already, we need to
    324         // disconnect explicitly so that reads exit promptly.
    325         // We can't queue the disconnect request to the looper, as it might be
    326         // queued behind a stuck read and never gets processed.
    327         // Doing a disconnect outside the looper to allows the pending reads to exit
    328         // (either successfully or with error).
    329         mSource->disconnect();
    330     }
    331 
    332     (new AMessage(kWhatReset, id()))->post();
    333 }
    334 
    335 void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
    336     sp<AMessage> msg = new AMessage(kWhatSeek, id());
    337     msg->setInt64("seekTimeUs", seekTimeUs);
    338     msg->setInt32("needNotify", needNotify);
    339     msg->post();
    340 }
    341 
    342 
    343 void NuPlayer::writeTrackInfo(
    344         Parcel* reply, const sp<AMessage> format) const {
    345     int32_t trackType;
    346     CHECK(format->findInt32("type", &trackType));
    347 
    348     AString lang;
    349     CHECK(format->findString("language", &lang));
    350 
    351     reply->writeInt32(2); // write something non-zero
    352     reply->writeInt32(trackType);
    353     reply->writeString16(String16(lang.c_str()));
    354 
    355     if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
    356         AString mime;
    357         CHECK(format->findString("mime", &mime));
    358 
    359         int32_t isAuto, isDefault, isForced;
    360         CHECK(format->findInt32("auto", &isAuto));
    361         CHECK(format->findInt32("default", &isDefault));
    362         CHECK(format->findInt32("forced", &isForced));
    363 
    364         reply->writeString16(String16(mime.c_str()));
    365         reply->writeInt32(isAuto);
    366         reply->writeInt32(isDefault);
    367         reply->writeInt32(isForced);
    368     }
    369 }
    370 
    371 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
    372     switch (msg->what()) {
    373         case kWhatSetDataSource:
    374         {
    375             ALOGV("kWhatSetDataSource");
    376 
    377             CHECK(mSource == NULL);
    378 
    379             status_t err = OK;
    380             sp<RefBase> obj;
    381             CHECK(msg->findObject("source", &obj));
    382             if (obj != NULL) {
    383                 mSource = static_cast<Source *>(obj.get());
    384             } else {
    385                 err = UNKNOWN_ERROR;
    386             }
    387 
    388             CHECK(mDriver != NULL);
    389             sp<NuPlayerDriver> driver = mDriver.promote();
    390             if (driver != NULL) {
    391                 driver->notifySetDataSourceCompleted(err);
    392             }
    393             break;
    394         }
    395 
    396         case kWhatPrepare:
    397         {
    398             mSource->prepareAsync();
    399             break;
    400         }
    401 
    402         case kWhatGetTrackInfo:
    403         {
    404             uint32_t replyID;
    405             CHECK(msg->senderAwaitsResponse(&replyID));
    406 
    407             Parcel* reply;
    408             CHECK(msg->findPointer("reply", (void**)&reply));
    409 
    410             size_t inbandTracks = 0;
    411             if (mSource != NULL) {
    412                 inbandTracks = mSource->getTrackCount();
    413             }
    414 
    415             size_t ccTracks = 0;
    416             if (mCCDecoder != NULL) {
    417                 ccTracks = mCCDecoder->getTrackCount();
    418             }
    419 
    420             // total track count
    421             reply->writeInt32(inbandTracks + ccTracks);
    422 
    423             // write inband tracks
    424             for (size_t i = 0; i < inbandTracks; ++i) {
    425                 writeTrackInfo(reply, mSource->getTrackInfo(i));
    426             }
    427 
    428             // write CC track
    429             for (size_t i = 0; i < ccTracks; ++i) {
    430                 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
    431             }
    432 
    433             sp<AMessage> response = new AMessage;
    434             response->postReply(replyID);
    435             break;
    436         }
    437 
    438         case kWhatGetSelectedTrack:
    439         {
    440             status_t err = INVALID_OPERATION;
    441             if (mSource != NULL) {
    442                 err = OK;
    443 
    444                 int32_t type32;
    445                 CHECK(msg->findInt32("type", (int32_t*)&type32));
    446                 media_track_type type = (media_track_type)type32;
    447                 ssize_t selectedTrack = mSource->getSelectedTrack(type);
    448 
    449                 Parcel* reply;
    450                 CHECK(msg->findPointer("reply", (void**)&reply));
    451                 reply->writeInt32(selectedTrack);
    452             }
    453 
    454             sp<AMessage> response = new AMessage;
    455             response->setInt32("err", err);
    456 
    457             uint32_t replyID;
    458             CHECK(msg->senderAwaitsResponse(&replyID));
    459             response->postReply(replyID);
    460             break;
    461         }
    462 
    463         case kWhatSelectTrack:
    464         {
    465             uint32_t replyID;
    466             CHECK(msg->senderAwaitsResponse(&replyID));
    467 
    468             size_t trackIndex;
    469             int32_t select;
    470             int64_t timeUs;
    471             CHECK(msg->findSize("trackIndex", &trackIndex));
    472             CHECK(msg->findInt32("select", &select));
    473             CHECK(msg->findInt64("timeUs", &timeUs));
    474 
    475             status_t err = INVALID_OPERATION;
    476 
    477             size_t inbandTracks = 0;
    478             if (mSource != NULL) {
    479                 inbandTracks = mSource->getTrackCount();
    480             }
    481             size_t ccTracks = 0;
    482             if (mCCDecoder != NULL) {
    483                 ccTracks = mCCDecoder->getTrackCount();
    484             }
    485 
    486             if (trackIndex < inbandTracks) {
    487                 err = mSource->selectTrack(trackIndex, select, timeUs);
    488 
    489                 if (!select && err == OK) {
    490                     int32_t type;
    491                     sp<AMessage> info = mSource->getTrackInfo(trackIndex);
    492                     if (info != NULL
    493                             && info->findInt32("type", &type)
    494                             && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
    495                         ++mTimedTextGeneration;
    496                     }
    497                 }
    498             } else {
    499                 trackIndex -= inbandTracks;
    500 
    501                 if (trackIndex < ccTracks) {
    502                     err = mCCDecoder->selectTrack(trackIndex, select);
    503                 }
    504             }
    505 
    506             sp<AMessage> response = new AMessage;
    507             response->setInt32("err", err);
    508 
    509             response->postReply(replyID);
    510             break;
    511         }
    512 
    513         case kWhatPollDuration:
    514         {
    515             int32_t generation;
    516             CHECK(msg->findInt32("generation", &generation));
    517 
    518             if (generation != mPollDurationGeneration) {
    519                 // stale
    520                 break;
    521             }
    522 
    523             int64_t durationUs;
    524             if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
    525                 sp<NuPlayerDriver> driver = mDriver.promote();
    526                 if (driver != NULL) {
    527                     driver->notifyDuration(durationUs);
    528                 }
    529             }
    530 
    531             msg->post(1000000ll);  // poll again in a second.
    532             break;
    533         }
    534 
    535         case kWhatSetVideoNativeWindow:
    536         {
    537             ALOGV("kWhatSetVideoNativeWindow");
    538 
    539             sp<RefBase> obj;
    540             CHECK(msg->findObject("native-window", &obj));
    541 
    542             if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) {
    543                 performSetSurface(static_cast<NativeWindowWrapper *>(obj.get()));
    544                 break;
    545             }
    546 
    547             mDeferredActions.push_back(
    548                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
    549                                            FLUSH_CMD_SHUTDOWN /* video */));
    550 
    551             mDeferredActions.push_back(
    552                     new SetSurfaceAction(
    553                         static_cast<NativeWindowWrapper *>(obj.get())));
    554 
    555             if (obj != NULL) {
    556                 if (mStarted) {
    557                     // Issue a seek to refresh the video screen only if started otherwise
    558                     // the extractor may not yet be started and will assert.
    559                     // If the video decoder is not set (perhaps audio only in this case)
    560                     // do not perform a seek as it is not needed.
    561                     int64_t currentPositionUs = 0;
    562                     if (getCurrentPosition(&currentPositionUs) == OK) {
    563                         mDeferredActions.push_back(
    564                                 new SeekAction(currentPositionUs, false /* needNotify */));
    565                     }
    566                 }
    567 
    568                 // If there is a new surface texture, instantiate decoders
    569                 // again if possible.
    570                 mDeferredActions.push_back(
    571                         new SimpleAction(&NuPlayer::performScanSources));
    572             }
    573 
    574             // After a flush without shutdown, decoder is paused.
    575             // Don't resume it until source seek is done, otherwise it could
    576             // start pulling stale data too soon.
    577             mDeferredActions.push_back(
    578                     new ResumeDecoderAction(false /* needNotify */));
    579 
    580             processDeferredActions();
    581             break;
    582         }
    583 
    584         case kWhatSetAudioSink:
    585         {
    586             ALOGV("kWhatSetAudioSink");
    587 
    588             sp<RefBase> obj;
    589             CHECK(msg->findObject("sink", &obj));
    590 
    591             mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
    592             break;
    593         }
    594 
    595         case kWhatStart:
    596         {
    597             ALOGV("kWhatStart");
    598             if (mStarted) {
    599                 onResume();
    600             } else {
    601                 onStart();
    602             }
    603             mPausedByClient = false;
    604             break;
    605         }
    606 
    607         case kWhatScanSources:
    608         {
    609             int32_t generation;
    610             CHECK(msg->findInt32("generation", &generation));
    611             if (generation != mScanSourcesGeneration) {
    612                 // Drop obsolete msg.
    613                 break;
    614             }
    615 
    616             mScanSourcesPending = false;
    617 
    618             ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
    619                  mAudioDecoder != NULL, mVideoDecoder != NULL);
    620 
    621             bool mHadAnySourcesBefore =
    622                 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
    623 
    624             // initialize video before audio because successful initialization of
    625             // video may change deep buffer mode of audio.
    626             if (mNativeWindow != NULL) {
    627                 instantiateDecoder(false, &mVideoDecoder);
    628             }
    629 
    630             // Don't try to re-open audio sink if there's an existing decoder.
    631             if (mAudioSink != NULL && mAudioDecoder == NULL) {
    632                 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
    633                 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
    634                 audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
    635                 const bool hasVideo = (videoFormat != NULL);
    636                 const bool canOffload = canOffloadStream(
    637                         audioMeta, hasVideo, true /* is_streaming */, streamType);
    638                 if (canOffload) {
    639                     if (!mOffloadAudio) {
    640                         mRenderer->signalEnableOffloadAudio();
    641                     }
    642                     // open audio sink early under offload mode.
    643                     sp<AMessage> format = mSource->getFormat(true /*audio*/);
    644                     tryOpenAudioSinkForOffload(format, hasVideo);
    645                 }
    646                 instantiateDecoder(true, &mAudioDecoder);
    647             }
    648 
    649             if (!mHadAnySourcesBefore
    650                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
    651                 // This is the first time we've found anything playable.
    652 
    653                 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
    654                     schedulePollDuration();
    655                 }
    656             }
    657 
    658             status_t err;
    659             if ((err = mSource->feedMoreTSData()) != OK) {
    660                 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
    661                     // We're not currently decoding anything (no audio or
    662                     // video tracks found) and we just ran out of input data.
    663 
    664                     if (err == ERROR_END_OF_STREAM) {
    665                         notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
    666                     } else {
    667                         notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
    668                     }
    669                 }
    670                 break;
    671             }
    672 
    673             if ((mAudioDecoder == NULL && mAudioSink != NULL)
    674                     || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
    675                 msg->post(100000ll);
    676                 mScanSourcesPending = true;
    677             }
    678             break;
    679         }
    680 
    681         case kWhatVideoNotify:
    682         case kWhatAudioNotify:
    683         {
    684             bool audio = msg->what() == kWhatAudioNotify;
    685 
    686             int32_t currentDecoderGeneration =
    687                 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
    688             int32_t requesterGeneration = currentDecoderGeneration - 1;
    689             CHECK(msg->findInt32("generation", &requesterGeneration));
    690 
    691             if (requesterGeneration != currentDecoderGeneration) {
    692                 ALOGV("got message from old %s decoder, generation(%d:%d)",
    693                         audio ? "audio" : "video", requesterGeneration,
    694                         currentDecoderGeneration);
    695                 sp<AMessage> reply;
    696                 if (!(msg->findMessage("reply", &reply))) {
    697                     return;
    698                 }
    699 
    700                 reply->setInt32("err", INFO_DISCONTINUITY);
    701                 reply->post();
    702                 return;
    703             }
    704 
    705             int32_t what;
    706             CHECK(msg->findInt32("what", &what));
    707 
    708             if (what == DecoderBase::kWhatInputDiscontinuity) {
    709                 int32_t formatChange;
    710                 CHECK(msg->findInt32("formatChange", &formatChange));
    711 
    712                 ALOGV("%s discontinuity: formatChange %d",
    713                         audio ? "audio" : "video", formatChange);
    714 
    715                 if (formatChange) {
    716                     mDeferredActions.push_back(
    717                             new FlushDecoderAction(
    718                                 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
    719                                 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
    720                 }
    721 
    722                 mDeferredActions.push_back(
    723                         new SimpleAction(
    724                                 &NuPlayer::performScanSources));
    725 
    726                 processDeferredActions();
    727             } else if (what == DecoderBase::kWhatEOS) {
    728                 int32_t err;
    729                 CHECK(msg->findInt32("err", &err));
    730 
    731                 if (err == ERROR_END_OF_STREAM) {
    732                     ALOGV("got %s decoder EOS", audio ? "audio" : "video");
    733                 } else {
    734                     ALOGV("got %s decoder EOS w/ error %d",
    735                          audio ? "audio" : "video",
    736                          err);
    737                 }
    738 
    739                 mRenderer->queueEOS(audio, err);
    740             } else if (what == DecoderBase::kWhatFlushCompleted) {
    741                 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
    742 
    743                 handleFlushComplete(audio, true /* isDecoder */);
    744                 finishFlushIfPossible();
    745             } else if (what == DecoderBase::kWhatVideoSizeChanged) {
    746                 sp<AMessage> format;
    747                 CHECK(msg->findMessage("format", &format));
    748 
    749                 sp<AMessage> inputFormat =
    750                         mSource->getFormat(false /* audio */);
    751 
    752                 updateVideoSize(inputFormat, format);
    753             } else if (what == DecoderBase::kWhatShutdownCompleted) {
    754                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
    755                 if (audio) {
    756                     mAudioDecoder.clear();
    757                     ++mAudioDecoderGeneration;
    758 
    759                     CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
    760                     mFlushingAudio = SHUT_DOWN;
    761                 } else {
    762                     mVideoDecoder.clear();
    763                     ++mVideoDecoderGeneration;
    764 
    765                     CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
    766                     mFlushingVideo = SHUT_DOWN;
    767                 }
    768 
    769                 finishFlushIfPossible();
    770             } else if (what == DecoderBase::kWhatResumeCompleted) {
    771                 finishResume();
    772             } else if (what == DecoderBase::kWhatError) {
    773                 status_t err;
    774                 if (!msg->findInt32("err", &err) || err == OK) {
    775                     err = UNKNOWN_ERROR;
    776                 }
    777 
    778                 // Decoder errors can be due to Source (e.g. from streaming),
    779                 // or from decoding corrupted bitstreams, or from other decoder
    780                 // MediaCodec operations (e.g. from an ongoing reset or seek).
    781                 // They may also be due to openAudioSink failure at
    782                 // decoder start or after a format change.
    783                 //
    784                 // We try to gracefully shut down the affected decoder if possible,
    785                 // rather than trying to force the shutdown with something
    786                 // similar to performReset(). This method can lead to a hang
    787                 // if MediaCodec functions block after an error, but they should
    788                 // typically return INVALID_OPERATION instead of blocking.
    789 
    790                 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
    791                 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
    792                         err, audio ? "audio" : "video", *flushing);
    793 
    794                 switch (*flushing) {
    795                     case NONE:
    796                         mDeferredActions.push_back(
    797                                 new FlushDecoderAction(
    798                                     audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
    799                                     audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
    800                         processDeferredActions();
    801                         break;
    802                     case FLUSHING_DECODER:
    803                         *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
    804                         break; // Wait for flush to complete.
    805                     case FLUSHING_DECODER_SHUTDOWN:
    806                         break; // Wait for flush to complete.
    807                     case SHUTTING_DOWN_DECODER:
    808                         break; // Wait for shutdown to complete.
    809                     case FLUSHED:
    810                         // Widevine source reads must stop before releasing the video decoder.
    811                         if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
    812                             mSource->stop();
    813                         }
    814                         getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
    815                         *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
    816                         break;
    817                     case SHUT_DOWN:
    818                         finishFlushIfPossible();  // Should not occur.
    819                         break;                    // Finish anyways.
    820                 }
    821                 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
    822             } else {
    823                 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
    824                       what,
    825                       what >> 24,
    826                       (what >> 16) & 0xff,
    827                       (what >> 8) & 0xff,
    828                       what & 0xff);
    829             }
    830 
    831             break;
    832         }
    833 
    834         case kWhatRendererNotify:
    835         {
    836             int32_t requesterGeneration = mRendererGeneration - 1;
    837             CHECK(msg->findInt32("generation", &requesterGeneration));
    838             if (requesterGeneration != mRendererGeneration) {
    839                 ALOGV("got message from old renderer, generation(%d:%d)",
    840                         requesterGeneration, mRendererGeneration);
    841                 return;
    842             }
    843 
    844             int32_t what;
    845             CHECK(msg->findInt32("what", &what));
    846 
    847             if (what == Renderer::kWhatEOS) {
    848                 int32_t audio;
    849                 CHECK(msg->findInt32("audio", &audio));
    850 
    851                 int32_t finalResult;
    852                 CHECK(msg->findInt32("finalResult", &finalResult));
    853 
    854                 if (audio) {
    855                     mAudioEOS = true;
    856                 } else {
    857                     mVideoEOS = true;
    858                 }
    859 
    860                 if (finalResult == ERROR_END_OF_STREAM) {
    861                     ALOGV("reached %s EOS", audio ? "audio" : "video");
    862                 } else {
    863                     ALOGE("%s track encountered an error (%d)",
    864                          audio ? "audio" : "video", finalResult);
    865 
    866                     notifyListener(
    867                             MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
    868                 }
    869 
    870                 if ((mAudioEOS || mAudioDecoder == NULL)
    871                         && (mVideoEOS || mVideoDecoder == NULL)) {
    872                     notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
    873                 }
    874             } else if (what == Renderer::kWhatFlushComplete) {
    875                 int32_t audio;
    876                 CHECK(msg->findInt32("audio", &audio));
    877 
    878                 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
    879                 handleFlushComplete(audio, false /* isDecoder */);
    880                 finishFlushIfPossible();
    881             } else if (what == Renderer::kWhatVideoRenderingStart) {
    882                 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
    883             } else if (what == Renderer::kWhatMediaRenderingStart) {
    884                 ALOGV("media rendering started");
    885                 notifyListener(MEDIA_STARTED, 0, 0);
    886             } else if (what == Renderer::kWhatAudioOffloadTearDown) {
    887                 ALOGV("Tear down audio offload, fall back to s/w path if due to error.");
    888                 int64_t positionUs;
    889                 CHECK(msg->findInt64("positionUs", &positionUs));
    890                 int32_t reason;
    891                 CHECK(msg->findInt32("reason", &reason));
    892                 closeAudioSink();
    893                 mAudioDecoder.clear();
    894                 ++mAudioDecoderGeneration;
    895                 mRenderer->flush(
    896                         true /* audio */, false /* notifyComplete */);
    897                 if (mVideoDecoder != NULL) {
    898                     mRenderer->flush(
    899                             false /* audio */, false /* notifyComplete */);
    900                 }
    901 
    902                 performSeek(positionUs, false /* needNotify */);
    903                 if (reason == Renderer::kDueToError) {
    904                     mRenderer->signalDisableOffloadAudio();
    905                     mOffloadAudio = false;
    906                     instantiateDecoder(true /* audio */, &mAudioDecoder);
    907                 }
    908             }
    909             break;
    910         }
    911 
    912         case kWhatMoreDataQueued:
    913         {
    914             break;
    915         }
    916 
    917         case kWhatReset:
    918         {
    919             ALOGV("kWhatReset");
    920 
    921             mDeferredActions.push_back(
    922                     new FlushDecoderAction(
    923                         FLUSH_CMD_SHUTDOWN /* audio */,
    924                         FLUSH_CMD_SHUTDOWN /* video */));
    925 
    926             mDeferredActions.push_back(
    927                     new SimpleAction(&NuPlayer::performReset));
    928 
    929             processDeferredActions();
    930             break;
    931         }
    932 
    933         case kWhatSeek:
    934         {
    935             int64_t seekTimeUs;
    936             int32_t needNotify;
    937             CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
    938             CHECK(msg->findInt32("needNotify", &needNotify));
    939 
    940             ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
    941                     seekTimeUs, needNotify);
    942 
    943             mDeferredActions.push_back(
    944                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
    945                                            FLUSH_CMD_FLUSH /* video */));
    946 
    947             mDeferredActions.push_back(
    948                     new SeekAction(seekTimeUs, needNotify));
    949 
    950             // After a flush without shutdown, decoder is paused.
    951             // Don't resume it until source seek is done, otherwise it could
    952             // start pulling stale data too soon.
    953             mDeferredActions.push_back(
    954                     new ResumeDecoderAction(needNotify));
    955 
    956             processDeferredActions();
    957             break;
    958         }
    959 
    960         case kWhatPause:
    961         {
    962             onPause();
    963             mPausedByClient = true;
    964             break;
    965         }
    966 
    967         case kWhatSourceNotify:
    968         {
    969             onSourceNotify(msg);
    970             break;
    971         }
    972 
    973         case kWhatClosedCaptionNotify:
    974         {
    975             onClosedCaptionNotify(msg);
    976             break;
    977         }
    978 
    979         default:
    980             TRESPASS();
    981             break;
    982     }
    983 }
    984 
    985 void NuPlayer::onResume() {
    986     if (!mPaused) {
    987         return;
    988     }
    989     mPaused = false;
    990     if (mSource != NULL) {
    991         mSource->resume();
    992     } else {
    993         ALOGW("resume called when source is gone or not set");
    994     }
    995     // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
    996     // needed.
    997     if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
    998         instantiateDecoder(true /* audio */, &mAudioDecoder);
    999     }
   1000     if (mRenderer != NULL) {
   1001         mRenderer->resume();
   1002     } else {
   1003         ALOGW("resume called when renderer is gone or not set");
   1004     }
   1005 }
   1006 
   1007 status_t NuPlayer::onInstantiateSecureDecoders() {
   1008     status_t err;
   1009     if (!(mSourceFlags & Source::FLAG_SECURE)) {
   1010         return BAD_TYPE;
   1011     }
   1012 
   1013     if (mRenderer != NULL) {
   1014         ALOGE("renderer should not be set when instantiating secure decoders");
   1015         return UNKNOWN_ERROR;
   1016     }
   1017 
   1018     // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
   1019     // data on instantiation.
   1020     if (mNativeWindow != NULL) {
   1021         err = instantiateDecoder(false, &mVideoDecoder);
   1022         if (err != OK) {
   1023             return err;
   1024         }
   1025     }
   1026 
   1027     if (mAudioSink != NULL) {
   1028         err = instantiateDecoder(true, &mAudioDecoder);
   1029         if (err != OK) {
   1030             return err;
   1031         }
   1032     }
   1033     return OK;
   1034 }
   1035 
   1036 void NuPlayer::onStart() {
   1037     mOffloadAudio = false;
   1038     mAudioEOS = false;
   1039     mVideoEOS = false;
   1040     mStarted = true;
   1041 
   1042     mSource->start();
   1043 
   1044     uint32_t flags = 0;
   1045 
   1046     if (mSource->isRealTime()) {
   1047         flags |= Renderer::FLAG_REAL_TIME;
   1048     }
   1049 
   1050     sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
   1051     audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
   1052     if (mAudioSink != NULL) {
   1053         streamType = mAudioSink->getAudioStreamType();
   1054     }
   1055 
   1056     sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
   1057 
   1058     mOffloadAudio =
   1059         canOffloadStream(audioMeta, (videoFormat != NULL),
   1060                          true /* is_streaming */, streamType);
   1061     if (mOffloadAudio) {
   1062         flags |= Renderer::FLAG_OFFLOAD_AUDIO;
   1063     }
   1064 
   1065     sp<AMessage> notify = new AMessage(kWhatRendererNotify, id());
   1066     ++mRendererGeneration;
   1067     notify->setInt32("generation", mRendererGeneration);
   1068     mRenderer = new Renderer(mAudioSink, notify, flags);
   1069 
   1070     mRendererLooper = new ALooper;
   1071     mRendererLooper->setName("NuPlayerRenderer");
   1072     mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
   1073     mRendererLooper->registerHandler(mRenderer);
   1074 
   1075     sp<MetaData> meta = getFileMeta();
   1076     int32_t rate;
   1077     if (meta != NULL
   1078             && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
   1079         mRenderer->setVideoFrameRate(rate);
   1080     }
   1081 
   1082     if (mVideoDecoder != NULL) {
   1083         mVideoDecoder->setRenderer(mRenderer);
   1084     }
   1085     if (mAudioDecoder != NULL) {
   1086         mAudioDecoder->setRenderer(mRenderer);
   1087     }
   1088 
   1089     postScanSources();
   1090 }
   1091 
   1092 void NuPlayer::onPause() {
   1093     if (mPaused) {
   1094         return;
   1095     }
   1096     mPaused = true;
   1097     if (mSource != NULL) {
   1098         mSource->pause();
   1099     } else {
   1100         ALOGW("pause called when source is gone or not set");
   1101     }
   1102     if (mRenderer != NULL) {
   1103         mRenderer->pause();
   1104     } else {
   1105         ALOGW("pause called when renderer is gone or not set");
   1106     }
   1107 }
   1108 
   1109 bool NuPlayer::audioDecoderStillNeeded() {
   1110     // Audio decoder is no longer needed if it's in shut/shutting down status.
   1111     return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
   1112 }
   1113 
   1114 void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
   1115     // We wait for both the decoder flush and the renderer flush to complete
   1116     // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
   1117 
   1118     mFlushComplete[audio][isDecoder] = true;
   1119     if (!mFlushComplete[audio][!isDecoder]) {
   1120         return;
   1121     }
   1122 
   1123     FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
   1124     switch (*state) {
   1125         case FLUSHING_DECODER:
   1126         {
   1127             *state = FLUSHED;
   1128             break;
   1129         }
   1130 
   1131         case FLUSHING_DECODER_SHUTDOWN:
   1132         {
   1133             *state = SHUTTING_DOWN_DECODER;
   1134 
   1135             ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
   1136             if (!audio) {
   1137                 // Widevine source reads must stop before releasing the video decoder.
   1138                 if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
   1139                     mSource->stop();
   1140                 }
   1141             }
   1142             getDecoder(audio)->initiateShutdown();
   1143             break;
   1144         }
   1145 
   1146         default:
   1147             // decoder flush completes only occur in a flushing state.
   1148             LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
   1149             break;
   1150     }
   1151 }
   1152 
   1153 void NuPlayer::finishFlushIfPossible() {
   1154     if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
   1155             && mFlushingAudio != SHUT_DOWN) {
   1156         return;
   1157     }
   1158 
   1159     if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
   1160             && mFlushingVideo != SHUT_DOWN) {
   1161         return;
   1162     }
   1163 
   1164     ALOGV("both audio and video are flushed now.");
   1165 
   1166     mFlushingAudio = NONE;
   1167     mFlushingVideo = NONE;
   1168 
   1169     clearFlushComplete();
   1170 
   1171     processDeferredActions();
   1172 }
   1173 
   1174 void NuPlayer::postScanSources() {
   1175     if (mScanSourcesPending) {
   1176         return;
   1177     }
   1178 
   1179     sp<AMessage> msg = new AMessage(kWhatScanSources, id());
   1180     msg->setInt32("generation", mScanSourcesGeneration);
   1181     msg->post();
   1182 
   1183     mScanSourcesPending = true;
   1184 }
   1185 
   1186 void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
   1187     // Note: This is called early in NuPlayer to determine whether offloading
   1188     // is possible; otherwise the decoders call the renderer openAudioSink directly.
   1189 
   1190     status_t err = mRenderer->openAudioSink(
   1191             format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
   1192     if (err != OK) {
   1193         // Any failure we turn off mOffloadAudio.
   1194         mOffloadAudio = false;
   1195     } else if (mOffloadAudio) {
   1196         sp<MetaData> audioMeta =
   1197                 mSource->getFormatMeta(true /* audio */);
   1198         sendMetaDataToHal(mAudioSink, audioMeta);
   1199     }
   1200 }
   1201 
   1202 void NuPlayer::closeAudioSink() {
   1203     mRenderer->closeAudioSink();
   1204 }
   1205 
   1206 status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
   1207     if (*decoder != NULL) {
   1208         return OK;
   1209     }
   1210 
   1211     sp<AMessage> format = mSource->getFormat(audio);
   1212 
   1213     if (format == NULL) {
   1214         return -EWOULDBLOCK;
   1215     }
   1216 
   1217     if (!audio) {
   1218         AString mime;
   1219         CHECK(format->findString("mime", &mime));
   1220 
   1221         sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
   1222         if (mCCDecoder == NULL) {
   1223             mCCDecoder = new CCDecoder(ccNotify);
   1224         }
   1225 
   1226         if (mSourceFlags & Source::FLAG_SECURE) {
   1227             format->setInt32("secure", true);
   1228         }
   1229 
   1230         if (mSourceFlags & Source::FLAG_PROTECTED) {
   1231             format->setInt32("protected", true);
   1232         }
   1233     }
   1234 
   1235     if (audio) {
   1236         sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
   1237         ++mAudioDecoderGeneration;
   1238         notify->setInt32("generation", mAudioDecoderGeneration);
   1239 
   1240         if (mOffloadAudio) {
   1241             *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
   1242         } else {
   1243             *decoder = new Decoder(notify, mSource, mRenderer);
   1244         }
   1245     } else {
   1246         sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
   1247         ++mVideoDecoderGeneration;
   1248         notify->setInt32("generation", mVideoDecoderGeneration);
   1249 
   1250         *decoder = new Decoder(
   1251                 notify, mSource, mRenderer, mNativeWindow, mCCDecoder);
   1252 
   1253         // enable FRC if high-quality AV sync is requested, even if not
   1254         // queuing to native window, as this will even improve textureview
   1255         // playback.
   1256         {
   1257             char value[PROPERTY_VALUE_MAX];
   1258             if (property_get("persist.sys.media.avsync", value, NULL) &&
   1259                     (!strcmp("1", value) || !strcasecmp("true", value))) {
   1260                 format->setInt32("auto-frc", 1);
   1261             }
   1262         }
   1263     }
   1264     (*decoder)->init();
   1265     (*decoder)->configure(format);
   1266 
   1267     // allocate buffers to decrypt widevine source buffers
   1268     if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
   1269         Vector<sp<ABuffer> > inputBufs;
   1270         CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
   1271 
   1272         Vector<MediaBuffer *> mediaBufs;
   1273         for (size_t i = 0; i < inputBufs.size(); i++) {
   1274             const sp<ABuffer> &buffer = inputBufs[i];
   1275             MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
   1276             mediaBufs.push(mbuf);
   1277         }
   1278 
   1279         status_t err = mSource->setBuffers(audio, mediaBufs);
   1280         if (err != OK) {
   1281             for (size_t i = 0; i < mediaBufs.size(); ++i) {
   1282                 mediaBufs[i]->release();
   1283             }
   1284             mediaBufs.clear();
   1285             ALOGE("Secure source didn't support secure mediaBufs.");
   1286             return err;
   1287         }
   1288     }
   1289     return OK;
   1290 }
   1291 
   1292 void NuPlayer::updateVideoSize(
   1293         const sp<AMessage> &inputFormat,
   1294         const sp<AMessage> &outputFormat) {
   1295     if (inputFormat == NULL) {
   1296         ALOGW("Unknown video size, reporting 0x0!");
   1297         notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
   1298         return;
   1299     }
   1300 
   1301     int32_t displayWidth, displayHeight;
   1302     int32_t cropLeft, cropTop, cropRight, cropBottom;
   1303 
   1304     if (outputFormat != NULL) {
   1305         int32_t width, height;
   1306         CHECK(outputFormat->findInt32("width", &width));
   1307         CHECK(outputFormat->findInt32("height", &height));
   1308 
   1309         int32_t cropLeft, cropTop, cropRight, cropBottom;
   1310         CHECK(outputFormat->findRect(
   1311                     "crop",
   1312                     &cropLeft, &cropTop, &cropRight, &cropBottom));
   1313 
   1314         displayWidth = cropRight - cropLeft + 1;
   1315         displayHeight = cropBottom - cropTop + 1;
   1316 
   1317         ALOGV("Video output format changed to %d x %d "
   1318              "(crop: %d x %d @ (%d, %d))",
   1319              width, height,
   1320              displayWidth,
   1321              displayHeight,
   1322              cropLeft, cropTop);
   1323     } else {
   1324         CHECK(inputFormat->findInt32("width", &displayWidth));
   1325         CHECK(inputFormat->findInt32("height", &displayHeight));
   1326 
   1327         ALOGV("Video input format %d x %d", displayWidth, displayHeight);
   1328     }
   1329 
   1330     // Take into account sample aspect ratio if necessary:
   1331     int32_t sarWidth, sarHeight;
   1332     if (inputFormat->findInt32("sar-width", &sarWidth)
   1333             && inputFormat->findInt32("sar-height", &sarHeight)) {
   1334         ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
   1335 
   1336         displayWidth = (displayWidth * sarWidth) / sarHeight;
   1337 
   1338         ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
   1339     }
   1340 
   1341     int32_t rotationDegrees;
   1342     if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
   1343         rotationDegrees = 0;
   1344     }
   1345 
   1346     if (rotationDegrees == 90 || rotationDegrees == 270) {
   1347         int32_t tmp = displayWidth;
   1348         displayWidth = displayHeight;
   1349         displayHeight = tmp;
   1350     }
   1351 
   1352     notifyListener(
   1353             MEDIA_SET_VIDEO_SIZE,
   1354             displayWidth,
   1355             displayHeight);
   1356 }
   1357 
   1358 void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
   1359     if (mDriver == NULL) {
   1360         return;
   1361     }
   1362 
   1363     sp<NuPlayerDriver> driver = mDriver.promote();
   1364 
   1365     if (driver == NULL) {
   1366         return;
   1367     }
   1368 
   1369     driver->notifyListener(msg, ext1, ext2, in);
   1370 }
   1371 
   1372 void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
   1373     ALOGV("[%s] flushDecoder needShutdown=%d",
   1374           audio ? "audio" : "video", needShutdown);
   1375 
   1376     const sp<DecoderBase> &decoder = getDecoder(audio);
   1377     if (decoder == NULL) {
   1378         ALOGI("flushDecoder %s without decoder present",
   1379              audio ? "audio" : "video");
   1380         return;
   1381     }
   1382 
   1383     // Make sure we don't continue to scan sources until we finish flushing.
   1384     ++mScanSourcesGeneration;
   1385     mScanSourcesPending = false;
   1386 
   1387     decoder->signalFlush();
   1388 
   1389     FlushStatus newStatus =
   1390         needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
   1391 
   1392     mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
   1393     mFlushComplete[audio][true /* isDecoder */] = false;
   1394     if (audio) {
   1395         ALOGE_IF(mFlushingAudio != NONE,
   1396                 "audio flushDecoder() is called in state %d", mFlushingAudio);
   1397         mFlushingAudio = newStatus;
   1398     } else {
   1399         ALOGE_IF(mFlushingVideo != NONE,
   1400                 "video flushDecoder() is called in state %d", mFlushingVideo);
   1401         mFlushingVideo = newStatus;
   1402     }
   1403 }
   1404 
   1405 void NuPlayer::queueDecoderShutdown(
   1406         bool audio, bool video, const sp<AMessage> &reply) {
   1407     ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
   1408 
   1409     mDeferredActions.push_back(
   1410             new FlushDecoderAction(
   1411                 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
   1412                 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
   1413 
   1414     mDeferredActions.push_back(
   1415             new SimpleAction(&NuPlayer::performScanSources));
   1416 
   1417     mDeferredActions.push_back(new PostMessageAction(reply));
   1418 
   1419     processDeferredActions();
   1420 }
   1421 
   1422 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
   1423     mVideoScalingMode = mode;
   1424     if (mNativeWindow != NULL) {
   1425         status_t ret = native_window_set_scaling_mode(
   1426                 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
   1427         if (ret != OK) {
   1428             ALOGE("Failed to set scaling mode (%d): %s",
   1429                 -ret, strerror(-ret));
   1430             return ret;
   1431         }
   1432     }
   1433     return OK;
   1434 }
   1435 
   1436 status_t NuPlayer::getTrackInfo(Parcel* reply) const {
   1437     sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
   1438     msg->setPointer("reply", reply);
   1439 
   1440     sp<AMessage> response;
   1441     status_t err = msg->postAndAwaitResponse(&response);
   1442     return err;
   1443 }
   1444 
   1445 status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
   1446     sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
   1447     msg->setPointer("reply", reply);
   1448     msg->setInt32("type", type);
   1449 
   1450     sp<AMessage> response;
   1451     status_t err = msg->postAndAwaitResponse(&response);
   1452     if (err == OK && response != NULL) {
   1453         CHECK(response->findInt32("err", &err));
   1454     }
   1455     return err;
   1456 }
   1457 
   1458 status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
   1459     sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
   1460     msg->setSize("trackIndex", trackIndex);
   1461     msg->setInt32("select", select);
   1462     msg->setInt64("timeUs", timeUs);
   1463 
   1464     sp<AMessage> response;
   1465     status_t err = msg->postAndAwaitResponse(&response);
   1466 
   1467     if (err != OK) {
   1468         return err;
   1469     }
   1470 
   1471     if (!response->findInt32("err", &err)) {
   1472         err = OK;
   1473     }
   1474 
   1475     return err;
   1476 }
   1477 
   1478 status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
   1479     sp<Renderer> renderer = mRenderer;
   1480     if (renderer == NULL) {
   1481         return NO_INIT;
   1482     }
   1483 
   1484     return renderer->getCurrentPosition(mediaUs);
   1485 }
   1486 
   1487 void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
   1488     sp<DecoderBase> decoder = getDecoder(false /* audio */);
   1489     if (decoder != NULL) {
   1490         decoder->getStats(numFramesTotal, numFramesDropped);
   1491     } else {
   1492         *numFramesTotal = 0;
   1493         *numFramesDropped = 0;
   1494     }
   1495 }
   1496 
   1497 sp<MetaData> NuPlayer::getFileMeta() {
   1498     return mSource->getFileFormatMeta();
   1499 }
   1500 
   1501 void NuPlayer::schedulePollDuration() {
   1502     sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
   1503     msg->setInt32("generation", mPollDurationGeneration);
   1504     msg->post();
   1505 }
   1506 
   1507 void NuPlayer::cancelPollDuration() {
   1508     ++mPollDurationGeneration;
   1509 }
   1510 
   1511 void NuPlayer::processDeferredActions() {
   1512     while (!mDeferredActions.empty()) {
   1513         // We won't execute any deferred actions until we're no longer in
   1514         // an intermediate state, i.e. one more more decoders are currently
   1515         // flushing or shutting down.
   1516 
   1517         if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
   1518             // We're currently flushing, postpone the reset until that's
   1519             // completed.
   1520 
   1521             ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
   1522                   mFlushingAudio, mFlushingVideo);
   1523 
   1524             break;
   1525         }
   1526 
   1527         sp<Action> action = *mDeferredActions.begin();
   1528         mDeferredActions.erase(mDeferredActions.begin());
   1529 
   1530         action->execute(this);
   1531     }
   1532 }
   1533 
   1534 void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
   1535     ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)",
   1536           seekTimeUs,
   1537           seekTimeUs / 1E6,
   1538           needNotify);
   1539 
   1540     if (mSource == NULL) {
   1541         // This happens when reset occurs right before the loop mode
   1542         // asynchronously seeks to the start of the stream.
   1543         LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
   1544                 "mSource is NULL and decoders not NULL audio(%p) video(%p)",
   1545                 mAudioDecoder.get(), mVideoDecoder.get());
   1546         return;
   1547     }
   1548     mSource->seekTo(seekTimeUs);
   1549     ++mTimedTextGeneration;
   1550 
   1551     // everything's flushed, continue playback.
   1552 }
   1553 
   1554 void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
   1555     ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
   1556 
   1557     if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
   1558             && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
   1559         return;
   1560     }
   1561 
   1562     if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
   1563         flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
   1564     }
   1565 
   1566     if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
   1567         flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
   1568     }
   1569 }
   1570 
   1571 void NuPlayer::performReset() {
   1572     ALOGV("performReset");
   1573 
   1574     CHECK(mAudioDecoder == NULL);
   1575     CHECK(mVideoDecoder == NULL);
   1576 
   1577     cancelPollDuration();
   1578 
   1579     ++mScanSourcesGeneration;
   1580     mScanSourcesPending = false;
   1581 
   1582     if (mRendererLooper != NULL) {
   1583         if (mRenderer != NULL) {
   1584             mRendererLooper->unregisterHandler(mRenderer->id());
   1585         }
   1586         mRendererLooper->stop();
   1587         mRendererLooper.clear();
   1588     }
   1589     mRenderer.clear();
   1590     ++mRendererGeneration;
   1591 
   1592     if (mSource != NULL) {
   1593         mSource->stop();
   1594 
   1595         mSource.clear();
   1596     }
   1597 
   1598     if (mDriver != NULL) {
   1599         sp<NuPlayerDriver> driver = mDriver.promote();
   1600         if (driver != NULL) {
   1601             driver->notifyResetComplete();
   1602         }
   1603     }
   1604 
   1605     mStarted = false;
   1606 }
   1607 
   1608 void NuPlayer::performScanSources() {
   1609     ALOGV("performScanSources");
   1610 
   1611     if (!mStarted) {
   1612         return;
   1613     }
   1614 
   1615     if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
   1616         postScanSources();
   1617     }
   1618 }
   1619 
   1620 void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
   1621     ALOGV("performSetSurface");
   1622 
   1623     mNativeWindow = wrapper;
   1624 
   1625     // XXX - ignore error from setVideoScalingMode for now
   1626     setVideoScalingMode(mVideoScalingMode);
   1627 
   1628     if (mDriver != NULL) {
   1629         sp<NuPlayerDriver> driver = mDriver.promote();
   1630         if (driver != NULL) {
   1631             driver->notifySetSurfaceComplete();
   1632         }
   1633     }
   1634 }
   1635 
   1636 void NuPlayer::performResumeDecoders(bool needNotify) {
   1637     if (needNotify) {
   1638         mResumePending = true;
   1639         if (mVideoDecoder == NULL) {
   1640             // if audio-only, we can notify seek complete now,
   1641             // as the resume operation will be relatively fast.
   1642             finishResume();
   1643         }
   1644     }
   1645 
   1646     if (mVideoDecoder != NULL) {
   1647         // When there is continuous seek, MediaPlayer will cache the seek
   1648         // position, and send down new seek request when previous seek is
   1649         // complete. Let's wait for at least one video output frame before
   1650         // notifying seek complete, so that the video thumbnail gets updated
   1651         // when seekbar is dragged.
   1652         mVideoDecoder->signalResume(needNotify);
   1653     }
   1654 
   1655     if (mAudioDecoder != NULL) {
   1656         mAudioDecoder->signalResume(false /* needNotify */);
   1657     }
   1658 }
   1659 
   1660 void NuPlayer::finishResume() {
   1661     if (mResumePending) {
   1662         mResumePending = false;
   1663         if (mDriver != NULL) {
   1664             sp<NuPlayerDriver> driver = mDriver.promote();
   1665             if (driver != NULL) {
   1666                 driver->notifySeekComplete();
   1667             }
   1668         }
   1669     }
   1670 }
   1671 
   1672 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
   1673     int32_t what;
   1674     CHECK(msg->findInt32("what", &what));
   1675 
   1676     switch (what) {
   1677         case Source::kWhatInstantiateSecureDecoders:
   1678         {
   1679             if (mSource == NULL) {
   1680                 // This is a stale notification from a source that was
   1681                 // asynchronously preparing when the client called reset().
   1682                 // We handled the reset, the source is gone.
   1683                 break;
   1684             }
   1685 
   1686             sp<AMessage> reply;
   1687             CHECK(msg->findMessage("reply", &reply));
   1688             status_t err = onInstantiateSecureDecoders();
   1689             reply->setInt32("err", err);
   1690             reply->post();
   1691             break;
   1692         }
   1693 
   1694         case Source::kWhatPrepared:
   1695         {
   1696             if (mSource == NULL) {
   1697                 // This is a stale notification from a source that was
   1698                 // asynchronously preparing when the client called reset().
   1699                 // We handled the reset, the source is gone.
   1700                 break;
   1701             }
   1702 
   1703             int32_t err;
   1704             CHECK(msg->findInt32("err", &err));
   1705 
   1706             if (err != OK) {
   1707                 // shut down potential secure codecs in case client never calls reset
   1708                 mDeferredActions.push_back(
   1709                         new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
   1710                                                FLUSH_CMD_SHUTDOWN /* video */));
   1711                 processDeferredActions();
   1712             }
   1713 
   1714             sp<NuPlayerDriver> driver = mDriver.promote();
   1715             if (driver != NULL) {
   1716                 // notify duration first, so that it's definitely set when
   1717                 // the app received the "prepare complete" callback.
   1718                 int64_t durationUs;
   1719                 if (mSource->getDuration(&durationUs) == OK) {
   1720                     driver->notifyDuration(durationUs);
   1721                 }
   1722                 driver->notifyPrepareCompleted(err);
   1723             }
   1724 
   1725             break;
   1726         }
   1727 
   1728         case Source::kWhatFlagsChanged:
   1729         {
   1730             uint32_t flags;
   1731             CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1732 
   1733             sp<NuPlayerDriver> driver = mDriver.promote();
   1734             if (driver != NULL) {
   1735                 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
   1736                     driver->notifyListener(
   1737                             MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
   1738                 }
   1739                 driver->notifyFlagsChanged(flags);
   1740             }
   1741 
   1742             if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
   1743                     && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
   1744                 cancelPollDuration();
   1745             } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
   1746                     && (flags & Source::FLAG_DYNAMIC_DURATION)
   1747                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
   1748                 schedulePollDuration();
   1749             }
   1750 
   1751             mSourceFlags = flags;
   1752             break;
   1753         }
   1754 
   1755         case Source::kWhatVideoSizeChanged:
   1756         {
   1757             sp<AMessage> format;
   1758             CHECK(msg->findMessage("format", &format));
   1759 
   1760             updateVideoSize(format);
   1761             break;
   1762         }
   1763 
   1764         case Source::kWhatBufferingUpdate:
   1765         {
   1766             int32_t percentage;
   1767             CHECK(msg->findInt32("percentage", &percentage));
   1768 
   1769             notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
   1770             break;
   1771         }
   1772 
   1773         case Source::kWhatPauseOnBufferingStart:
   1774         {
   1775             // ignore if not playing
   1776             if (mStarted && !mPausedByClient) {
   1777                 ALOGI("buffer low, pausing...");
   1778 
   1779                 onPause();
   1780             }
   1781             // fall-thru
   1782         }
   1783 
   1784         case Source::kWhatBufferingStart:
   1785         {
   1786             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
   1787             break;
   1788         }
   1789 
   1790         case Source::kWhatResumeOnBufferingEnd:
   1791         {
   1792             // ignore if not playing
   1793             if (mStarted && !mPausedByClient) {
   1794                 ALOGI("buffer ready, resuming...");
   1795 
   1796                 onResume();
   1797             }
   1798             // fall-thru
   1799         }
   1800 
   1801         case Source::kWhatBufferingEnd:
   1802         {
   1803             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
   1804             break;
   1805         }
   1806 
   1807         case Source::kWhatCacheStats:
   1808         {
   1809             int32_t kbps;
   1810             CHECK(msg->findInt32("bandwidth", &kbps));
   1811 
   1812             notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
   1813             break;
   1814         }
   1815 
   1816         case Source::kWhatSubtitleData:
   1817         {
   1818             sp<ABuffer> buffer;
   1819             CHECK(msg->findBuffer("buffer", &buffer));
   1820 
   1821             sendSubtitleData(buffer, 0 /* baseIndex */);
   1822             break;
   1823         }
   1824 
   1825         case Source::kWhatTimedTextData:
   1826         {
   1827             int32_t generation;
   1828             if (msg->findInt32("generation", &generation)
   1829                     && generation != mTimedTextGeneration) {
   1830                 break;
   1831             }
   1832 
   1833             sp<ABuffer> buffer;
   1834             CHECK(msg->findBuffer("buffer", &buffer));
   1835 
   1836             sp<NuPlayerDriver> driver = mDriver.promote();
   1837             if (driver == NULL) {
   1838                 break;
   1839             }
   1840 
   1841             int posMs;
   1842             int64_t timeUs, posUs;
   1843             driver->getCurrentPosition(&posMs);
   1844             posUs = posMs * 1000;
   1845             CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   1846 
   1847             if (posUs < timeUs) {
   1848                 if (!msg->findInt32("generation", &generation)) {
   1849                     msg->setInt32("generation", mTimedTextGeneration);
   1850                 }
   1851                 msg->post(timeUs - posUs);
   1852             } else {
   1853                 sendTimedTextData(buffer);
   1854             }
   1855             break;
   1856         }
   1857 
   1858         case Source::kWhatQueueDecoderShutdown:
   1859         {
   1860             int32_t audio, video;
   1861             CHECK(msg->findInt32("audio", &audio));
   1862             CHECK(msg->findInt32("video", &video));
   1863 
   1864             sp<AMessage> reply;
   1865             CHECK(msg->findMessage("reply", &reply));
   1866 
   1867             queueDecoderShutdown(audio, video, reply);
   1868             break;
   1869         }
   1870 
   1871         case Source::kWhatDrmNoLicense:
   1872         {
   1873             notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
   1874             break;
   1875         }
   1876 
   1877         default:
   1878             TRESPASS();
   1879     }
   1880 }
   1881 
   1882 void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
   1883     int32_t what;
   1884     CHECK(msg->findInt32("what", &what));
   1885 
   1886     switch (what) {
   1887         case NuPlayer::CCDecoder::kWhatClosedCaptionData:
   1888         {
   1889             sp<ABuffer> buffer;
   1890             CHECK(msg->findBuffer("buffer", &buffer));
   1891 
   1892             size_t inbandTracks = 0;
   1893             if (mSource != NULL) {
   1894                 inbandTracks = mSource->getTrackCount();
   1895             }
   1896 
   1897             sendSubtitleData(buffer, inbandTracks);
   1898             break;
   1899         }
   1900 
   1901         case NuPlayer::CCDecoder::kWhatTrackAdded:
   1902         {
   1903             notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
   1904 
   1905             break;
   1906         }
   1907 
   1908         default:
   1909             TRESPASS();
   1910     }
   1911 
   1912 
   1913 }
   1914 
   1915 void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
   1916     int32_t trackIndex;
   1917     int64_t timeUs, durationUs;
   1918     CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
   1919     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   1920     CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
   1921 
   1922     Parcel in;
   1923     in.writeInt32(trackIndex + baseIndex);
   1924     in.writeInt64(timeUs);
   1925     in.writeInt64(durationUs);
   1926     in.writeInt32(buffer->size());
   1927     in.writeInt32(buffer->size());
   1928     in.write(buffer->data(), buffer->size());
   1929 
   1930     notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
   1931 }
   1932 
   1933 void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
   1934     const void *data;
   1935     size_t size = 0;
   1936     int64_t timeUs;
   1937     int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
   1938 
   1939     AString mime;
   1940     CHECK(buffer->meta()->findString("mime", &mime));
   1941     CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
   1942 
   1943     data = buffer->data();
   1944     size = buffer->size();
   1945 
   1946     Parcel parcel;
   1947     if (size > 0) {
   1948         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
   1949         flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
   1950         TextDescriptions::getParcelOfDescriptions(
   1951                 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
   1952     }
   1953 
   1954     if ((parcel.dataSize() > 0)) {
   1955         notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
   1956     } else {  // send an empty timed text
   1957         notifyListener(MEDIA_TIMED_TEXT, 0, 0);
   1958     }
   1959 }
   1960 ////////////////////////////////////////////////////////////////////////////////
   1961 
   1962 sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
   1963     sp<MetaData> meta = getFormatMeta(audio);
   1964 
   1965     if (meta == NULL) {
   1966         return NULL;
   1967     }
   1968 
   1969     sp<AMessage> msg = new AMessage;
   1970 
   1971     if(convertMetaDataToMessage(meta, &msg) == OK) {
   1972         return msg;
   1973     }
   1974     return NULL;
   1975 }
   1976 
   1977 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
   1978     sp<AMessage> notify = dupNotify();
   1979     notify->setInt32("what", kWhatFlagsChanged);
   1980     notify->setInt32("flags", flags);
   1981     notify->post();
   1982 }
   1983 
   1984 void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
   1985     sp<AMessage> notify = dupNotify();
   1986     notify->setInt32("what", kWhatVideoSizeChanged);
   1987     notify->setMessage("format", format);
   1988     notify->post();
   1989 }
   1990 
   1991 void NuPlayer::Source::notifyPrepared(status_t err) {
   1992     sp<AMessage> notify = dupNotify();
   1993     notify->setInt32("what", kWhatPrepared);
   1994     notify->setInt32("err", err);
   1995     notify->post();
   1996 }
   1997 
   1998 void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
   1999     sp<AMessage> notify = dupNotify();
   2000     notify->setInt32("what", kWhatInstantiateSecureDecoders);
   2001     notify->setMessage("reply", reply);
   2002     notify->post();
   2003 }
   2004 
   2005 void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
   2006     TRESPASS();
   2007 }
   2008 
   2009 }  // namespace android
   2010