概述 setDataSource是使用MediaPlayer播放音乐文件的重要步骤。这个操作会去创建NuplayerDriver,Nuplayer,然后根据传递的参数(文件信息)创建GenericSource。为后续的prepare或者prepareAsync操作作准备。 类说明 1.NuPlayerFactory:工具类。在本章中,它用于构造NuplayerDriver。 2.MediaPlayerFactory:工具类。在本章中,它用于创建NuPlayerFactory和TestPlayerFactory。 3.NuplayerDriver:它是Nuplayer的wrapper。它继承了MediaPlayerInterface接口,然后MediaPlayerInterface继承了MediaPlayerBase。MediaPlayerService对Nuplayer的访问是通过NuplayerDriver的父类MediaPlayerInterface来实现的。所以它相当于一个中转站。 4.Nuplayer::GenericSource:解析模块。从extractor中读取解封装之后的文件数据。它是Nuplayer::Source的子类。 5.Nuplayer::Decoder:解码模块。在播放的时候会调用MediaCodec去获取编解码列表,选择合适解码库。 6.MediaCodec:Decoder的代工。根据Decoder的要求,去MediaCodecList中查找解码器信息,然后选择合适的解码库。负责跟ACodec进行数据交互。 7.MediaCodecList:用于获取编解码信息列表,这些信息是从OmxStore那里获取的。OmxStore是一个HAL server(也就是hidl的server端)。在media.codec进程中,会注册OmxStore和Omx服务,OmxStore先把解码器信息解析出来,然后保存在自己的成员变量中。 8.Nuplayer:这个类主要是扮演操控者的角色,根据NuplayerDriver的指令去控制Decoder和Source,也就是协调解析和解码的工作。 9.ACodec:主要负责解码相关工作。通过IOMXNode去控制解码器:设置参数,获取参数等。将从ACodecBufferChannel获取的解析之后的文件数据送给解析器。 10.MediaPlayerService::Client:它继承于BnMediaPlayer,用于上层对音乐播放流程的控制。 总bouml时序图
我把setDataSource,prepareAsync,start这几个重要步骤放在同一张时序图里面。目的是为了对nuplay的工作流程有一个整体上的认识。这一节只讲setDataSource流程,所以只需看setDataSource那一部分就行了。 时序图说明 Nuplayer、Decoder、GenericSource中有些控制块是有颜色的。因为这三个类都有消息发送处理这种异步机制,所以为了更好的表示时序图,我把消息的源和目标都标成同样的颜色。 setDataSource过程可以分解为下面几个子流程: 1.创建NuPlayerDriver和NuPlayer。返回NuPlayerDriver的父类指针MediaPlayerBase指针给MediaPlayerService::Client。 2.通过NuPlayerDriver提供的setDataSource以异步的方式去创建GenericSource,然后把文件描述符等信息保存到GenericSource中。 3.设置NuPlayerDriver状态,为下一个步骤prepareAsync(下一节会讲)做准备。 下面对这三点进行展开讲述 1.创建NuPlayerDriver和NuPlayer MediaPlayerService::Client在创建NuPlayerDriver的时候并不是直接new NuPlayerDriver,而是通过NuPlayerFactory这一个工具类来创建的。这个类只是让Client多了一个选择而已。在android 6.0中有三个选择StagefrightPlayerFactory、NuPlayerFactory、TestPlayerFactory。 但是高版本已经把StagefrightPlayerFactory去掉了,也就是说AwesomePlayer已经在高版本中消失了。创建出来的NuplayerDriver保存在全局变量sFactoryMap中,并且设置它的索引key为NU_PLAYER=4。在创建的时候会传递pid给NuPlayerDriver,这个pid是调用者的pid。比如我用安卓原生的music播放音乐,那这个pid就是com.android.music的。 创建NuPlayerDriver的时候会去创建NuPlayer,并保存为自己的成员变量mPlayer。由于NuPlayer是继承于AHandler,所以还得给它new 一个ALooper提供一个循环。这个过程没啥操作,这里就不赘述了。 2.创建GenericSource NuPlayerDriver是以异步的方式设置数据源的。 从总时序图中,可以看出new GenericSource之后的source->setDataSource仅仅是将文件描述符等信息保存到GenericSource中。由于这里的设置源是异步调用,所以需要NuPlayer给NuPlayerDriver答复。 可以看出setDataSource这个操作仅仅是设置数据源信息而已,并没有去加载解析器和解码器。在notifySetDataSourceCompleted中有一个重要的操作就是:当返回的状态OK的时候会设置mState的状态为STATE_UNPREPARED,也就是未准备的状态。所以从这里我们也可以看出下一个操作就是prepare操作了 原文链接:https://blog.csdn.net/qq_27136111/java/article/details/94594673 |
|