Qt Mobility videoplayer 源码剖析

Qt Mobility 提供了很多移动平台上所需的特性和功能,例如摄像头服务、地图服务和短信服务等。

Meego中的应用程序大部分都是建立在Qt Mobility API的基础上的。

其中的video模块在底层调用gstreamer,为应用程序提供了一个方便高效的视频播放API,下面是最简单的example。

 

player = new QMediaPlayer; player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3")); widget = new QVideoWidget; player->setVideoOutput(widget); widget->show(); player->play(); 

 

下面是一些主要类的功能:

QMediaServiceProvider

提供媒体服务的抽象类,主要功能是requestService得到QMediaService对象。

 

QMediaService

媒体服务的抽象类,主要功能是requestControl得到QMediaControl对象。

 

QMediaControl

控制媒体的抽象类,包含大量控制媒体的成员函数。

 

QMediaServiceProviderPlugin

所有提供媒体服务的plugin都必须继承这个抽象类。create成员函数用来得到实现后的QMediaService派生类实例的指针,key成员函数用来得到一个QStringList,里面包含这个plugin中能提供的所有媒体服务的id。

注:由于一个plugin可能包含几个QMediaServiceProvider的实现,一个QMediaServiceProvider的实现又可能提供几个QMediaService的实现,一个QMediaService的实现也可能提供几个QMediaControl的实现...所以他们的每个派生类都有一个id来识别。

 

QMediaPlayer 

提供给外部应用程序的主要API,应用程序可以通过调用其成员函数play,setVolume,setPosition等控制视频文件的播放。大部分成员函数都是通过调用QMediaPlayerControl类型指针的方法来实现的。例如:

void QMediaPlayer::pause() { Q_D(QMediaPlayer); if (d->control != 0) d->control->pause(); } 

 

那么这个d->control到底指向什么东东呢?

上面已经说了,QMediaPlayer中成员函数的功能都是通过调用QMediaPlayerControl类型对象的成员函数的方法来实现的。获取QMediaPlayerControl类型对象的指针,是在QMediaPlayer构造函数中实现的:

provider = QMediaServiceProvider::defaultServiceProvider(); ... d -> service = provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER); ... d -> control = qobject_cast(d->service->requestControl(QMediaPlayerControl_iid));

1.其实前两句在source code中是不存在的,而是分别通过默认参数和基类初始化式来实现的,我将其改写,只为了清晰地表示出代码体现出的意义。

2.provider和service分别是QMediaServiceProvider和QMediaService类型指针。

3.Q_MEDIASERVICE_MEDIAPLAYER和QMediaPlayerControl_iid就是上面所说的派生类的id。

 

显然我们可以沿着provider和d->service顺藤摸瓜找到d->control。

首先我们在Qmediaserviceprovider.cpp中找到QMediaServiceProvider::defaultServiceProvider()的定义:

Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider); ... QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider() { return pluginProvider(); } 

Q_GLOBAL_STATIC是Qt常用的一个宏,Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider)代表的含义:pluginProvider是一个无参函数,返回一个指向新建QPluginServiceProvider对象的指针。这也就是说QMediaPlayer构造函数中的provider指向一个新分配的QPluginServiceProvider对象。

 

而QPluginServiceProvider继承QMediaServiceProvider 类,它实现了父类的所有纯虚函数。其中最重要的功能即requestService函数,程序扫描plugin/mediaservice/文件夹内的所有插件文件,并用QPluginLoader载入,获得一个指向插件root component的指针obj,然后用qobject_cast将obj转型为一个QMediaServiceProviderPlugin指针:

QMediaServiceProviderPlugin *plugin = qobject_cast(obj); ... QMediaService *service = plugin->create(key); return service; 

由Qt的插件机制知道,若插件的root component继承自QMediaServiceProviderPlugin,则qobject_cast转型有效,否则结果为0。接着用create就可以得到QMediaService指针service,并将其作为requestService的返回值返回。这个service指向的内容实际上已经是插件文件中继承自QMediaService且id为Q_MEDIASERVICE_MEDIAPLAYER的那个类的实例了。

 

最后,回到QMediaPlayer的构造函数中,既然d -> service 指向插件中QMediaService派生类的实例,那么d -> service -> requestControl( QMediaPlayerControl_iid )也就指向插件中QMediaControl派生类的实例了。

 

你可能感兴趣的:(Qt Mobility videoplayer 源码剖析)