Android 12(S) MultiMedia Learning(四)MediaPlayerService


getMediaPlayerService方法获取到的是media.player服务

IMediaDeathNotifier::getMediaPlayerService()
{
        // ...... 
        sp sm = defaultServiceManager();
        sp binder;
        binder = sm->getService(String16("media.player"));
        sMediaPlayerService = interface_cast(binder);
        // ......
        return sMediaPlayerService;
}

MediaPlayerService 和 MediaPlayerFactory的主要代码位置:

http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp 

http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp

1、服务注册

main_mediaserver 中会调用instantiate方法将media.player服务注册到servicemanager当中

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

注册时会实例化一个MediaPlayerService对象,构造函数中会调用 MediaPlayerFactory::registerBuiltinFactories 来初始化播放器工厂

// MediaPlayerService
MediaPlayerService::MediaPlayerService()
{
    ALOGV("MediaPlayerService created");
    mNextConnId = 1;

    MediaPlayerFactory::registerBuiltinFactories();
}

// MediaPlayerFactory
void MediaPlayerFactory::registerBuiltinFactories() {
    Mutex::Autolock lock_(&sLock);

    if (sInitComplete)
        return;

    IFactory* factory = new NuPlayerFactory();
    if (registerFactory_l(factory, NU_PLAYER) != OK)
        delete factory;
    factory = new TestPlayerFactory();
    if (registerFactory_l(factory, TEST_PLAYER) != OK)
        delete factory;

    sInitComplete = true;
}

2、服务使用

2.1、create

create方法中实例化了一个Client对象,并且把这个对象返回给了native mediaplayer,同时创建的Client对象会被记录到mClient这个列表当中

sp MediaPlayerService::create(const sp& client,
        audio_session_t audioSessionId, const AttributionSourceState& attributionSource)
{
    // ......
    sp c = new Client(
            this, verifiedAttributionSource, connId, client, audioSessionId);
    // ......
    wp w = c;
    {
        Mutex::Autolock lock(mLock);
        mClients.add(w);
    }
    return c;
}

 

3、MediaPlayerService::Client

client是MediaPlayerService的一个内部类,继承于BnMediaPlayer,既然是个binder对象,所以可以使用binder service来传递给native mediaplayer。

/**********************************************************
*     Native mediaplayer               ->          MediaPlayerService::Client
*  setDataSource                                 构造函数  setDataSource
*  setVideoSurfaceTexture                        setVideoSurfaceTexture
*  prepareAsync                                  setAudioStreamType  prepareAsync
*  start                                         setLooping  setVolume  start
**********************************************************/

3.1、构造函数

构造函数主要初始化了成员变量,这里看到第四个参数传来的是native mediaPlayer对象,主要是要调用notify方法,回调上层postEventFromNative函数

MediaPlayerService::Client::Client(
        const sp& service, const AttributionSourceState& attributionSource,
        int32_t connId, const sp& client,
        audio_session_t audioSessionId)
        : mAttributionSource(attributionSource)
{
    ALOGV("Client(%d) constructor", connId);
    mConnId = connId;
    mService = service;
    mClient = client;
    mLoop = false;
    mStatus = NO_INIT;
    mAudioSessionId = audioSessionId;
    mRetransmitEndpointValid = false;
    mAudioAttributes = NULL;
    mListener = new Listener(this);

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

3.2、setDataSource

这里干了两件事:

a. MediaPlayerFactory::getPlayerType 从MediaPlayerFactory中获取播放器的类型

b. setDataSource_pre 根据类型来创建播放器

c. setDataSource 调用创建的MediaPlayerBase的setDataSource方法

status_t MediaPlayerService::Client::setDataSource(
        const sp &httpService,
        const char *url,
        const KeyedVector *headers)
{
    ALOGV("setDataSource(%s)", url);
    if (url == NULL)
        return UNKNOWN_ERROR;

    if ((strncmp(url, "http://", 7) == 0) ||
        (strncmp(url, "https://", 8) == 0) ||
        (strncmp(url, "rtsp://", 7) == 0)) {
        if (!checkPermission("android.permission.INTERNET")) {
            return PERMISSION_DENIED;
        }
    }

    if (strncmp(url, "content://", 10) == 0) {
        // get a filedescriptor for the content Uri and
        // pass it to the setDataSource(fd) method

        String16 url16(url);
        int fd = android::openContentProviderFile(url16);
        if (fd < 0)
        {
            ALOGE("Couldn't open fd for %s", url);
            return UNKNOWN_ERROR;
        }
        status_t status = setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
        close(fd);
        return mStatus = status;
    } else {
        player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
        sp p = setDataSource_pre(playerType);
        if (p == NULL) {
            return NO_INIT;
        }

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

3.3、setVideoSurfaceTexture

这里做的事情目前还不太了解是做什么用的,但是调用了MediaPlayerBase的setVideoSurfaceTexture方法

status_t MediaPlayerService::Client::setVideoSurfaceTexture(
        const sp& bufferProducer)
{
    ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());
    sp p = getPlayer();
    if (p == 0) return UNKNOWN_ERROR;

    sp binder(IInterface::asBinder(bufferProducer));
    if (mConnectedWindowBinder == binder) {
        return OK;
    }

    sp anw;
    if (bufferProducer != NULL) {
        anw = new Surface(bufferProducer, true /* controlledByApp */);
        status_t err = nativeWindowConnect(anw.get(), "setVideoSurfaceTexture");

        if (err != OK) {
            ALOGE("setVideoSurfaceTexture failed: %d", err);
            // Note that we must do the reset before disconnecting from the ANW.
            // Otherwise queue/dequeue calls could be made on the disconnected
            // ANW, which may result in errors.
            reset();

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

            return err;
        }
    }

    // Note that we must set the player's new GraphicBufferProducer before
    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
    // on the disconnected ANW, which may result in errors.
    status_t err = p->setVideoSurfaceTexture(bufferProducer);

    mLock.lock();
    disconnectNativeWindow_l();

    if (err == OK) {
        mConnectedWindow = anw;
        mConnectedWindowBinder = binder;
        mLock.unlock();
    } else {
        mLock.unlock();
        status_t err = nativeWindowDisconnect(
                anw.get(), "disconnectNativeWindow");

        if (err != OK) {
            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
                    strerror(-err), err);
        }
    }

    return err;
}

3.4、setAudioStreamType

setAudioStreamType 操作的是AudioOutput对象,暂时不研究audio部分

status_t MediaPlayerService::Client::setAudioStreamType(audio_stream_type_t type)
{
    ALOGV("[%d] setAudioStreamType(%d)", mConnId, type);
    // TODO: for hardware output, call player instead
    Mutex::Autolock l(mLock);
    if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
    return NO_ERROR;
}

3.5、prepareAsync

调用了MediaPlayerBase的prepareAsync方法

status_t MediaPlayerService::Client::prepareAsync()
{
    ALOGV("[%d] prepareAsync", mConnId);
    sp p = getPlayer();
    if (p == 0) return UNKNOWN_ERROR;
    status_t ret = p->prepareAsync();
#if CALLBACK_ANTAGONIZER
    ALOGD("start Antagonizer");
    if (ret == NO_ERROR) mAntagonizer->start();
#endif
    return ret;
}

3.6、start

调用了MediaPlayerBase的start方法

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

看到这里明白了mediaPlayer的调用顺序

mediaplayer java   -->     JNI    -->    mediaPlayer native     -->     mediaplayerservice (create player)     -->     NuplayerDriver

上层收到MEDIA_PREPARED事件的过程

 接下来一节将会学习NuPlayer

相关