第二章:第一节:PVPlayer的实现方式

本文深入剖析了Android系统中多媒体播放的架构设计,从Mediaserver进程中的MediaPlayerService实例化开始,逐步介绍了如何通过工厂模式创建不同的播放器实例,如PVPlayer,并详细解释了PVPlayer与PVPlayerDriver之间的交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于opencore下多媒体播放,在mediaserver进程里面只有一行代码:

MediaPlayerService::instantiate();

这行代码的作用是初始化一个MediaPlayerService类的实例,并接把他加入到系统的serveceManager中。

 

MediaPlayerService的具体实现在文件夹frameworks/base/media/libmediaplayerservice中。

 

在涉及到要播放一个具体的媒体文件时,调用的函数是:

MediaPlayerService::create,这个new 了一个Client 并且函数将它返回为sp<IMediaPlayer>。

 

Client对象什么在文件MediaPlayerService.h中,并且是private类,说明它只被MediaPlayerService对象使用。

Client对象继承自BnMediaPlayer,而BnMediaPlaye又继承自BnInterface<IMediaPlayer>,看来是用来响应binder的IPC的函数。

 

而IMediaPlayer又是何许东东。

IMediaPlayer.cpp在文件夹frameworks/base/media/中,

而IMediaPlayer.h 在文件夹frameworks/base/include/media中。

IMediaPlayer.h中声明了一个IMediaPlayer的类,而它的函数又都是virtual,一看就是用来申明接口的。

 

 

MediaPlayerService::create函数调用以后,马上调用Client:setDataSource,其实现在MediaPlayerService.cpp中,

代码如下:

 

 

 

注意这行代码:sp<MediaPlayerBase> p = createPlayer(playerType);

他的作用是根据不同的playerType来创建player实例,我们这里主要关注PVPlayer。

 

说了这么多,终于到达opencore那一层了。

 

有时候会觉得android这样的设计实在太复杂了,调用起来太麻烦,直接实现一个IMediaPlayer的类不就完了吗。

但是仔细一样,androide的这种设计方式其实有它在扩展性和可维护性上才这样做的。

 

说到底就是一句话,降低模块间的耦合性。

 

涉及到具体的操作,都是通过实现一个接口类来实现,这样具体的实例在创建的时候就可以通过工厂模式来简单的进行扩展。

 

例如上面所提到的createPlayer(playerType)这个函数,当你需要添加自己的特殊格式的播放器的时候,就不用来改它本来的代码,而只用在createPlayer(playerType)的实现下面几行代码:

 

非常方便,而这种扩展性和是由接口和实现的分离带来的,createPlayer 返回的是sp<MediaPlayerBase>类,而去看这个类的代码,发现这个类都是由virtual函数组成的,当你要实现具体实现时候,你可以继承它,然后写好这些virtual函数的实现。

 

扯远了。设计模式的厉害,可能需要我花整个的职业生涯来体会。

 

废话不多说,让我们来看PVPlayer的实现,我刚才说过,PVPlayer才是opencore真正的内容。

 

PVPlayer的申明在frameworks/base/include/media/PVPlayer.h中,而实现在external/opencore/android/playerdriver.cpp。

 

为什么要这样做?我不懂,我猜测还是为了实现和接口的分离,只不过这次的分离就只能简单的通过把头文件和实现文件放到不同文件夹下来实现。

 

OK,那么让我们来看看PVPlayer是干嘛的。

 

PVPlayer继承自MediaPlayerInterface,而MediaPlayerInterface是Opencore对媒体播放的抽象接口的声明类。

 

那么我们去看看PVPlayer的各个接口的实现吧。

 

 

 

PVPlayer的很多借口都是通过向它的成员mPlayerDriver发送命令来实现,而mPlayerDriver通过调用mPVPlayer的sendEvent函数来告诉PVPlayer,命令是否执行成功了。PlayerDriver是PVPlayer的一个内部成员,它是PVPlayer的命令执行者。

 

sendEvent的实现如下:

 

 

MediaPlayerBase::sendEvent的实现如下:

 

mNotify是MediaPlayerBase的一个成员变量,它是一个函数指针,原型如下:

 

这个成员变量在调用createPlayer的时候就调用setNotifyCallback来赋值的。

所以,可以看到,底层的事件会一层一层的往上调用,直至返回给用户层。

 

这里涉及到2个设计模式:

命令模式和观察者模式。

 

这两个模式都是设计模式中的基本模式之一,功能强大,逻辑清晰。具体的内容不是本文的重点,在此略过。

 

下一节介绍PVPlayer是怎样通过PVPlayerDriver来完成那些接口的

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值