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 "NuPlayerDecoder.h"
     25 #include "NuPlayerDriver.h"
     26 #include "NuPlayerRenderer.h"
     27 #include "NuPlayerSource.h"
     28 #include "RTSPSource.h"
     29 #include "StreamingSource.h"
     30 #include "GenericSource.h"
     31 #include "mp4/MP4Source.h"
     32 
     33 #include "ATSParser.h"
     34 
     35 #include <cutils/properties.h> // for property_get
     36 #include <media/stagefright/foundation/hexdump.h>
     37 #include <media/stagefright/foundation/ABuffer.h>
     38 #include <media/stagefright/foundation/ADebug.h>
     39 #include <media/stagefright/foundation/AMessage.h>
     40 #include <media/stagefright/ACodec.h>
     41 #include <media/stagefright/MediaDefs.h>
     42 #include <media/stagefright/MediaErrors.h>
     43 #include <media/stagefright/MetaData.h>
     44 #include <gui/IGraphicBufferProducer.h>
     45 
     46 #include "avc_utils.h"
     47 
     48 #include "ESDS.h"
     49 #include <media/stagefright/Utils.h>
     50 
     51 namespace android {
     52 
     53 struct NuPlayer::Action : public RefBase {
     54     Action() {}
     55 
     56     virtual void execute(NuPlayer *player) = 0;
     57 
     58 private:
     59     DISALLOW_EVIL_CONSTRUCTORS(Action);
     60 };
     61 
     62 struct NuPlayer::SeekAction : public Action {
     63     SeekAction(int64_t seekTimeUs)
     64         : mSeekTimeUs(seekTimeUs) {
     65     }
     66 
     67     virtual void execute(NuPlayer *player) {
     68         player->performSeek(mSeekTimeUs);
     69     }
     70 
     71 private:
     72     int64_t mSeekTimeUs;
     73 
     74     DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
     75 };
     76 
     77 struct NuPlayer::SetSurfaceAction : public Action {
     78     SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
     79         : mWrapper(wrapper) {
     80     }
     81 
     82     virtual void execute(NuPlayer *player) {
     83         player->performSetSurface(mWrapper);
     84     }
     85 
     86 private:
     87     sp<NativeWindowWrapper> mWrapper;
     88 
     89     DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
     90 };
     91 
     92 // Use this if there's no state necessary to save in order to execute
     93 // the action.
     94 struct NuPlayer::SimpleAction : public Action {
     95     typedef void (NuPlayer::*ActionFunc)();
     96 
     97     SimpleAction(ActionFunc func)
     98         : mFunc(func) {
     99     }
    100 
    101     virtual void execute(NuPlayer *player) {
    102         (player->*mFunc)();
    103     }
    104 
    105 private:
    106     ActionFunc mFunc;
    107 
    108     DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
    109 };
    110 
    111 ////////////////////////////////////////////////////////////////////////////////
    112 
    113 NuPlayer::NuPlayer()
    114     : mUIDValid(false),
    115       mSourceFlags(0),
    116       mVideoIsAVC(false),
    117       mAudioEOS(false),
    118       mVideoEOS(false),
    119       mScanSourcesPending(false),
    120       mScanSourcesGeneration(0),
    121       mPollDurationGeneration(0),
    122       mTimeDiscontinuityPending(false),
    123       mFlushingAudio(NONE),
    124       mFlushingVideo(NONE),
    125       mSkipRenderingAudioUntilMediaTimeUs(-1ll),
    126       mSkipRenderingVideoUntilMediaTimeUs(-1ll),
    127       mVideoLateByUs(0ll),
    128       mNumFramesTotal(0ll),
    129       mNumFramesDropped(0ll),
    130       mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
    131       mStarted(false) {
    132 }
    133 
    134 NuPlayer::~NuPlayer() {
    135 }
    136 
    137 void NuPlayer::setUID(uid_t uid) {
    138     mUIDValid = true;
    139     mUID = uid;
    140 }
    141 
    142 void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
    143     mDriver = driver;
    144 }
    145 
    146 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
    147     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    148 
    149     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    150 
    151     char prop[PROPERTY_VALUE_MAX];
    152     if (property_get("media.stagefright.use-mp4source", prop, NULL)
    153             && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
    154         msg->setObject("source", new MP4Source(notify, source));
    155     } else {
    156         msg->setObject("source", new StreamingSource(notify, source));
    157     }
    158 
    159     msg->post();
    160 }
    161 
    162 static bool IsHTTPLiveURL(const char *url) {
    163     if (!strncasecmp("http://", url, 7)
    164             || !strncasecmp("https://", url, 8)
    165             || !strncasecmp("file://", url, 7)) {
    166         size_t len = strlen(url);
    167         if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
    168             return true;
    169         }
    170 
    171         if (strstr(url,"m3u8")) {
    172             return true;
    173         }
    174     }
    175 
    176     return false;
    177 }
    178 
    179 void NuPlayer::setDataSourceAsync(
    180         const char *url, const KeyedVector<String8, String8> *headers) {
    181     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    182     size_t len = strlen(url);
    183 
    184     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    185 
    186     sp<Source> source;
    187     if (IsHTTPLiveURL(url)) {
    188         source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
    189     } else if (!strncasecmp(url, "rtsp://", 7)) {
    190         source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
    191     } else if ((!strncasecmp(url, "http://", 7)
    192                 || !strncasecmp(url, "https://", 8))
    193                     && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
    194                     || strstr(url, ".sdp?"))) {
    195         source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true);
    196     } else {
    197         source = new GenericSource(notify, url, headers, mUIDValid, mUID);
    198     }
    199 
    200     msg->setObject("source", source);
    201     msg->post();
    202 }
    203 
    204 void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
    205     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    206 
    207     sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
    208 
    209     sp<Source> source = new GenericSource(notify, fd, offset, length);
    210     msg->setObject("source", source);
    211     msg->post();
    212 }
    213 
    214 void NuPlayer::prepareAsync() {
    215     (new AMessage(kWhatPrepare, id()))->post();
    216 }
    217 
    218 void NuPlayer::setVideoSurfaceTextureAsync(
    219         const sp<IGraphicBufferProducer> &bufferProducer) {
    220     sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
    221 
    222     if (bufferProducer == NULL) {
    223         msg->setObject("native-window", NULL);
    224     } else {
    225         msg->setObject(
    226                 "native-window",
    227                 new NativeWindowWrapper(
    228                     new Surface(bufferProducer)));
    229     }
    230 
    231     msg->post();
    232 }
    233 
    234 void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
    235     sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
    236     msg->setObject("sink", sink);
    237     msg->post();
    238 }
    239 
    240 void NuPlayer::start() {
    241     (new AMessage(kWhatStart, id()))->post();
    242 }
    243 
    244 void NuPlayer::pause() {
    245     (new AMessage(kWhatPause, id()))->post();
    246 }
    247 
    248 void NuPlayer::resume() {
    249     (new AMessage(kWhatResume, id()))->post();
    250 }
    251 
    252 void NuPlayer::resetAsync() {
    253     (new AMessage(kWhatReset, id()))->post();
    254 }
    255 
    256 void NuPlayer::seekToAsync(int64_t seekTimeUs) {
    257     sp<AMessage> msg = new AMessage(kWhatSeek, id());
    258     msg->setInt64("seekTimeUs", seekTimeUs);
    259     msg->post();
    260 }
    261 
    262 // static
    263 bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
    264     switch (state) {
    265         case FLUSHING_DECODER:
    266             if (needShutdown != NULL) {
    267                 *needShutdown = false;
    268             }
    269             return true;
    270 
    271         case FLUSHING_DECODER_SHUTDOWN:
    272             if (needShutdown != NULL) {
    273                 *needShutdown = true;
    274             }
    275             return true;
    276 
    277         default:
    278             return false;
    279     }
    280 }
    281 
    282 void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
    283     switch (msg->what()) {
    284         case kWhatSetDataSource:
    285         {
    286             ALOGV("kWhatSetDataSource");
    287 
    288             CHECK(mSource == NULL);
    289 
    290             sp<RefBase> obj;
    291             CHECK(msg->findObject("source", &obj));
    292 
    293             mSource = static_cast<Source *>(obj.get());
    294 
    295             looper()->registerHandler(mSource);
    296 
    297             CHECK(mDriver != NULL);
    298             sp<NuPlayerDriver> driver = mDriver.promote();
    299             if (driver != NULL) {
    300                 driver->notifySetDataSourceCompleted(OK);
    301             }
    302             break;
    303         }
    304 
    305         case kWhatPrepare:
    306         {
    307             mSource->prepareAsync();
    308             break;
    309         }
    310 
    311         case kWhatPollDuration:
    312         {
    313             int32_t generation;
    314             CHECK(msg->findInt32("generation", &generation));
    315 
    316             if (generation != mPollDurationGeneration) {
    317                 // stale
    318                 break;
    319             }
    320 
    321             int64_t durationUs;
    322             if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
    323                 sp<NuPlayerDriver> driver = mDriver.promote();
    324                 if (driver != NULL) {
    325                     driver->notifyDuration(durationUs);
    326                 }
    327             }
    328 
    329             msg->post(1000000ll);  // poll again in a second.
    330             break;
    331         }
    332 
    333         case kWhatSetVideoNativeWindow:
    334         {
    335             ALOGV("kWhatSetVideoNativeWindow");
    336 
    337             mDeferredActions.push_back(
    338                     new SimpleAction(&NuPlayer::performDecoderShutdown));
    339 
    340             sp<RefBase> obj;
    341             CHECK(msg->findObject("native-window", &obj));
    342 
    343             mDeferredActions.push_back(
    344                     new SetSurfaceAction(
    345                         static_cast<NativeWindowWrapper *>(obj.get())));
    346 
    347             if (obj != NULL) {
    348                 // If there is a new surface texture, instantiate decoders
    349                 // again if possible.
    350                 mDeferredActions.push_back(
    351                         new SimpleAction(&NuPlayer::performScanSources));
    352             }
    353 
    354             processDeferredActions();
    355             break;
    356         }
    357 
    358         case kWhatSetAudioSink:
    359         {
    360             ALOGV("kWhatSetAudioSink");
    361 
    362             sp<RefBase> obj;
    363             CHECK(msg->findObject("sink", &obj));
    364 
    365             mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
    366             break;
    367         }
    368 
    369         case kWhatStart:
    370         {
    371             ALOGV("kWhatStart");
    372 
    373             mVideoIsAVC = false;
    374             mAudioEOS = false;
    375             mVideoEOS = false;
    376             mSkipRenderingAudioUntilMediaTimeUs = -1;
    377             mSkipRenderingVideoUntilMediaTimeUs = -1;
    378             mVideoLateByUs = 0;
    379             mNumFramesTotal = 0;
    380             mNumFramesDropped = 0;
    381             mStarted = true;
    382 
    383             mSource->start();
    384 
    385             uint32_t flags = 0;
    386 
    387             if (mSource->isRealTime()) {
    388                 flags |= Renderer::FLAG_REAL_TIME;
    389             }
    390 
    391             mRenderer = new Renderer(
    392                     mAudioSink,
    393                     new AMessage(kWhatRendererNotify, id()),
    394                     flags);
    395 
    396             looper()->registerHandler(mRenderer);
    397 
    398             postScanSources();
    399             break;
    400         }
    401 
    402         case kWhatScanSources:
    403         {
    404             int32_t generation;
    405             CHECK(msg->findInt32("generation", &generation));
    406             if (generation != mScanSourcesGeneration) {
    407                 // Drop obsolete msg.
    408                 break;
    409             }
    410 
    411             mScanSourcesPending = false;
    412 
    413             ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
    414                  mAudioDecoder != NULL, mVideoDecoder != NULL);
    415 
    416             bool mHadAnySourcesBefore =
    417                 (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
    418 
    419             if (mNativeWindow != NULL) {
    420                 instantiateDecoder(false, &mVideoDecoder);
    421             }
    422 
    423             if (mAudioSink != NULL) {
    424                 instantiateDecoder(true, &mAudioDecoder);
    425             }
    426 
    427             if (!mHadAnySourcesBefore
    428                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
    429                 // This is the first time we've found anything playable.
    430 
    431                 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
    432                     schedulePollDuration();
    433                 }
    434             }
    435 
    436             status_t err;
    437             if ((err = mSource->feedMoreTSData()) != OK) {
    438                 if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
    439                     // We're not currently decoding anything (no audio or
    440                     // video tracks found) and we just ran out of input data.
    441 
    442                     if (err == ERROR_END_OF_STREAM) {
    443                         notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
    444                     } else {
    445                         notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
    446                     }
    447                 }
    448                 break;
    449             }
    450 
    451             if ((mAudioDecoder == NULL && mAudioSink != NULL)
    452                     || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
    453                 msg->post(100000ll);
    454                 mScanSourcesPending = true;
    455             }
    456             break;
    457         }
    458 
    459         case kWhatVideoNotify:
    460         case kWhatAudioNotify:
    461         {
    462             bool audio = msg->what() == kWhatAudioNotify;
    463 
    464             sp<AMessage> codecRequest;
    465             CHECK(msg->findMessage("codec-request", &codecRequest));
    466 
    467             int32_t what;
    468             CHECK(codecRequest->findInt32("what", &what));
    469 
    470             if (what == ACodec::kWhatFillThisBuffer) {
    471                 status_t err = feedDecoderInputData(
    472                         audio, codecRequest);
    473 
    474                 if (err == -EWOULDBLOCK) {
    475                     if (mSource->feedMoreTSData() == OK) {
    476                         msg->post(10000ll);
    477                     }
    478                 }
    479             } else if (what == ACodec::kWhatEOS) {
    480                 int32_t err;
    481                 CHECK(codecRequest->findInt32("err", &err));
    482 
    483                 if (err == ERROR_END_OF_STREAM) {
    484                     ALOGV("got %s decoder EOS", audio ? "audio" : "video");
    485                 } else {
    486                     ALOGV("got %s decoder EOS w/ error %d",
    487                          audio ? "audio" : "video",
    488                          err);
    489                 }
    490 
    491                 mRenderer->queueEOS(audio, err);
    492             } else if (what == ACodec::kWhatFlushCompleted) {
    493                 bool needShutdown;
    494 
    495                 if (audio) {
    496                     CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
    497                     mFlushingAudio = FLUSHED;
    498                 } else {
    499                     CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
    500                     mFlushingVideo = FLUSHED;
    501 
    502                     mVideoLateByUs = 0;
    503                 }
    504 
    505                 ALOGV("decoder %s flush completed", audio ? "audio" : "video");
    506 
    507                 if (needShutdown) {
    508                     ALOGV("initiating %s decoder shutdown",
    509                          audio ? "audio" : "video");
    510 
    511                     (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();
    512 
    513                     if (audio) {
    514                         mFlushingAudio = SHUTTING_DOWN_DECODER;
    515                     } else {
    516                         mFlushingVideo = SHUTTING_DOWN_DECODER;
    517                     }
    518                 }
    519 
    520                 finishFlushIfPossible();
    521             } else if (what == ACodec::kWhatOutputFormatChanged) {
    522                 if (audio) {
    523                     int32_t numChannels;
    524                     CHECK(codecRequest->findInt32(
    525                                 "channel-count", &numChannels));
    526 
    527                     int32_t sampleRate;
    528                     CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
    529 
    530                     ALOGV("Audio output format changed to %d Hz, %d channels",
    531                          sampleRate, numChannels);
    532 
    533                     mAudioSink->close();
    534 
    535                     audio_output_flags_t flags;
    536                     int64_t durationUs;
    537                     // FIXME: we should handle the case where the video decoder
    538                     // is created after we receive the format change indication.
    539                     // Current code will just make that we select deep buffer
    540                     // with video which should not be a problem as it should
    541                     // not prevent from keeping A/V sync.
    542                     if (mVideoDecoder == NULL &&
    543                             mSource->getDuration(&durationUs) == OK &&
    544                             durationUs
    545                                 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
    546                         flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
    547                     } else {
    548                         flags = AUDIO_OUTPUT_FLAG_NONE;
    549                     }
    550 
    551                     int32_t channelMask;
    552                     if (!codecRequest->findInt32("channel-mask", &channelMask)) {
    553                         channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
    554                     }
    555 
    556                     CHECK_EQ(mAudioSink->open(
    557                                 sampleRate,
    558                                 numChannels,
    559                                 (audio_channel_mask_t)channelMask,
    560                                 AUDIO_FORMAT_PCM_16_BIT,
    561                                 8 /* bufferCount */,
    562                                 NULL,
    563                                 NULL,
    564                                 flags),
    565                              (status_t)OK);
    566                     mAudioSink->start();
    567 
    568                     mRenderer->signalAudioSinkChanged();
    569                 } else {
    570                     // video
    571 
    572                     int32_t width, height;
    573                     CHECK(codecRequest->findInt32("width", &width));
    574                     CHECK(codecRequest->findInt32("height", &height));
    575 
    576                     int32_t cropLeft, cropTop, cropRight, cropBottom;
    577                     CHECK(codecRequest->findRect(
    578                                 "crop",
    579                                 &cropLeft, &cropTop, &cropRight, &cropBottom));
    580 
    581                     int32_t displayWidth = cropRight - cropLeft + 1;
    582                     int32_t displayHeight = cropBottom - cropTop + 1;
    583 
    584                     ALOGV("Video output format changed to %d x %d "
    585                          "(crop: %d x %d @ (%d, %d))",
    586                          width, height,
    587                          displayWidth,
    588                          displayHeight,
    589                          cropLeft, cropTop);
    590 
    591                     sp<AMessage> videoInputFormat =
    592                         mSource->getFormat(false /* audio */);
    593 
    594                     // Take into account sample aspect ratio if necessary:
    595                     int32_t sarWidth, sarHeight;
    596                     if (videoInputFormat->findInt32("sar-width", &sarWidth)
    597                             && videoInputFormat->findInt32(
    598                                 "sar-height", &sarHeight)) {
    599                         ALOGV("Sample aspect ratio %d : %d",
    600                               sarWidth, sarHeight);
    601 
    602                         displayWidth = (displayWidth * sarWidth) / sarHeight;
    603 
    604                         ALOGV("display dimensions %d x %d",
    605                               displayWidth, displayHeight);
    606                     }
    607 
    608                     notifyListener(
    609                             MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
    610                 }
    611             } else if (what == ACodec::kWhatShutdownCompleted) {
    612                 ALOGV("%s shutdown completed", audio ? "audio" : "video");
    613                 if (audio) {
    614                     mAudioDecoder.clear();
    615 
    616                     CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
    617                     mFlushingAudio = SHUT_DOWN;
    618                 } else {
    619                     mVideoDecoder.clear();
    620 
    621                     CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
    622                     mFlushingVideo = SHUT_DOWN;
    623                 }
    624 
    625                 finishFlushIfPossible();
    626             } else if (what == ACodec::kWhatError) {
    627                 ALOGE("Received error from %s decoder, aborting playback.",
    628                      audio ? "audio" : "video");
    629 
    630                 mRenderer->queueEOS(audio, UNKNOWN_ERROR);
    631             } else if (what == ACodec::kWhatDrainThisBuffer) {
    632                 renderBuffer(audio, codecRequest);
    633             } else if (what != ACodec::kWhatComponentAllocated
    634                     && what != ACodec::kWhatComponentConfigured
    635                     && what != ACodec::kWhatBuffersAllocated) {
    636                 ALOGV("Unhandled codec notification %d '%c%c%c%c'.",
    637                       what,
    638                       what >> 24,
    639                       (what >> 16) & 0xff,
    640                       (what >> 8) & 0xff,
    641                       what & 0xff);
    642             }
    643 
    644             break;
    645         }
    646 
    647         case kWhatRendererNotify:
    648         {
    649             int32_t what;
    650             CHECK(msg->findInt32("what", &what));
    651 
    652             if (what == Renderer::kWhatEOS) {
    653                 int32_t audio;
    654                 CHECK(msg->findInt32("audio", &audio));
    655 
    656                 int32_t finalResult;
    657                 CHECK(msg->findInt32("finalResult", &finalResult));
    658 
    659                 if (audio) {
    660                     mAudioEOS = true;
    661                 } else {
    662                     mVideoEOS = true;
    663                 }
    664 
    665                 if (finalResult == ERROR_END_OF_STREAM) {
    666                     ALOGV("reached %s EOS", audio ? "audio" : "video");
    667                 } else {
    668                     ALOGE("%s track encountered an error (%d)",
    669                          audio ? "audio" : "video", finalResult);
    670 
    671                     notifyListener(
    672                             MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
    673                 }
    674 
    675                 if ((mAudioEOS || mAudioDecoder == NULL)
    676                         && (mVideoEOS || mVideoDecoder == NULL)) {
    677                     notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
    678                 }
    679             } else if (what == Renderer::kWhatPosition) {
    680                 int64_t positionUs;
    681                 CHECK(msg->findInt64("positionUs", &positionUs));
    682 
    683                 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
    684 
    685                 if (mDriver != NULL) {
    686                     sp<NuPlayerDriver> driver = mDriver.promote();
    687                     if (driver != NULL) {
    688                         driver->notifyPosition(positionUs);
    689 
    690                         driver->notifyFrameStats(
    691                                 mNumFramesTotal, mNumFramesDropped);
    692                     }
    693                 }
    694             } else if (what == Renderer::kWhatFlushComplete) {
    695                 int32_t audio;
    696                 CHECK(msg->findInt32("audio", &audio));
    697 
    698                 ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
    699             } else if (what == Renderer::kWhatVideoRenderingStart) {
    700                 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
    701             }
    702             break;
    703         }
    704 
    705         case kWhatMoreDataQueued:
    706         {
    707             break;
    708         }
    709 
    710         case kWhatReset:
    711         {
    712             ALOGV("kWhatReset");
    713 
    714             mDeferredActions.push_back(
    715                     new SimpleAction(&NuPlayer::performDecoderShutdown));
    716 
    717             mDeferredActions.push_back(
    718                     new SimpleAction(&NuPlayer::performReset));
    719 
    720             processDeferredActions();
    721             break;
    722         }
    723 
    724         case kWhatSeek:
    725         {
    726             int64_t seekTimeUs;
    727             CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
    728 
    729             ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
    730 
    731             mDeferredActions.push_back(
    732                     new SimpleAction(&NuPlayer::performDecoderFlush));
    733 
    734             mDeferredActions.push_back(new SeekAction(seekTimeUs));
    735 
    736             processDeferredActions();
    737             break;
    738         }
    739 
    740         case kWhatPause:
    741         {
    742             CHECK(mRenderer != NULL);
    743             mSource->pause();
    744             mRenderer->pause();
    745             break;
    746         }
    747 
    748         case kWhatResume:
    749         {
    750             CHECK(mRenderer != NULL);
    751             mSource->resume();
    752             mRenderer->resume();
    753             break;
    754         }
    755 
    756         case kWhatSourceNotify:
    757         {
    758             onSourceNotify(msg);
    759             break;
    760         }
    761 
    762         default:
    763             TRESPASS();
    764             break;
    765     }
    766 }
    767 
    768 void NuPlayer::finishFlushIfPossible() {
    769     if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
    770         return;
    771     }
    772 
    773     if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
    774         return;
    775     }
    776 
    777     ALOGV("both audio and video are flushed now.");
    778 
    779     if (mTimeDiscontinuityPending) {
    780         mRenderer->signalTimeDiscontinuity();
    781         mTimeDiscontinuityPending = false;
    782     }
    783 
    784     if (mAudioDecoder != NULL) {
    785         mAudioDecoder->signalResume();
    786     }
    787 
    788     if (mVideoDecoder != NULL) {
    789         mVideoDecoder->signalResume();
    790     }
    791 
    792     mFlushingAudio = NONE;
    793     mFlushingVideo = NONE;
    794 
    795     processDeferredActions();
    796 }
    797 
    798 void NuPlayer::postScanSources() {
    799     if (mScanSourcesPending) {
    800         return;
    801     }
    802 
    803     sp<AMessage> msg = new AMessage(kWhatScanSources, id());
    804     msg->setInt32("generation", mScanSourcesGeneration);
    805     msg->post();
    806 
    807     mScanSourcesPending = true;
    808 }
    809 
    810 status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
    811     if (*decoder != NULL) {
    812         return OK;
    813     }
    814 
    815     sp<AMessage> format = mSource->getFormat(audio);
    816 
    817     if (format == NULL) {
    818         return -EWOULDBLOCK;
    819     }
    820 
    821     if (!audio) {
    822         AString mime;
    823         CHECK(format->findString("mime", &mime));
    824         mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
    825     }
    826 
    827     sp<AMessage> notify =
    828         new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
    829                      id());
    830 
    831     *decoder = audio ? new Decoder(notify) :
    832                        new Decoder(notify, mNativeWindow);
    833     looper()->registerHandler(*decoder);
    834 
    835     (*decoder)->configure(format);
    836 
    837     return OK;
    838 }
    839 
    840 status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
    841     sp<AMessage> reply;
    842     CHECK(msg->findMessage("reply", &reply));
    843 
    844     if ((audio && IsFlushingState(mFlushingAudio))
    845             || (!audio && IsFlushingState(mFlushingVideo))) {
    846         reply->setInt32("err", INFO_DISCONTINUITY);
    847         reply->post();
    848         return OK;
    849     }
    850 
    851     sp<ABuffer> accessUnit;
    852 
    853     bool dropAccessUnit;
    854     do {
    855         status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
    856 
    857         if (err == -EWOULDBLOCK) {
    858             return err;
    859         } else if (err != OK) {
    860             if (err == INFO_DISCONTINUITY) {
    861                 int32_t type;
    862                 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
    863 
    864                 bool formatChange =
    865                     (audio &&
    866                      (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
    867                     || (!audio &&
    868                             (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
    869 
    870                 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
    871 
    872                 ALOGI("%s discontinuity (formatChange=%d, time=%d)",
    873                      audio ? "audio" : "video", formatChange, timeChange);
    874 
    875                 if (audio) {
    876                     mSkipRenderingAudioUntilMediaTimeUs = -1;
    877                 } else {
    878                     mSkipRenderingVideoUntilMediaTimeUs = -1;
    879                 }
    880 
    881                 if (timeChange) {
    882                     sp<AMessage> extra;
    883                     if (accessUnit->meta()->findMessage("extra", &extra)
    884                             && extra != NULL) {
    885                         int64_t resumeAtMediaTimeUs;
    886                         if (extra->findInt64(
    887                                     "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
    888                             ALOGI("suppressing rendering of %s until %lld us",
    889                                     audio ? "audio" : "video", resumeAtMediaTimeUs);
    890 
    891                             if (audio) {
    892                                 mSkipRenderingAudioUntilMediaTimeUs =
    893                                     resumeAtMediaTimeUs;
    894                             } else {
    895                                 mSkipRenderingVideoUntilMediaTimeUs =
    896                                     resumeAtMediaTimeUs;
    897                             }
    898                         }
    899                     }
    900                 }
    901 
    902                 mTimeDiscontinuityPending =
    903                     mTimeDiscontinuityPending || timeChange;
    904 
    905                 if (formatChange || timeChange) {
    906                     if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
    907                         // And we'll resume scanning sources once we're done
    908                         // flushing.
    909                         mDeferredActions.push_front(
    910                                 new SimpleAction(
    911                                     &NuPlayer::performScanSources));
    912                     }
    913 
    914                     flushDecoder(audio, formatChange);
    915                 } else {
    916                     // This stream is unaffected by the discontinuity
    917 
    918                     if (audio) {
    919                         mFlushingAudio = FLUSHED;
    920                     } else {
    921                         mFlushingVideo = FLUSHED;
    922                     }
    923 
    924                     finishFlushIfPossible();
    925 
    926                     return -EWOULDBLOCK;
    927                 }
    928             }
    929 
    930             reply->setInt32("err", err);
    931             reply->post();
    932             return OK;
    933         }
    934 
    935         if (!audio) {
    936             ++mNumFramesTotal;
    937         }
    938 
    939         dropAccessUnit = false;
    940         if (!audio
    941                 && mVideoLateByUs > 100000ll
    942                 && mVideoIsAVC
    943                 && !IsAVCReferenceFrame(accessUnit)) {
    944             dropAccessUnit = true;
    945             ++mNumFramesDropped;
    946         }
    947     } while (dropAccessUnit);
    948 
    949     // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
    950 
    951 #if 0
    952     int64_t mediaTimeUs;
    953     CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
    954     ALOGV("feeding %s input buffer at media time %.2f secs",
    955          audio ? "audio" : "video",
    956          mediaTimeUs / 1E6);
    957 #endif
    958 
    959     reply->setBuffer("buffer", accessUnit);
    960     reply->post();
    961 
    962     return OK;
    963 }
    964 
    965 void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
    966     // ALOGV("renderBuffer %s", audio ? "audio" : "video");
    967 
    968     sp<AMessage> reply;
    969     CHECK(msg->findMessage("reply", &reply));
    970 
    971     if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
    972         // We're currently attempting to flush the decoder, in order
    973         // to complete this, the decoder wants all its buffers back,
    974         // so we don't want any output buffers it sent us (from before
    975         // we initiated the flush) to be stuck in the renderer's queue.
    976 
    977         ALOGV("we're still flushing the %s decoder, sending its output buffer"
    978              " right back.", audio ? "audio" : "video");
    979 
    980         reply->post();
    981         return;
    982     }
    983 
    984     sp<ABuffer> buffer;
    985     CHECK(msg->findBuffer("buffer", &buffer));
    986 
    987     int64_t &skipUntilMediaTimeUs =
    988         audio
    989             ? mSkipRenderingAudioUntilMediaTimeUs
    990             : mSkipRenderingVideoUntilMediaTimeUs;
    991 
    992     if (skipUntilMediaTimeUs >= 0) {
    993         int64_t mediaTimeUs;
    994         CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
    995 
    996         if (mediaTimeUs < skipUntilMediaTimeUs) {
    997             ALOGV("dropping %s buffer at time %lld as requested.",
    998                  audio ? "audio" : "video",
    999                  mediaTimeUs);
   1000 
   1001             reply->post();
   1002             return;
   1003         }
   1004 
   1005         skipUntilMediaTimeUs = -1;
   1006     }
   1007 
   1008     mRenderer->queueBuffer(audio, buffer, reply);
   1009 }
   1010 
   1011 void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
   1012     if (mDriver == NULL) {
   1013         return;
   1014     }
   1015 
   1016     sp<NuPlayerDriver> driver = mDriver.promote();
   1017 
   1018     if (driver == NULL) {
   1019         return;
   1020     }
   1021 
   1022     driver->notifyListener(msg, ext1, ext2);
   1023 }
   1024 
   1025 void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
   1026     if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
   1027         ALOGI("flushDecoder %s without decoder present",
   1028              audio ? "audio" : "video");
   1029     }
   1030 
   1031     // Make sure we don't continue to scan sources until we finish flushing.
   1032     ++mScanSourcesGeneration;
   1033     mScanSourcesPending = false;
   1034 
   1035     (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
   1036     mRenderer->flush(audio);
   1037 
   1038     FlushStatus newStatus =
   1039         needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
   1040 
   1041     if (audio) {
   1042         CHECK(mFlushingAudio == NONE
   1043                 || mFlushingAudio == AWAITING_DISCONTINUITY);
   1044 
   1045         mFlushingAudio = newStatus;
   1046 
   1047         if (mFlushingVideo == NONE) {
   1048             mFlushingVideo = (mVideoDecoder != NULL)
   1049                 ? AWAITING_DISCONTINUITY
   1050                 : FLUSHED;
   1051         }
   1052     } else {
   1053         CHECK(mFlushingVideo == NONE
   1054                 || mFlushingVideo == AWAITING_DISCONTINUITY);
   1055 
   1056         mFlushingVideo = newStatus;
   1057 
   1058         if (mFlushingAudio == NONE) {
   1059             mFlushingAudio = (mAudioDecoder != NULL)
   1060                 ? AWAITING_DISCONTINUITY
   1061                 : FLUSHED;
   1062         }
   1063     }
   1064 }
   1065 
   1066 sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
   1067     sp<MetaData> meta = getFormatMeta(audio);
   1068 
   1069     if (meta == NULL) {
   1070         return NULL;
   1071     }
   1072 
   1073     sp<AMessage> msg = new AMessage;
   1074 
   1075     if(convertMetaDataToMessage(meta, &msg) == OK) {
   1076         return msg;
   1077     }
   1078     return NULL;
   1079 }
   1080 
   1081 status_t NuPlayer::setVideoScalingMode(int32_t mode) {
   1082     mVideoScalingMode = mode;
   1083     if (mNativeWindow != NULL) {
   1084         status_t ret = native_window_set_scaling_mode(
   1085                 mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
   1086         if (ret != OK) {
   1087             ALOGE("Failed to set scaling mode (%d): %s",
   1088                 -ret, strerror(-ret));
   1089             return ret;
   1090         }
   1091     }
   1092     return OK;
   1093 }
   1094 
   1095 void NuPlayer::schedulePollDuration() {
   1096     sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
   1097     msg->setInt32("generation", mPollDurationGeneration);
   1098     msg->post();
   1099 }
   1100 
   1101 void NuPlayer::cancelPollDuration() {
   1102     ++mPollDurationGeneration;
   1103 }
   1104 
   1105 void NuPlayer::processDeferredActions() {
   1106     while (!mDeferredActions.empty()) {
   1107         // We won't execute any deferred actions until we're no longer in
   1108         // an intermediate state, i.e. one more more decoders are currently
   1109         // flushing or shutting down.
   1110 
   1111         if (mRenderer != NULL) {
   1112             // There's an edge case where the renderer owns all output
   1113             // buffers and is paused, therefore the decoder will not read
   1114             // more input data and will never encounter the matching
   1115             // discontinuity. To avoid this, we resume the renderer.
   1116 
   1117             if (mFlushingAudio == AWAITING_DISCONTINUITY
   1118                     || mFlushingVideo == AWAITING_DISCONTINUITY) {
   1119                 mRenderer->resume();
   1120             }
   1121         }
   1122 
   1123         if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
   1124             // We're currently flushing, postpone the reset until that's
   1125             // completed.
   1126 
   1127             ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
   1128                   mFlushingAudio, mFlushingVideo);
   1129 
   1130             break;
   1131         }
   1132 
   1133         sp<Action> action = *mDeferredActions.begin();
   1134         mDeferredActions.erase(mDeferredActions.begin());
   1135 
   1136         action->execute(this);
   1137     }
   1138 }
   1139 
   1140 void NuPlayer::performSeek(int64_t seekTimeUs) {
   1141     ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
   1142           seekTimeUs,
   1143           seekTimeUs / 1E6);
   1144 
   1145     mSource->seekTo(seekTimeUs);
   1146 
   1147     if (mDriver != NULL) {
   1148         sp<NuPlayerDriver> driver = mDriver.promote();
   1149         if (driver != NULL) {
   1150             driver->notifyPosition(seekTimeUs);
   1151             driver->notifySeekComplete();
   1152         }
   1153     }
   1154 
   1155     // everything's flushed, continue playback.
   1156 }
   1157 
   1158 void NuPlayer::performDecoderFlush() {
   1159     ALOGV("performDecoderFlush");
   1160 
   1161     if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
   1162         return;
   1163     }
   1164 
   1165     mTimeDiscontinuityPending = true;
   1166 
   1167     if (mAudioDecoder != NULL) {
   1168         flushDecoder(true /* audio */, false /* needShutdown */);
   1169     }
   1170 
   1171     if (mVideoDecoder != NULL) {
   1172         flushDecoder(false /* audio */, false /* needShutdown */);
   1173     }
   1174 }
   1175 
   1176 void NuPlayer::performDecoderShutdown() {
   1177     ALOGV("performDecoderShutdown");
   1178 
   1179     if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
   1180         return;
   1181     }
   1182 
   1183     mTimeDiscontinuityPending = true;
   1184 
   1185     if (mAudioDecoder != NULL) {
   1186         flushDecoder(true /* audio */, true /* needShutdown */);
   1187     }
   1188 
   1189     if (mVideoDecoder != NULL) {
   1190         flushDecoder(false /* audio */, true /* needShutdown */);
   1191     }
   1192 }
   1193 
   1194 void NuPlayer::performReset() {
   1195     ALOGV("performReset");
   1196 
   1197     CHECK(mAudioDecoder == NULL);
   1198     CHECK(mVideoDecoder == NULL);
   1199 
   1200     cancelPollDuration();
   1201 
   1202     ++mScanSourcesGeneration;
   1203     mScanSourcesPending = false;
   1204 
   1205     mRenderer.clear();
   1206 
   1207     if (mSource != NULL) {
   1208         mSource->stop();
   1209 
   1210         looper()->unregisterHandler(mSource->id());
   1211 
   1212         mSource.clear();
   1213     }
   1214 
   1215     if (mDriver != NULL) {
   1216         sp<NuPlayerDriver> driver = mDriver.promote();
   1217         if (driver != NULL) {
   1218             driver->notifyResetComplete();
   1219         }
   1220     }
   1221 
   1222     mStarted = false;
   1223 }
   1224 
   1225 void NuPlayer::performScanSources() {
   1226     ALOGV("performScanSources");
   1227 
   1228     if (!mStarted) {
   1229         return;
   1230     }
   1231 
   1232     if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
   1233         postScanSources();
   1234     }
   1235 }
   1236 
   1237 void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
   1238     ALOGV("performSetSurface");
   1239 
   1240     mNativeWindow = wrapper;
   1241 
   1242     // XXX - ignore error from setVideoScalingMode for now
   1243     setVideoScalingMode(mVideoScalingMode);
   1244 
   1245     if (mDriver != NULL) {
   1246         sp<NuPlayerDriver> driver = mDriver.promote();
   1247         if (driver != NULL) {
   1248             driver->notifySetSurfaceComplete();
   1249         }
   1250     }
   1251 }
   1252 
   1253 void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
   1254     int32_t what;
   1255     CHECK(msg->findInt32("what", &what));
   1256 
   1257     switch (what) {
   1258         case Source::kWhatPrepared:
   1259         {
   1260             if (mSource == NULL) {
   1261                 // This is a stale notification from a source that was
   1262                 // asynchronously preparing when the client called reset().
   1263                 // We handled the reset, the source is gone.
   1264                 break;
   1265             }
   1266 
   1267             int32_t err;
   1268             CHECK(msg->findInt32("err", &err));
   1269 
   1270             sp<NuPlayerDriver> driver = mDriver.promote();
   1271             if (driver != NULL) {
   1272                 driver->notifyPrepareCompleted(err);
   1273             }
   1274 
   1275             int64_t durationUs;
   1276             if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
   1277                 sp<NuPlayerDriver> driver = mDriver.promote();
   1278                 if (driver != NULL) {
   1279                     driver->notifyDuration(durationUs);
   1280                 }
   1281             }
   1282             break;
   1283         }
   1284 
   1285         case Source::kWhatFlagsChanged:
   1286         {
   1287             uint32_t flags;
   1288             CHECK(msg->findInt32("flags", (int32_t *)&flags));
   1289 
   1290             if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
   1291                     && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
   1292                 cancelPollDuration();
   1293             } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
   1294                     && (flags & Source::FLAG_DYNAMIC_DURATION)
   1295                     && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
   1296                 schedulePollDuration();
   1297             }
   1298 
   1299             mSourceFlags = flags;
   1300             break;
   1301         }
   1302 
   1303         case Source::kWhatVideoSizeChanged:
   1304         {
   1305             int32_t width, height;
   1306             CHECK(msg->findInt32("width", &width));
   1307             CHECK(msg->findInt32("height", &height));
   1308 
   1309             notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
   1310             break;
   1311         }
   1312 
   1313         case Source::kWhatBufferingStart:
   1314         {
   1315             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
   1316             break;
   1317         }
   1318 
   1319         case Source::kWhatBufferingEnd:
   1320         {
   1321             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
   1322             break;
   1323         }
   1324 
   1325         default:
   1326             TRESPASS();
   1327     }
   1328 }
   1329 
   1330 ////////////////////////////////////////////////////////////////////////////////
   1331 
   1332 void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
   1333     sp<AMessage> notify = dupNotify();
   1334     notify->setInt32("what", kWhatFlagsChanged);
   1335     notify->setInt32("flags", flags);
   1336     notify->post();
   1337 }
   1338 
   1339 void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) {
   1340     sp<AMessage> notify = dupNotify();
   1341     notify->setInt32("what", kWhatVideoSizeChanged);
   1342     notify->setInt32("width", width);
   1343     notify->setInt32("height", height);
   1344     notify->post();
   1345 }
   1346 
   1347 void NuPlayer::Source::notifyPrepared(status_t err) {
   1348     sp<AMessage> notify = dupNotify();
   1349     notify->setInt32("what", kWhatPrepared);
   1350     notify->setInt32("err", err);
   1351     notify->post();
   1352 }
   1353 
   1354 void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
   1355     TRESPASS();
   1356 }
   1357 
   1358 }  // namespace android
   1359