Home | History | Annotate | Download | only in libmedia
      1 /*
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 //#define LOG_NDEBUG 0
     19 #define LOG_TAG "MediaPlayer"
     20 #include <utils/Log.h>
     21 
     22 #include <sys/types.h>
     23 #include <sys/stat.h>
     24 #include <unistd.h>
     25 #include <fcntl.h>
     26 
     27 #include <binder/IServiceManager.h>
     28 #include <binder/IPCThreadState.h>
     29 
     30 #include <gui/SurfaceTextureClient.h>
     31 
     32 #include <media/mediaplayer.h>
     33 #include <media/AudioSystem.h>
     34 
     35 #include <binder/MemoryBase.h>
     36 
     37 #include <utils/KeyedVector.h>
     38 #include <utils/String8.h>
     39 
     40 #include <system/audio.h>
     41 #include <system/window.h>
     42 
     43 namespace android {
     44 
     45 MediaPlayer::MediaPlayer()
     46 {
     47     ALOGV("constructor");
     48     mListener = NULL;
     49     mCookie = NULL;
     50     mDuration = -1;
     51     mStreamType = AUDIO_STREAM_MUSIC;
     52     mCurrentPosition = -1;
     53     mSeekPosition = -1;
     54     mCurrentState = MEDIA_PLAYER_IDLE;
     55     mPrepareSync = false;
     56     mPrepareStatus = NO_ERROR;
     57     mLoop = false;
     58     mLeftVolume = mRightVolume = 1.0;
     59     mVideoWidth = mVideoHeight = 0;
     60     mLockThreadId = 0;
     61     mAudioSessionId = AudioSystem::newAudioSessionId();
     62     AudioSystem::acquireAudioSessionId(mAudioSessionId);
     63     mSendLevel = 0;
     64     mRetransmitEndpointValid = false;
     65 }
     66 
     67 MediaPlayer::~MediaPlayer()
     68 {
     69     ALOGV("destructor");
     70     AudioSystem::releaseAudioSessionId(mAudioSessionId);
     71     disconnect();
     72     IPCThreadState::self()->flushCommands();
     73 }
     74 
     75 void MediaPlayer::disconnect()
     76 {
     77     ALOGV("disconnect");
     78     sp<IMediaPlayer> p;
     79     {
     80         Mutex::Autolock _l(mLock);
     81         p = mPlayer;
     82         mPlayer.clear();
     83     }
     84 
     85     if (p != 0) {
     86         p->disconnect();
     87     }
     88 }
     89 
     90 // always call with lock held
     91 void MediaPlayer::clear_l()
     92 {
     93     mDuration = -1;
     94     mCurrentPosition = -1;
     95     mSeekPosition = -1;
     96     mVideoWidth = mVideoHeight = 0;
     97     mRetransmitEndpointValid = false;
     98 }
     99 
    100 status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
    101 {
    102     ALOGV("setListener");
    103     Mutex::Autolock _l(mLock);
    104     mListener = listener;
    105     return NO_ERROR;
    106 }
    107 
    108 
    109 status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
    110 {
    111     status_t err = UNKNOWN_ERROR;
    112     sp<IMediaPlayer> p;
    113     { // scope for the lock
    114         Mutex::Autolock _l(mLock);
    115 
    116         if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
    117                 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
    118             ALOGE("attachNewPlayer called in state %d", mCurrentState);
    119             return INVALID_OPERATION;
    120         }
    121 
    122         clear_l();
    123         p = mPlayer;
    124         mPlayer = player;
    125         if (player != 0) {
    126             mCurrentState = MEDIA_PLAYER_INITIALIZED;
    127             err = NO_ERROR;
    128         } else {
    129             ALOGE("Unable to to create media player");
    130         }
    131     }
    132 
    133     if (p != 0) {
    134         p->disconnect();
    135     }
    136 
    137     return err;
    138 }
    139 
    140 status_t MediaPlayer::setDataSource(
    141         const char *url, const KeyedVector<String8, String8> *headers)
    142 {
    143     ALOGV("setDataSource(%s)", url);
    144     status_t err = BAD_VALUE;
    145     if (url != NULL) {
    146         const sp<IMediaPlayerService>& service(getMediaPlayerService());
    147         if (service != 0) {
    148             sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
    149             if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
    150                 (NO_ERROR != player->setDataSource(url, headers))) {
    151                 player.clear();
    152             }
    153             err = attachNewPlayer(player);
    154         }
    155     }
    156     return err;
    157 }
    158 
    159 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
    160 {
    161     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
    162     status_t err = UNKNOWN_ERROR;
    163     const sp<IMediaPlayerService>& service(getMediaPlayerService());
    164     if (service != 0) {
    165         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
    166         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
    167             (NO_ERROR != player->setDataSource(fd, offset, length))) {
    168             player.clear();
    169         }
    170         err = attachNewPlayer(player);
    171     }
    172     return err;
    173 }
    174 
    175 status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
    176 {
    177     ALOGV("setDataSource");
    178     status_t err = UNKNOWN_ERROR;
    179     const sp<IMediaPlayerService>& service(getMediaPlayerService());
    180     if (service != 0) {
    181         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
    182         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
    183             (NO_ERROR != player->setDataSource(source))) {
    184             player.clear();
    185         }
    186         err = attachNewPlayer(player);
    187     }
    188     return err;
    189 }
    190 
    191 status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
    192 {
    193     Mutex::Autolock _l(mLock);
    194     const bool hasBeenInitialized =
    195             (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
    196             ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
    197     if ((mPlayer != NULL) && hasBeenInitialized) {
    198         ALOGV("invoke %d", request.dataSize());
    199         return  mPlayer->invoke(request, reply);
    200     }
    201     ALOGE("invoke failed: wrong state %X", mCurrentState);
    202     return INVALID_OPERATION;
    203 }
    204 
    205 status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
    206 {
    207     ALOGD("setMetadataFilter");
    208     Mutex::Autolock lock(mLock);
    209     if (mPlayer == NULL) {
    210         return NO_INIT;
    211     }
    212     return mPlayer->setMetadataFilter(filter);
    213 }
    214 
    215 status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
    216 {
    217     ALOGD("getMetadata");
    218     Mutex::Autolock lock(mLock);
    219     if (mPlayer == NULL) {
    220         return NO_INIT;
    221     }
    222     return mPlayer->getMetadata(update_only, apply_filter, metadata);
    223 }
    224 
    225 status_t MediaPlayer::setVideoSurfaceTexture(
    226         const sp<ISurfaceTexture>& surfaceTexture)
    227 {
    228     ALOGV("setVideoSurfaceTexture");
    229     Mutex::Autolock _l(mLock);
    230     if (mPlayer == 0) return NO_INIT;
    231     return mPlayer->setVideoSurfaceTexture(surfaceTexture);
    232 }
    233 
    234 // must call with lock held
    235 status_t MediaPlayer::prepareAsync_l()
    236 {
    237     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
    238         mPlayer->setAudioStreamType(mStreamType);
    239         mCurrentState = MEDIA_PLAYER_PREPARING;
    240         return mPlayer->prepareAsync();
    241     }
    242     ALOGE("prepareAsync called in state %d", mCurrentState);
    243     return INVALID_OPERATION;
    244 }
    245 
    246 // TODO: In case of error, prepareAsync provides the caller with 2 error codes,
    247 // one defined in the Android framework and one provided by the implementation
    248 // that generated the error. The sync version of prepare returns only 1 error
    249 // code.
    250 status_t MediaPlayer::prepare()
    251 {
    252     ALOGV("prepare");
    253     Mutex::Autolock _l(mLock);
    254     mLockThreadId = getThreadId();
    255     if (mPrepareSync) {
    256         mLockThreadId = 0;
    257         return -EALREADY;
    258     }
    259     mPrepareSync = true;
    260     status_t ret = prepareAsync_l();
    261     if (ret != NO_ERROR) {
    262         mLockThreadId = 0;
    263         return ret;
    264     }
    265 
    266     if (mPrepareSync) {
    267         mSignal.wait(mLock);  // wait for prepare done
    268         mPrepareSync = false;
    269     }
    270     ALOGV("prepare complete - status=%d", mPrepareStatus);
    271     mLockThreadId = 0;
    272     return mPrepareStatus;
    273 }
    274 
    275 status_t MediaPlayer::prepareAsync()
    276 {
    277     ALOGV("prepareAsync");
    278     Mutex::Autolock _l(mLock);
    279     return prepareAsync_l();
    280 }
    281 
    282 status_t MediaPlayer::start()
    283 {
    284     ALOGV("start");
    285     Mutex::Autolock _l(mLock);
    286     if (mCurrentState & MEDIA_PLAYER_STARTED)
    287         return NO_ERROR;
    288     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
    289                     MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
    290         mPlayer->setLooping(mLoop);
    291         mPlayer->setVolume(mLeftVolume, mRightVolume);
    292         mPlayer->setAuxEffectSendLevel(mSendLevel);
    293         mCurrentState = MEDIA_PLAYER_STARTED;
    294         status_t ret = mPlayer->start();
    295         if (ret != NO_ERROR) {
    296             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    297         } else {
    298             if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
    299                 ALOGV("playback completed immediately following start()");
    300             }
    301         }
    302         return ret;
    303     }
    304     ALOGE("start called in state %d", mCurrentState);
    305     return INVALID_OPERATION;
    306 }
    307 
    308 status_t MediaPlayer::stop()
    309 {
    310     ALOGV("stop");
    311     Mutex::Autolock _l(mLock);
    312     if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
    313     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
    314                     MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
    315         status_t ret = mPlayer->stop();
    316         if (ret != NO_ERROR) {
    317             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    318         } else {
    319             mCurrentState = MEDIA_PLAYER_STOPPED;
    320         }
    321         return ret;
    322     }
    323     ALOGE("stop called in state %d", mCurrentState);
    324     return INVALID_OPERATION;
    325 }
    326 
    327 status_t MediaPlayer::pause()
    328 {
    329     ALOGV("pause");
    330     Mutex::Autolock _l(mLock);
    331     if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
    332         return NO_ERROR;
    333     if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
    334         status_t ret = mPlayer->pause();
    335         if (ret != NO_ERROR) {
    336             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    337         } else {
    338             mCurrentState = MEDIA_PLAYER_PAUSED;
    339         }
    340         return ret;
    341     }
    342     ALOGE("pause called in state %d", mCurrentState);
    343     return INVALID_OPERATION;
    344 }
    345 
    346 bool MediaPlayer::isPlaying()
    347 {
    348     Mutex::Autolock _l(mLock);
    349     if (mPlayer != 0) {
    350         bool temp = false;
    351         mPlayer->isPlaying(&temp);
    352         ALOGV("isPlaying: %d", temp);
    353         if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
    354             ALOGE("internal/external state mismatch corrected");
    355             mCurrentState = MEDIA_PLAYER_PAUSED;
    356         }
    357         return temp;
    358     }
    359     ALOGV("isPlaying: no active player");
    360     return false;
    361 }
    362 
    363 status_t MediaPlayer::getVideoWidth(int *w)
    364 {
    365     ALOGV("getVideoWidth");
    366     Mutex::Autolock _l(mLock);
    367     if (mPlayer == 0) return INVALID_OPERATION;
    368     *w = mVideoWidth;
    369     return NO_ERROR;
    370 }
    371 
    372 status_t MediaPlayer::getVideoHeight(int *h)
    373 {
    374     ALOGV("getVideoHeight");
    375     Mutex::Autolock _l(mLock);
    376     if (mPlayer == 0) return INVALID_OPERATION;
    377     *h = mVideoHeight;
    378     return NO_ERROR;
    379 }
    380 
    381 status_t MediaPlayer::getCurrentPosition(int *msec)
    382 {
    383     ALOGV("getCurrentPosition");
    384     Mutex::Autolock _l(mLock);
    385     if (mPlayer != 0) {
    386         if (mCurrentPosition >= 0) {
    387             ALOGV("Using cached seek position: %d", mCurrentPosition);
    388             *msec = mCurrentPosition;
    389             return NO_ERROR;
    390         }
    391         return mPlayer->getCurrentPosition(msec);
    392     }
    393     return INVALID_OPERATION;
    394 }
    395 
    396 status_t MediaPlayer::getDuration_l(int *msec)
    397 {
    398     ALOGV("getDuration");
    399     bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
    400     if (mPlayer != 0 && isValidState) {
    401         status_t ret = NO_ERROR;
    402         if (mDuration <= 0)
    403             ret = mPlayer->getDuration(&mDuration);
    404         if (msec)
    405             *msec = mDuration;
    406         return ret;
    407     }
    408     ALOGE("Attempt to call getDuration without a valid mediaplayer");
    409     return INVALID_OPERATION;
    410 }
    411 
    412 status_t MediaPlayer::getDuration(int *msec)
    413 {
    414     Mutex::Autolock _l(mLock);
    415     return getDuration_l(msec);
    416 }
    417 
    418 status_t MediaPlayer::seekTo_l(int msec)
    419 {
    420     ALOGV("seekTo %d", msec);
    421     if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
    422         if ( msec < 0 ) {
    423             ALOGW("Attempt to seek to invalid position: %d", msec);
    424             msec = 0;
    425         } else if ((mDuration > 0) && (msec > mDuration)) {
    426             ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration);
    427             msec = mDuration;
    428         }
    429         // cache duration
    430         mCurrentPosition = msec;
    431         if (mSeekPosition < 0) {
    432             getDuration_l(NULL);
    433             mSeekPosition = msec;
    434             return mPlayer->seekTo(msec);
    435         }
    436         else {
    437             ALOGV("Seek in progress - queue up seekTo[%d]", msec);
    438             return NO_ERROR;
    439         }
    440     }
    441     ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState);
    442     return INVALID_OPERATION;
    443 }
    444 
    445 status_t MediaPlayer::seekTo(int msec)
    446 {
    447     mLockThreadId = getThreadId();
    448     Mutex::Autolock _l(mLock);
    449     status_t result = seekTo_l(msec);
    450     mLockThreadId = 0;
    451 
    452     return result;
    453 }
    454 
    455 status_t MediaPlayer::reset_l()
    456 {
    457     mLoop = false;
    458     if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
    459     mPrepareSync = false;
    460     if (mPlayer != 0) {
    461         status_t ret = mPlayer->reset();
    462         if (ret != NO_ERROR) {
    463             ALOGE("reset() failed with return code (%d)", ret);
    464             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    465         } else {
    466             mCurrentState = MEDIA_PLAYER_IDLE;
    467         }
    468         // setDataSource has to be called again to create a
    469         // new mediaplayer.
    470         mPlayer = 0;
    471         return ret;
    472     }
    473     clear_l();
    474     return NO_ERROR;
    475 }
    476 
    477 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) {
    478     Mutex::Autolock _l(mLock);
    479 
    480     if (player == NULL) {
    481         return UNKNOWN_ERROR;
    482     }
    483 
    484     if (mRetransmitEndpointValid) {
    485         return player->setRetransmitEndpoint(&mRetransmitEndpoint);
    486     }
    487 
    488     return OK;
    489 }
    490 
    491 status_t MediaPlayer::reset()
    492 {
    493     ALOGV("reset");
    494     Mutex::Autolock _l(mLock);
    495     return reset_l();
    496 }
    497 
    498 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
    499 {
    500     ALOGV("MediaPlayer::setAudioStreamType");
    501     Mutex::Autolock _l(mLock);
    502     if (mStreamType == type) return NO_ERROR;
    503     if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
    504                 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
    505         // Can't change the stream type after prepare
    506         ALOGE("setAudioStream called in state %d", mCurrentState);
    507         return INVALID_OPERATION;
    508     }
    509     // cache
    510     mStreamType = type;
    511     return OK;
    512 }
    513 
    514 status_t MediaPlayer::setLooping(int loop)
    515 {
    516     ALOGV("MediaPlayer::setLooping");
    517     Mutex::Autolock _l(mLock);
    518     mLoop = (loop != 0);
    519     if (mPlayer != 0) {
    520         return mPlayer->setLooping(loop);
    521     }
    522     return OK;
    523 }
    524 
    525 bool MediaPlayer::isLooping() {
    526     ALOGV("isLooping");
    527     Mutex::Autolock _l(mLock);
    528     if (mPlayer != 0) {
    529         return mLoop;
    530     }
    531     ALOGV("isLooping: no active player");
    532     return false;
    533 }
    534 
    535 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
    536 {
    537     ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
    538     Mutex::Autolock _l(mLock);
    539     mLeftVolume = leftVolume;
    540     mRightVolume = rightVolume;
    541     if (mPlayer != 0) {
    542         return mPlayer->setVolume(leftVolume, rightVolume);
    543     }
    544     return OK;
    545 }
    546 
    547 status_t MediaPlayer::setAudioSessionId(int sessionId)
    548 {
    549     ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
    550     Mutex::Autolock _l(mLock);
    551     if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
    552         ALOGE("setAudioSessionId called in state %d", mCurrentState);
    553         return INVALID_OPERATION;
    554     }
    555     if (sessionId < 0) {
    556         return BAD_VALUE;
    557     }
    558     if (sessionId != mAudioSessionId) {
    559         AudioSystem::releaseAudioSessionId(mAudioSessionId);
    560         AudioSystem::acquireAudioSessionId(sessionId);
    561         mAudioSessionId = sessionId;
    562     }
    563     return NO_ERROR;
    564 }
    565 
    566 int MediaPlayer::getAudioSessionId()
    567 {
    568     Mutex::Autolock _l(mLock);
    569     return mAudioSessionId;
    570 }
    571 
    572 status_t MediaPlayer::setAuxEffectSendLevel(float level)
    573 {
    574     ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
    575     Mutex::Autolock _l(mLock);
    576     mSendLevel = level;
    577     if (mPlayer != 0) {
    578         return mPlayer->setAuxEffectSendLevel(level);
    579     }
    580     return OK;
    581 }
    582 
    583 status_t MediaPlayer::attachAuxEffect(int effectId)
    584 {
    585     ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
    586     Mutex::Autolock _l(mLock);
    587     if (mPlayer == 0 ||
    588         (mCurrentState & MEDIA_PLAYER_IDLE) ||
    589         (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
    590         ALOGE("attachAuxEffect called in state %d", mCurrentState);
    591         return INVALID_OPERATION;
    592     }
    593 
    594     return mPlayer->attachAuxEffect(effectId);
    595 }
    596 
    597 status_t MediaPlayer::setParameter(int key, const Parcel& request)
    598 {
    599     ALOGV("MediaPlayer::setParameter(%d)", key);
    600     Mutex::Autolock _l(mLock);
    601     if (mPlayer != NULL) {
    602         return  mPlayer->setParameter(key, request);
    603     }
    604     ALOGV("setParameter: no active player");
    605     return INVALID_OPERATION;
    606 }
    607 
    608 status_t MediaPlayer::getParameter(int key, Parcel *reply)
    609 {
    610     ALOGV("MediaPlayer::getParameter(%d)", key);
    611     Mutex::Autolock _l(mLock);
    612     if (mPlayer != NULL) {
    613         return  mPlayer->getParameter(key, reply);
    614     }
    615     ALOGV("getParameter: no active player");
    616     return INVALID_OPERATION;
    617 }
    618 
    619 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
    620                                             uint16_t port) {
    621     ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)",
    622             addrString ? addrString : "(null)", port);
    623 
    624     Mutex::Autolock _l(mLock);
    625     if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE))
    626         return INVALID_OPERATION;
    627 
    628     if (NULL == addrString) {
    629         mRetransmitEndpointValid = false;
    630         return OK;
    631     }
    632 
    633     struct in_addr saddr;
    634     if(!inet_aton(addrString, &saddr)) {
    635         return BAD_VALUE;
    636     }
    637 
    638     memset(&mRetransmitEndpoint, 0, sizeof(&mRetransmitEndpoint));
    639     mRetransmitEndpoint.sin_family = AF_INET;
    640     mRetransmitEndpoint.sin_addr   = saddr;
    641     mRetransmitEndpoint.sin_port   = htons(port);
    642     mRetransmitEndpointValid       = true;
    643 
    644     return OK;
    645 }
    646 
    647 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
    648 {
    649     ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
    650     bool send = true;
    651     bool locked = false;
    652 
    653     // TODO: In the future, we might be on the same thread if the app is
    654     // running in the same process as the media server. In that case,
    655     // this will deadlock.
    656     //
    657     // The threadId hack below works around this for the care of prepare
    658     // and seekTo within the same process.
    659     // FIXME: Remember, this is a hack, it's not even a hack that is applied
    660     // consistently for all use-cases, this needs to be revisited.
    661     if (mLockThreadId != getThreadId()) {
    662         mLock.lock();
    663         locked = true;
    664     }
    665 
    666     // Allows calls from JNI in idle state to notify errors
    667     if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
    668         ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
    669         if (locked) mLock.unlock();   // release the lock when done.
    670         return;
    671     }
    672 
    673     switch (msg) {
    674     case MEDIA_NOP: // interface test message
    675         break;
    676     case MEDIA_PREPARED:
    677         ALOGV("prepared");
    678         mCurrentState = MEDIA_PLAYER_PREPARED;
    679         if (mPrepareSync) {
    680             ALOGV("signal application thread");
    681             mPrepareSync = false;
    682             mPrepareStatus = NO_ERROR;
    683             mSignal.signal();
    684         }
    685         break;
    686     case MEDIA_PLAYBACK_COMPLETE:
    687         ALOGV("playback complete");
    688         if (mCurrentState == MEDIA_PLAYER_IDLE) {
    689             ALOGE("playback complete in idle state");
    690         }
    691         if (!mLoop) {
    692             mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
    693         }
    694         break;
    695     case MEDIA_ERROR:
    696         // Always log errors.
    697         // ext1: Media framework error code.
    698         // ext2: Implementation dependant error code.
    699         ALOGE("error (%d, %d)", ext1, ext2);
    700         mCurrentState = MEDIA_PLAYER_STATE_ERROR;
    701         if (mPrepareSync)
    702         {
    703             ALOGV("signal application thread");
    704             mPrepareSync = false;
    705             mPrepareStatus = ext1;
    706             mSignal.signal();
    707             send = false;
    708         }
    709         break;
    710     case MEDIA_INFO:
    711         // ext1: Media framework error code.
    712         // ext2: Implementation dependant error code.
    713         if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
    714             ALOGW("info/warning (%d, %d)", ext1, ext2);
    715         }
    716         break;
    717     case MEDIA_SEEK_COMPLETE:
    718         ALOGV("Received seek complete");
    719         if (mSeekPosition != mCurrentPosition) {
    720             ALOGV("Executing queued seekTo(%d)", mSeekPosition);
    721             mSeekPosition = -1;
    722             seekTo_l(mCurrentPosition);
    723         }
    724         else {
    725             ALOGV("All seeks complete - return to regularly scheduled program");
    726             mCurrentPosition = mSeekPosition = -1;
    727         }
    728         break;
    729     case MEDIA_BUFFERING_UPDATE:
    730         ALOGV("buffering %d", ext1);
    731         break;
    732     case MEDIA_SET_VIDEO_SIZE:
    733         ALOGV("New video size %d x %d", ext1, ext2);
    734         mVideoWidth = ext1;
    735         mVideoHeight = ext2;
    736         break;
    737     case MEDIA_TIMED_TEXT:
    738         ALOGV("Received timed text message");
    739         break;
    740     default:
    741         ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
    742         break;
    743     }
    744 
    745     sp<MediaPlayerListener> listener = mListener;
    746     if (locked) mLock.unlock();
    747 
    748     // this prevents re-entrant calls into client code
    749     if ((listener != 0) && send) {
    750         Mutex::Autolock _l(mNotifyLock);
    751         ALOGV("callback application");
    752         listener->notify(msg, ext1, ext2, obj);
    753         ALOGV("back from callback");
    754     }
    755 }
    756 
    757 /*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
    758 {
    759     ALOGV("decode(%s)", url);
    760     sp<IMemory> p;
    761     const sp<IMediaPlayerService>& service = getMediaPlayerService();
    762     if (service != 0) {
    763         p = service->decode(url, pSampleRate, pNumChannels, pFormat);
    764     } else {
    765         ALOGE("Unable to locate media service");
    766     }
    767     return p;
    768 
    769 }
    770 
    771 void MediaPlayer::died()
    772 {
    773     ALOGV("died");
    774     notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
    775 }
    776 
    777 /*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
    778 {
    779     ALOGV("decode(%d, %lld, %lld)", fd, offset, length);
    780     sp<IMemory> p;
    781     const sp<IMediaPlayerService>& service = getMediaPlayerService();
    782     if (service != 0) {
    783         p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat);
    784     } else {
    785         ALOGE("Unable to locate media service");
    786     }
    787     return p;
    788 
    789 }
    790 
    791 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
    792     if (mPlayer == NULL) {
    793         return NO_INIT;
    794     }
    795     return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
    796 }
    797 
    798 }; // namespace android
    799