使用FFMpeg 模仿Android MediaPlayer

MediaPlayer--stop()流程

2020-06-17  本文已影响0人  llm_5243

frameworks/base/media/java/android/media/MediaPlayer.java

    /**
     * Stops playback after playback has been started or paused.
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     */
    public void stop() throws IllegalStateException {
        stayAwake(false);
        _stop();
        baseStop();
    }

下面主要分析一般的流程_stop()
frameworks/base/media/jni/android_media_MediaPlayer.cpp

static void
android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
{
    ALOGV("stop");
    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    if (mp == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return;
    }
    process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
}

没有其他逻辑,直接调下一层
frameworks/av/media/libmedia/mediaplayer.cpp

status_t MediaPlayer::stop()
{
    ALOGV("stop");
    Mutex::Autolock _l(mLock);
   //已经是stop状态,则直接返回
    if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
    //判断播放器状态是否符合条件
    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
                    MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
        //调用下一次接口
        status_t ret = mPlayer->stop();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
        } else {
            mCurrentState = MEDIA_PLAYER_STOPPED;
        }
        return ret;
    }
    ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
    return INVALID_OPERATION;
}

先判断player的状态, 处于以下状态才会调用下一层播放器接口 MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE.

mPlayer是mediaplayer 同服务端MediaPlayerService
frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

status_t MediaPlayerService::Client::stop()
{
    ALOGV("[%d] stop", mConnId);
    mMaybeVideoAlive = false;
    sp<MediaPlayerBase> p = getPlayer();
    if (p == 0) return UNKNOWN_ERROR;
    return p->stop();
}

这里直接调用了底层的即可, 如果是原生android 8, 就是调用了Nuplayer 的接口

上一篇 下一篇

猜你喜欢

热点阅读