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     if (reply == NULL) {
    263         ALOGE("reply is a NULL pointer");
    264         return BAD_VALUE;
    265     }
    266 
    267     int32_t methodId;
    268     status_t ret = request.readInt32(&methodId);
    269     if (ret != OK) {
    270         ALOGE("Failed to retrieve the requested method to invoke");
    271         return ret;
    272     }
    273 
    274     switch (methodId) {
    275         case INVOKE_ID_SET_VIDEO_SCALING_MODE:
    276         {
    277             int mode = request.readInt32();
    278             return mPlayer->setVideoScalingMode(mode);
    279         }
    280         default:
    281         {
    282             return INVALID_OPERATION;
    283         }
    284     }
    285 }
    286 
    287 void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
    288     mPlayer->setAudioSink(audioSink);
    289 }
    290 
    291 status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
    292     return INVALID_OPERATION;
    293 }
    294 
    295 status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
    296     return INVALID_OPERATION;
    297 }
    298 
    299 status_t NuPlayerDriver::getMetadata(
    300         const media::Metadata::Filter& ids, Parcel *records) {
    301     return INVALID_OPERATION;
    302 }
    303 
    304 void NuPlayerDriver::notifyResetComplete() {
    305     Mutex::Autolock autoLock(mLock);
    306     CHECK(mResetInProgress);
    307     mResetInProgress = false;
    308     mCondition.broadcast();
    309 }
    310 
    311 void NuPlayerDriver::notifyDuration(int64_t durationUs) {
    312     Mutex::Autolock autoLock(mLock);
    313     mDurationUs = durationUs;
    314 }
    315 
    316 void NuPlayerDriver::notifyPosition(int64_t positionUs) {
    317     Mutex::Autolock autoLock(mLock);
    318     mPositionUs = positionUs;
    319 }
    320 
    321 void NuPlayerDriver::notifySeekComplete() {
    322     notifyListener(MEDIA_SEEK_COMPLETE);
    323 }
    324 
    325 void NuPlayerDriver::notifyFrameStats(
    326         int64_t numFramesTotal, int64_t numFramesDropped) {
    327     Mutex::Autolock autoLock(mLock);
    328     mNumFramesTotal = numFramesTotal;
    329     mNumFramesDropped = numFramesDropped;
    330 }
    331 
    332 status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
    333     Mutex::Autolock autoLock(mLock);
    334 
    335     FILE *out = fdopen(dup(fd), "w");
    336 
    337     fprintf(out, " NuPlayer\n");
    338     fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
    339                  "percentageDropped(%.2f)\n",
    340                  mNumFramesTotal,
    341                  mNumFramesDropped,
    342                  mNumFramesTotal == 0
    343                     ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
    344 
    345     fclose(out);
    346     out = NULL;
    347 
    348     return OK;
    349 }
    350 
    351 void NuPlayerDriver::notifyListener(int msg, int ext1, int ext2) {
    352     if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
    353         mAtEOS = true;
    354     }
    355 
    356     sendEvent(msg, ext1, ext2);
    357 }
    358 
    359 }  // namespace android
    360