上一节谈到QMediaPlayer构造函数如何使用到插件中的类,先回顾一下QMediaPlayer构造函数
provider = QMediaServiceProvider::defaultServiceProvider(); ... d -> service = provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER); ... d -> control = qobject_cast
我们现在已经知道d -> service指向插件中的一个QMediaService派生类的实例,所以我们开始分析插件的源代码。
首先我们找到插件的root component(cpp文件中包含Q_EXPORT_PLUGIN2的那个类)
#ifndef QGSTREAMERSERVICEPLUGIN_H #define QGSTREAMERSERVICEPLUGIN_H #include
可以看出这个插件实现了两个接口,其中QMediaServiceProviderPlugin是提供视频播放服务的接口。它的成员函数create返回一个QMediaService指针,就是QMediaService构造函数d->service的candidate(至于为什么是candidate,是因为源代码还要对这个指针进行一些验证和处理)。下面是create()的源码:
QMediaService* QGstreamerServicePlugin::create(const QString &key) { static bool initialized = false; if (!initialized) { initialized = true; gst_init(NULL, NULL); } #ifdef QMEDIA_GSTREAMER_PLAYER if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) return new QGstreamerPlayerService; #endif #ifdef QMEDIA_GSTREAMER_CAMERABIN if (key == QLatin1String(Q_MEDIASERVICE_CAMERA) && CameraBinService::isCameraBinAvailable()) return new CameraBinService(key); #endif #ifdef QMEDIA_GSTREAMER_CAPTURE if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) return new QGstreamerCaptureService(key); if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) return new QGstreamerCaptureService(key); #endif qWarning() << "Gstreamer service plugin: unsupported key:" << key; return 0; }
(gst_init是GStreamer库的初始化函数,它会对 GStreamer 库做一些必要的初始化工作)
这些宏都是不同服务的id,create根据参数的不同返回不同的QMediaService指针。例如我们需要id为Q_MEDIASERVICE_MEDIAPLAYER的实例,create即创建一个QGstreamerPlayerService实例,并返回其指针。
考察QGstreamerPlayerService类,requestControl的源码:
QMediaControl *QGstreamerPlayerService::requestControl(const char *name) { if (qstrcmp(name,QMediaPlayerControl_iid) == 0) return m_control; if (qstrcmp(name,QMetaDataReaderControl_iid) == 0) return m_metaData; if (qstrcmp(name,QMediaStreamsControl_iid) == 0) return m_streamsControl; if (!m_videoOutput) { if (qstrcmp(name, QVideoWidgetControl_iid) == 0) m_videoOutput = m_videoWidget; else if (qstrcmp(name, QVideoRendererControl_iid) == 0) m_videoOutput = m_videoRenderer; else if (qstrcmp(name, QVideoWindowControl_iid) == 0) m_videoOutput = m_videoWindow; if (m_videoOutput) { m_control->setVideoOutput(m_videoOutput); return m_videoOutput; } } return 0; }
QMediaPlayerControl_iid是我们需要的控制类的id,返回值m_control指向一个新分配的QGstreamerPlayerControl实例,于是d->control指向的对象终于明朗了。要想知道如果控制视频的播放,我们只需要分析QGstreamerPlayerControl类的代码。