导航号,我的单页导航
文章目录

前言

之前介绍MediaPlayer的使用,上次写过《MediaPlayer JNI层介绍》,发现很多方法都是都是

# //BpMediaPlayer.prepareAsync()
mPlayer->start()

调用,而且BpMediaPlayer也只是代理而已,真正调用的还是另有其人。

通过百度或谷歌,知道媒体相关的内部跟mediaserver有关系,因此提前介绍一下mediaserver的启动。

正文

涉及文件

system\core\init\init.cpp
frameworks\av\media\mediaserver\mediaserver.rc
frameworks\av\media\mediaserver\main_mediaserver.cpp

frameworks\native\libs\binder\IServiceManager.cpp

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
frameworks\av\media\libmediaplayerservice\MediaPlayerService.h
frameworks\av\media\libmediaplayerservice\MediaPlayerFactory.cpp

mediaserver启动

我们知道,大部分服务都是在init中启动,mediaserver也不例外。Android7之后,mediaserver的启动是放在mediaserver.rc中

# mediaserver.rc
service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

或许你会好奇那啥时候解析mediaserver.rc文件呢?

在Android中,init的启动后会遍历设备中的/system/etc/init目录,而且这个目录中有很多.rc文件

# 部分(随机删除过)
hwservicemanager.rc
mediaserver.rc
servicemanager.rc
statsd.rc
storaged.rc
surfaceflinger.rc
tombstoned.rc
wait_for_keymaster.rc
wifi-events.rc
wificond.rc
# init.cpp
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    //看是否有值,如果有就解析bootscript
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        //解析/system/etc/init目录中的rc
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        //定制rc文件启动
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

所以mediaserver在上面中启动的,对应的代码是main_mediaserver.cpp

main_mediaserver.cpp

代码很少

int main(int argc , char **argv )
{
    //ProcessState初始化
    sp<ProcessState> proc(ProcessState::self());
    //BpServiceManager初始化,其实就是跟ServiceManager搭上关系,用于通信
    sp<IServiceManager> sm(defaultServiceManager());
    InitializeIcuOrDie();
    //MediaPlayerService初始化[重点,本文只关心这块]
    MediaPlayerService::instantiate();
    //ResourceManagerService初始化
    ResourceManagerService::instantiate();
    registerExtensions();
    //启动线程池
    ProcessState::self()->startThreadPool();
    //加入线程池
    IPCThreadState::self()->joinThreadPool();
}

这里不关注服务的添加和其他的哈,只关注MediaPlayerService的启动,后面其他地方需要分析。

进入MediaPlayerService

 MediaPlayerService::instantiate();

MediaPlayerService.cpp

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

至于defaultServiceManager(),这里稍微提一下,哈哈 很多地方都有这个,单例模式,

IServiceManager::defaultServiceManager()
//BpServiceManager,在interface_cast中进行转换的
sp<IServiceManager> defaultServiceManager(){
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

也是单例模式,通过之前文章(《interface_cast简介》)对interface_cast有一定的了解,那就可以得出 defaultServiceManager()放回的就是BpServiceManager,也就是ServiceManager的代理。

addService

addService()等分析MediaPlayerService时在介绍哈,

意思是MediaPlayerService注册ServiceManager进行统一管理,其他地方可通过getService()获取MediaPlayerService。

我们关注MediaPlayerService对象的创建。

new MediaPlayerService();
MediaPlayerService构造函数

进入MediaPlayerService构造函数

MediaPlayerService::MediaPlayerService(){
    mNextConnId = 1;
    MediaPlayerFactory::registerBuiltinFactories();
}

继续看registerBuiltinFactories()

void MediaPlayerFactory::registerBuiltinFactories() {
    Mutex::Autolock lock_(&sLock);
    //第一次为sInitComplete= 0,下面会赋值,也就是后面不会再次进入了。
    if (sInitComplete)
        return;
    //初始化NuPlayerFactory
    IFactory* factory = new NuPlayerFactory();
    //如果注册失败就delete
    if (registerFactory_l(factory, NU_PLAYER) != OK)
        delete factory;
    //下面是TestPlayerFactory
    factory = new TestPlayerFactory();
    if (registerFactory_l(factory, TEST_PLAYER) != OK)
        delete factory;
    sInitComplete = true;
}

重点是NuPlayerFactory对象,然后注册registerFactory_l()

registerFactory_l()
registerFactory_l(factory, NU_PLAYER)

第一个参数是NuPlayerFactory对象,第二个是NU_PLAYER类型(枚举类型)。

enum player_type {
    STAGEFRIGHT_PLAYER = 3,
    NU_PLAYER = 4,
    TEST_PLAYER = 5,
};

进入registerFactory_l()

status_t MediaPlayerFactory::registerFactory_l(IFactory* factory,player_type type) {
    if (NULL == factory) {
        return BAD_VALUE;
    }
	//判断当前类型的factory是否存在
    if (sFactoryMap.indexOfKey(type) >= 0) {
        return ALREADY_EXISTS;
    }
    //通过类型索引添加factory
    if (sFactoryMap.add(type, factory) < 0) {
        return UNKNOWN_ERROR;
    }
    return OK;
}

sFactoryMap集合通过类型进行存储对应的IFactory,因为上面只初始化一次,后面需要直接通过类型获取。

至此,MediaPlayerService的启动和初始化都启动了。

这里顺带说一下NuPlayerFactory哈。

NuPlayerFactory

在MediaPlayerFactory.cpp中定义。

class NuPlayerFactory : public MediaPlayerFactory::IFactory {
  public:
	//略
    virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
		//重点
        return new NuPlayerDriver(pid);
    }
};

部分省略,重点就是createPlayer(),返回的是NuPlayerDriver对象。

小结

  1. init解析mediaserver.rc启动mediaserver

  2. 获取ServiceManager的代理把mediaserver添加到服务列表,以供其他需要的获取

  3. 注册NuPlayerFactory到sFactoryMap,以便需要的获取

参考文章

  1. mediaserver创建

  2. Android P (9.0) 之Init进程源码分析

  3. Android 7.0 init.rc mediaserver

  4. Android MultiMedia框架——mediaserver启动

  5. Binder系列5—注册服务(addService)

© 版权声明
导航号,我的单页导航

暂无评论

暂无评论...