MediaPlayer_Analyze-4-MediaPlayerService

MediaPlayer Analyze - MediaPlayerService

Android-Nuplayer播放视频怎么获取对应的extractor

一 初始化

frameworks\av\media\libmedia\mediaplayer.cpp

            // 通过MediaPlayerService调用create
            sp<IMediaPlayer> player(service->create(this, mAudioSessionId));

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client, audio_session_t audioSessionId)
{
    pid_t pid = IPCThreadState::self()->getCallingPid();
    int32_t connId = android_atomic_inc(&mNextConnId);

    sp<Client> c = new Client(
            this, pid, connId, client, audioSessionId,
            IPCThreadState::self()->getCallingUid());

    ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid, IPCThreadState::self()->getCallingUid());

    wp<Client> w = c;
    {
        Mutex::Autolock lock(mLock);
        mClients.add(w);
    }
    return c;
}

MediaPlayerService::Client::Client(
        const sp<MediaPlayerService>& service, pid_t pid,
        int32_t connId, const sp<IMediaPlayerClient>& client,
        audio_session_t audioSessionId, uid_t uid)
{
    ALOGV("Client(%d) constructor", connId);
    mPid = pid;
    mConnId = connId;
    mService = service;
    mClient = client;
    mLoop = false;
    mStatus = NO_INIT;
    mAudioSessionId = audioSessionId;
    mUid = uid;
    mRetransmitEndpointValid = false;
    mAudioAttributes = NULL;
    mListener = new Listener(this);

#if CALLBACK_ANTAGONIZER
    ALOGD("create Antagonizer");
    mAntagonizer = new Antagonizer(mListener);
#endif
}

二 设置Source setDataSource

frameworks\av\media\libmedia\mediaplayer.cpp

            sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
            if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
                (NO_ERROR != player->setDataSource(httpService, url, headers))) {
                player.clear();
            }

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

status_t MediaPlayerService::Client::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers)
{
    // 本地流
    if (strncmp(url, "content://", 10) == 0) {
        ......
    } else { // 网路流
        player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
        // 创建NuPlayerDriver
        sp<MediaPlayerBase> p = setDataSource_pre(playerType);
        if (p == NULL) {
            return NO_INIT;
        }

        return mStatus = setDataSource_post(p, p->setDataSource(httpService, url, headers));
    }
}

2.1 setDataSource_pre(playerType)

sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(player_type playerType)
{
    // create the right type of player
    // 根据后文可知,这里是NuPlayerDriver实例
    sp<MediaPlayerBase> p = createPlayer(playerType);

    // Listen to death of media.extractor service
    ......
    {
        using ::android::hidl::base::V1_0::IBase;
        // Listen to death of OMX service
        ......
        // Listen to death of Codec2 services
        ......
    }

    Mutex::Autolock lock(mLock);
    ......

    if (!p->hardwareOutput()) {
        mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
                mPid, mAudioAttributes, mAudioDeviceUpdatedListener);
        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
    }
    // NuPlayerDriver
    return p;
}

sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
    // determine if we have the right player type
    sp<MediaPlayerBase> p = getPlayer();
    if ((p != NULL) && (p->playerType() != playerType)) {
        ALOGV("delete player");
        p.clear();
    }
    if (p == NULL) {
        // NuPlayerDriver
        p = MediaPlayerFactory::createPlayer(playerType, mListener, mPid);
    }

    if (p != NULL) {
        p->setUID(mUid);
    }

    return p;
}

frameworks\av\media\libmediaplayerservice\MediaPlayerFactory.cpp

sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
        player_type playerType,
        const sp<MediaPlayerBase::Listener> &listener,
        pid_t pid) {
    sp<MediaPlayerBase> p;
    IFactory* factory;
    status_t init_result;
    Mutex::Autolock lock_(&sLock);

    if (sFactoryMap.indexOfKey(playerType) < 0) {
        ALOGE("Failed to create player object of type %d, no registered factory", playerType);
        return p;
    }

    factory = sFactoryMap.valueFor(playerType);
    CHECK(NULL != factory);
    // NuPlayerDriver
    p = factory->createPlayer(pid);

    if (p == NULL) {
        ALOGE("Failed to create player object of type %d, create failed", playerType);
        return p;
    }

    init_result = p->initCheck();
    if (init_result == NO_ERROR) {
        p->setNotifyCallback(listener);
    } else {
        ALOGE("Failed to create player object of type %d, initCheck failed (res = %d)", playerType, init_result);
        p.clear();
    }

    return p;
}

class NuPlayerFactory : public MediaPlayerFactory::IFactory {
  public:
    virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
        ALOGV(" create NuPlayer");
        return new NuPlayerDriver(pid);
    }
};

2.2 setDataSource_post(p, p->setDataSource(httpService, url, headers))

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::setDataSource(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers) {
    ALOGV("setDataSource(%p) url(%s)", this, uriDebugString(url, false).c_str());
    Mutex::Autolock autoLock(mLock);

    if (mState != STATE_IDLE) {
        return INVALID_OPERATION;
    }

    mState = STATE_SET_DATASOURCE_PENDING;
    // 此处的mPlayer是指NuPlayer实例
    mPlayer->setDataSourceAsync(httpService, url, headers);

    while (mState == STATE_SET_DATASOURCE_PENDING) {
        mCondition.wait(mLock);
    }

    return mAsyncResult;
}

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

