概述
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的。
MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap;
class NuPlayerFactory :