这里的实现,可以参照C++设计模式中的工厂模式,:http://blog.csdn.net/wuzhekai1985/article/details/6660462
这里插讲一下厂商定制Player的过程,可以参考NuPlayer的创建过程,通过这个过程,也能够对MediaPlayerFactory类有个比较深入的理解。
(这里需要注意,代码是KK442版本的,FSL在那个版本使用OMXPlayer和GMPlayer来播放,他们是通过OMX Plugin来搭建的一个播放器,在N7.1代码中并没有下面的代码,放在这里只是为了加深理解,和送给有需要定制播放器的同学)
首先来看这个class MediaPlayerFactory,它定义在MediaPlayerFactory.h文件中,里面包含一个IFactory类和其他的功能函数,如注册工厂类函数:registerFactory等等操作。而这个IFactory类,就是每个工厂类的基类。
核心就是这个class MediaPlayerFactory。
每个工厂类都继承自这个IFactory基类,如
class OMXPlayerFactory : public MediaPlayerFactory::IFactory
class StagefrightPlayerFactory : public MediaPlayerFactory::IFactory
class NuPlayerFactory : public MediaPlayerFactory::IFactory
下面来看看这个IFactory类:
class IFactory {
public:
virtual ~IFactory() { }
virtual float scoreFactory(const sp<IMediaPlayer>& client,
const char* url,
float curScore,
const KeyedVector<String8, String8> *headers = NULL) { return 0.0; }
virtual float scoreFactory(const sp<IMediaPlayer>& client,
int fd,
int64_t offset,
int64_t length,
float curScore) { return 0.0; }
virtual float scoreFactory(const sp<IMediaPlayer>& client,
const sp<IStreamSource> &source,
float curScore) { return 0.0; }
virtual sp<MediaPlayerBase> createPlayer() = 0;
};
想要新建一个工厂类其实是很简单的,只需要创建一个工厂类,继承自IFactory类,并实现其中的虚函数(scoreFactory和createPlayer)即可(仿照已经创建好的工厂类,如StagefrightPlayerFactory等等)。最终通过registerFactory_l函数将新建的工厂类注册到MediaPlayerFactory里面。
创建OMXPlayerFactory工厂类与StagefrightPlayerFactory,NuPlayerFactory一样,都需要实现了scoreFactory和createPlayer这几个虚函数。而createPlayer这个虚函数,就是真正的创建player的函数。
怎么注册到MediaPlayerFactory里面呢?就是通过下面这个函数:
void MediaPlayerFactory::registerBuiltinFactories() {
Mutex::Autolock lock_(&sLock);
if (sInitComplete)
return;
#ifdef FSL_GM_PLAYER
registerFactory_l(new OMXPlayerFactory(), OMX_PLAYER);
#endif
registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);
registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER);
registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
sInitComplete = true;
}
android中是通过一个KeyedVector来保存这些player的,在registerFactory_l函数中,通过sFactoryMap.add来将对应的Player添加到这个vector中。
下面来简单说明一下,为什么每一个工厂类都需要去实现scoreFactory和createPlayer两个虚函数。
这个简单的应用是,在MediaPlayerService.cpp中的MediaPlayerService::Client::setDataSource函数中,通过如下的语句:
player_type playerType = MediaPlayerFactory::getPlayerType(this,
fd,
offset,
length);
来获取想要使用的Player类型。
这个函数是MediaPlayerFactory中实现的:
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
int fd,
int64_t offset,
int64_t length) {
GET_PLAYER_TYPE_IMPL(client, fd, offset, length, bestScore);
}
在这个GET_PLAYER_TYPE_IMPL宏中,会去遍历sFactoryMap这个vector中的每一项,在上面我们已经知道,vector中包含各个IFactory,怎么选择最合适的一个IFactory呢?就是通过遍历sFactoryMap这个vector中的每一项,分别调用各个IFactory各自实现的scoreFactory,需要读取文件的内容,判断文件的格式,看这个格式自己是否支持播放,如果支持那么就可以返回1(最高得分),或者返回0(最低得分)。得分最高的一个IFactory就是最合适的。
#define GET_PLAYER_TYPE_IMPL(a...) \
Mutex::Autolock lock_(&sLock); \
\
player_type ret = STAGEFRIGHT_PLAYER; \
float bestScore = 0.0; \
\
for (size_t i = 0; i < sFactoryMap.size(); ++i) { \
\
IFactory* v = sFactoryMap.valueAt(i); \
float thisScore; \
CHECK(v != NULL); \
thisScore = v->scoreFactory(a); \
if (thisScore > bestScore) { \
ret = sFactoryMap.keyAt(i); \
bestScore = thisScore; \
} \
} \
\
if (0.0 == bestScore) { \
ret = getDefaultPlayerType(); \
} \
\
return ret;
那么各个工厂类的得分情况是什么样呢?大致如下:
bestScore = 0.0
StagefrightPlayer : ogg文件的话,得分为1.0, 其他为0.0
NuPlayer : 0.8
OMXPlayer : 1.0
所以,基本情况下都会使用OMXPlayer工厂类。
(这里传入的参数a还有问题,没有研究透彻,a是哪一个参数,是如何根据a判断的?以后有时间的话再深究)
这个文件中有许多种类型的播放器工厂,可以创建出不同的播放器,如果厂商要定制自己的播放器,就可以在这里面做文章,创建自己的工厂类,实现createPlayer方法,然后修改scoreFactory返回得分值为一个较大的数值,在注册进sFactoryMap变量,或者直接修改GET_PLAYER_TYPE宏和getDefaultPlayerType方法的规则,下面也给出了FSL的OMXPlayer的实现过程。
在FSL的代码中,OMXPlayer也只是一个皮包公司,真正做事的是GMPlayer,下面给出这一步步的额实现过程:
(1)mediaserver, a daemon running in android, started by zygote, called: MediaPlayerFactory::createPlayer(playerType, this, notify); (/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp)
同样,在创建Player时,需要根据文件获取对应的playerType后,再去创建,所以先调用
player_type playerType = MediaPlayerFactory::getPlayerType(NULL /* client */,
fd, offset, length);
(2)之后跳转到MediaPlayerFactory::createPlayer中,
MediaPlayerFactory, called: return new OMXPlayer(); (/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp)
函数调用流程如下:
factory = sFactoryMap.valueFor(playerType); //获取得分最高的一个工厂类,此时为OMXPlayer
p = factory->createPlayer(); //调用得分最高工厂类里面的createPlayer函数。
virtual sp<MediaPlayerBase> createPlayer() {
ALOGV(" create OMXPlayer");
return new OMXPlayer();
}
(3)new OMXPlayer()时,就会调用这个类的构造函数,构造函数OMXPlayer::OMXPlayer(int nMediaType),这时就创建好OMXPlayer了,在构造函数中,创建了真正干活的GMPlayer:
called: gm = OMX_GraphManagerCreate(); (/external/fsl_imx_omx/Android/OMXPlayer.cpp)
(4)同样,在OMX_GraphManager* OMX_GraphManagerCreate()函数中,
called: Player = FSL_NEW(GMPlayer, ());, (/external/fsl_imx_omx/OpenMAXIL/src/client/GMPlayerWrapper.cpp)
之后调用
Player->Init();
来完成对这个GMPlayer的初始化,至此,GMPlayer也创建完成了。