status_t MediaPlayerService::Client::setDataSource_post(
        const sp<MediaPlayerBase>& p,
        status_t status)
{
    // Set the re-transmission endpoint if one was chosen.
    // resume时重新设置播放位置的地方?
    if (mRetransmitEndpointValid) {
        status = p->setRetransmitEndpoint(&mRetransmitEndpoint);
        if (status != NO_ERROR) {
            ALOGE("setRetransmitEndpoint error: %d", status);
        }
    }

    if (status == OK) {
        Mutex::Autolock lock(mLock);
        mPlayer = p; // 保存player到mPlayer变量
    }
    return status;
}

三 准备 prepare

frameworks\av\media\libmedia\mediaplayer.cpp

        return mPlayer->prepareAsync();

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

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

    return ret;
}

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::prepareAsync() {
    ALOGV("prepareAsync(%p)", this);
    Mutex::Autolock autoLock(mLock);

    switch (mState) {
        case STATE_UNPREPARED:
            mState = STATE_PREPARING;
            mIsAsyncPrepare = true;
            mPlayer->prepareAsync(); // NuPlayer调用另外分析
            return OK;
        case STATE_STOPPED:
            // this is really just paused. handle as seek to start
            mAtEOS = false;
            mState = STATE_STOPPED_AND_PREPARING;
            mIsAsyncPrepare = true;
            mPlayer->seekToAsync(0, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */, true /* needNotify */);
            return OK;
        default:
            return INVALID_OPERATION;
    };
}

四 开始/恢复播放 start/resume

frameworks\av\media\libmedia\mediaplayer.cpp

        ret = mPlayer->start();

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

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

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::start() {
    ALOGV("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
    Mutex::Autolock autoLock(mLock);
    return start_l();
}

status_t NuPlayerDriver::start_l() {
    switch (mState) {
        ......
        case STATE_PAUSED:
        case STATE_STOPPED_AND_PREPARED:
        case STATE_PREPARED:
        {
            mPlayer->start(); // NuPlayer另外分析

            FALLTHROUGH_INTENDED;
        }
        ......
    }

    mState = STATE_RUNNING;

    return OK;
}

五 暂停 pause

frameworks\av\media\libmedia\mediaplayer.cpp

status_t MediaPlayer::pause()
{
    ......
    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
        status_t ret = mPlayer->pause();
        ......
        return ret;
    }
    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
    return INVALID_OPERATION;
}

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

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

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::pause() {
    ......
    switch (mState) {
        ......
        case STATE_RUNNING:
            mState = STATE_PAUSED;
            notifyListener_l(MEDIA_PAUSED);
            mPlayer->pause(); // NuPlayer另外分析
            break;

        default:
            return INVALID_OPERATION;
    }

    return OK;
}

六 停止 stop

frameworks\av\media\libmedia\mediaplayer.cpp

status_t MediaPlayer::stop()
{
    .....
    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
                    MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
        status_t ret = mPlayer->stop();
        .....
    }
    ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
    return INVALID_OPERATION;
}

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

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

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::stop() {
    ......
    switch (mState) {
        case STATE_RUNNING:
            mPlayer->pause(); // NuPlayer另外分析
            FALLTHROUGH_INTENDED;
        ......
    }

    return OK;
}

七 重置 reset

frameworks\av\media\libmedia\mediaplayer.cpp

status_t MediaPlayer::reset()
{
    ALOGV("reset");
    mLockThreadId = getThreadId();
    Mutex::Autolock _l(mLock);
    status_t result = reset_l();
    mLockThreadId = 0;

    return result;
}

status_t MediaPlayer::reset_l()
{
    mLoop = false;
    if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
    mPrepareSync = false;
    if (mPlayer != 0) {
        status_t ret = mPlayer->reset();
        ......
    }
    clear_l();
    return NO_ERROR;
}

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

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

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::reset() {
    ......
    mState = STATE_RESET_IN_PROGRESS;
    mPlayer->resetAsync(); // NuPlayer另外分析
    ......
}

八 释放 release

frameworks\av\media\libmedia\mediaplayer.cpp

void MediaPlayer::disconnect()
{
    ALOGV("disconnect");
    sp<IMediaPlayer> p;
    {
        Mutex::Autolock _l(mLock);
        p = mPlayer;
        mPlayer.clear(); // TODO: clear()函数在哪里? 作用好像是强弱引用的清除?
    }

    if (p != 0) {
        p->disconnect();
    }
}

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

void MediaPlayerService::Client::disconnect()
{
    ALOGV("disconnect(%d) from pid %d", mConnId, mPid);
    // grab local reference and clear main reference to prevent future
    // access to object
    sp<MediaPlayerBase> p;
    {
        Mutex::Autolock l(mLock);
        p = mPlayer;
        mClient.clear();
        mPlayer.clear();
    }

    // clear the notification to prevent callbacks to dead client
    // and reset the player. We assume the player will serialize
    // access to itself if necessary.
    if (p != 0) {
        p->setNotifyCallback(0);
        p->reset(); // 调用NuPlayerDriver的reset()
    }

    {
        Mutex::Autolock l(mLock);
        disconnectNativeWindow_l();
    }

    IPCThreadState::self()->flushCommands();
}

frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp

status_t NuPlayerDriver::reset() {
    ......
    mState = STATE_RESET_IN_PROGRESS;
    mPlayer->resetAsync(); // NuPlayer另外分析
    ......
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值