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 "NuPlayerDriver"
     19 #include <utils/Log.h>
     20 
     21 #include "NuPlayerDriver.h"
     22 
     23 #include "NuPlayer.h"
     24 
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/foundation/ALooper.h>
     27 
     28 namespace android {
     29 
     30 NuPlayerDriver::NuPlayerDriver()
     31     : mResetInProgress(false),
     32       mDurationUs(-1),
     33       mPositionUs(-1),
     34       mNumFramesTotal(0),
     35       mNumFramesDropped(0),
     36       mLooper(new ALooper),
     37       mState(UNINITIALIZED),
     38       mAtEOS(false),
     39       mStartupSeekTimeUs(-1) {
     40     mLooper->setName("NuPlayerDriver Looper");
     41 
     42     mLooper->start(
     43             false, /* runOnCallingThread */
     44             true,  /* canCallJava */
     45             PRIORITY_AUDIO);
     46 
     47     mPlayer = new NuPlayer;
     48     mLooper->registerHandler(mPlayer);
     49 
     50     mPlayer->setDriver(this);
     51 }
     52 
     53 NuPlayerDriver::~NuPlayerDriver() {
     54     mLooper->stop();
     55 }
     56 
     57 status_t NuPlayerDriver::initCheck() {
     58     return OK;
     59 }
     60 
     61 status_t NuPlayerDriver::setUID(uid_t uid) {
     62     mPlayer->setUID(uid);
     63 
     64     return OK;
     65 }
     66 
     67 status_t NuPlayerDriver::setDataSource(
     68         const char *url, const KeyedVector<String8, String8> *headers) {
     69     CHECK_EQ((int)mState, (int)UNINITIALIZED);
     70 
     71     mPlayer->setDataSource(url, headers);
     72 
     73     mState = STOPPED;
     74 
     75     return OK;
     76 }
     77 
     78 status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
     79     CHECK_EQ((int)mState, (int)UNINITIALIZED);
     80 
     81     mPlayer->setDataSource(fd, offset, length);
     82 
     83     mState = STOPPED;
     84 
     85     return OK;
     86 }
     87 
     88 status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
     89     CHECK_EQ((int)mState, (int)UNINITIALIZED);
     90 
     91     mPlayer->setDataSource(source);
     92 
     93     mState = STOPPED;
     94 
     95     return OK;
     96 }
     97 
     98 status_t NuPlayerDriver::setVideoSurfaceTexture(
     99         const sp<ISurfaceTexture> &surfaceTexture) {
    100     mPlayer->setVideoSurfaceTexture(surfaceTexture);
    101 
    102     return OK;
    103 }
    104 
    105 status_t NuPlayerDriver::prepare() {
    106     sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0);
    107     return OK;
    108 }
    109 
    110 status_t NuPlayerDriver::prepareAsync() {
    111     status_t err = prepare();
    112 
    113     notifyListener(MEDIA_PREPARED);
    114 
    115     return err;
    116 }
    117 
    118 status_t NuPlayerDriver::start() {
    119     switch (mState) {
    120         case UNINITIALIZED:
    121             return INVALID_OPERATION;
    122         case STOPPED:
    123         {
    124             mAtEOS = false;
    125             mPlayer->start();
    126 
    127             if (mStartupSeekTimeUs >= 0) {
    128                 if (mStartupSeekTimeUs == 0) {
    129                     notifySeekComplete();
    130                 } else {
    131                     mPlayer->seekToAsync(mStartupSeekTimeUs);
    132                 }
    133 
    134                 mStartupSeekTimeUs = -1;
    135             }
    136 
    137             break;
    138         }
    139         case PLAYING:
    140             return OK;
    141         default:
    142         {
    143             CHECK_EQ((int)mState, (int)PAUSED);
    144 
    145             mPlayer->resume();
    146             break;
    147         }
    148     }
    149 
    150     mState = PLAYING;
    151 
    152     return OK;
    153 }
    154 
    155 status_t NuPlayerDriver::stop() {
    156     return pause();
    157 }
    158 
    159 status_t NuPlayerDriver::pause() {
    160     switch (mState) {
    161         case UNINITIALIZED:
    162             return INVALID_OPERATION;
    163         case STOPPED:
    164             return OK;
    165         case PLAYING:
    166             mPlayer->pause();
    167             break;
    168         default:
    169         {
    170             CHECK_EQ((int)mState, (int)PAUSED);
    171             return OK;
    172         }
    173     }
    174 
    175     mState = PAUSED;
    176 
    177     return OK;
    178 }
    179 
    180 bool NuPlayerDriver::isPlaying() {
    181     return mState == PLAYING && !mAtEOS;
    182 }
    183 
    184 status_t NuPlayerDriver::seekTo(int msec) {
    185     int64_t seekTimeUs = msec * 1000ll;
    186 
    187     switch (mState) {
    188         case UNINITIALIZED:
    189             return INVALID_OPERATION;
    190         case STOPPED:
    191         {
    192             mStartupSeekTimeUs = seekTimeUs;
    193             break;
    194         }
    195         case PLAYING:
    196         case PAUSED:
    197         {
    198             mAtEOS = false;
    199             mPlayer->seekToAsync(seekTimeUs);
    200             break;
    201         }
    202 
    203         default:
    204             TRESPASS();
    205             break;
    206     }
    207 
    208     return OK;
    209 }
    210 
    211 status_t NuPlayerDriver::getCurrentPosition(int *msec) {
    212     Mutex::Autolock autoLock(mLock);
    213 
    214     if (mPositionUs < 0) {
    215         *msec = 0;
    216     } else {
    217         *msec = (mPositionUs + 500ll) / 1000;
    218     }
    219 
    220     return OK;
    221 }
    222 
    223 status_t NuPlayerDriver::getDuration(int *msec) {
    224     Mutex::Autolock autoLock(mLock);
    225 
    226     if (mDurationUs < 0) {
    227         *msec = 0;
    228     } else {
    229         *msec = (mDurationUs + 500ll) / 1000;
    230     }
    231 
    232     return OK;
    233 }
    234 
    235 status_t NuPlayerDriver::reset() {
    236     Mutex::Autolock autoLock(mLock);
    237     mResetInProgress = true;
    238 
    239     mPlayer->resetAsync();
    240 
    241     while (mResetInProgress) {
    242         mCondition.wait(mLock);
    243     }
    244 
    245     mDurationUs = -1;
    246     mPositionUs = -1;
    247     mState = UNINITIALIZED;
    248     mStartupSeekTimeUs = -1;
    249 
    250     return OK;
    251 }
    252 
    253 status_t NuPlayerDriver::setLooping(int loop) {
    254     return INVALID_OPERATION;
    255 }
    256 
    257 player_type NuPlayerDriver::playerType() {
    258     return NU_PLAYER;
    259 }
    260 
    261 status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
    262     return INVALID_OPERATION;
    263 }
    264 
    265 void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
    266     mPlayer->setAudioSink(audioSink);
    267 }
    268 
    269 status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
    270     return INVALID_OPERATION;
    271 }
    272 
    273 status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
    274     return INVALID_OPERATION;
    275 }
    276 
    277 status_t NuPlayerDriver::getMetadata(
    278         const media::Metadata::Filter& ids, Parcel *records) {
    279     return INVALID_OPERATION;
    280 }
    281 
    282 void NuPlayerDriver::notifyResetComplete() {
    283     Mutex::Autolock autoLock(mLock);
    284     CHECK(mResetInProgress);
    285     mResetInProgress = false;
    286     mCondition.broadcast();
    287 }
    288 
    289 void NuPlayerDriver::notifyDuration(int64_t durationUs) {
    290     Mutex::Autolock autoLock(mLock);
    291     mDurationUs = durationUs;
    292 }
    293 
    294 void NuPlayerDriver::notifyPosition(int64_t positionUs) {
    295     Mutex::Autolock autoLock(mLock);
    296     mPositionUs = positionUs;
    297 }
    298 
    299 void NuPlayerDriver::notifySeekComplete() {
    300     notifyListener(MEDIA_SEEK_COMPLETE);
    301 }
    302 
    303 void NuPlayerDriver::notifyFrameStats(
    304         int64_t numFramesTotal, int64_t numFramesDropped) {
    305     Mutex::Autolock autoLock(mLock);
    306     mNumFramesTotal = numFramesTotal;
    307     mNumFramesDropped = numFramesDropped;
    308 }
    309 
    310 status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
    311     Mutex::Autolock autoLock(mLock);
    312 
    313     FILE *out = fdopen(dup(fd), "w");
    314 
    315     fprintf(out, " NuPlayer\n");
    316     fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
    317                  "percentageDropped(%.2f)\n",
    318                  mNumFramesTotal,
    319                  mNumFramesDropped,
    320                  mNumFramesTotal == 0
    321                     ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
    322 
    323     fclose(out);
    324     out = NULL;
    325 
    326     return OK;
    327 }
    328 
    329 void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
    330     if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
    331         mAtEOS = true;
    332     }
    333 
    334     sendEvent(msg, ext1, ext2);
    335 }
    336 
    337 }  // namespace android
    338