summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Pasion <jerome.pasion@digia.com>2012-11-02 15:40:51 +0100
committerJerome Pasion <jerome.pasion@digia.com>2012-11-02 15:41:00 +0100
commita5947906d3aac7ec2f21a9621f7ad67a761a4560 (patch)
treeb67a28ecfdf01a0ca71ec51e00ee45ee1491eeaf
parent962e99534d8955ae6c3c3524c5005f518b4e01bc (diff)
parent79f585b9e90c311f2c7b905426318d345b1bf641 (diff)
downloadqtmultimedia-a5947906d3aac7ec2f21a9621f7ad67a761a4560.tar.gz
Merge branch 'master' of ssh://codereview.qt-project.org/qt/qtmultimedia into newdocs
Change-Id: Idb607da32f80784d94556443be6740c6d7223411
-rw-r--r--qtmultimedia.pro6
-rw-r--r--src/imports/audioengine/qdeclarative_audioengine_p.cpp2
-rw-r--r--src/imports/audioengine/qdeclarative_sound_p.cpp2
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_window.cpp6
-rw-r--r--src/multimedia/audio/qaudio.h2
-rw-r--r--src/multimedia/audio/qaudio_mac_p.h2
-rw-r--r--src/multimedia/audio/qaudiobuffer.h2
-rw-r--r--src/multimedia/audio/qaudiobuffer_p.h2
-rw-r--r--src/multimedia/audio/qaudiodecoder.h2
-rw-r--r--src/multimedia/audio/qaudiodevicefactory_p.h2
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo.h2
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.h2
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_mac_p.h2
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp29
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.h2
-rw-r--r--src/multimedia/audio/qaudioformat.h2
-rw-r--r--src/multimedia/audio/qaudioinput.h2
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.h2
-rw-r--r--src/multimedia/audio/qaudioinput_mac_p.h2
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.h6
-rw-r--r--src/multimedia/audio/qaudiooutput.h2
-rw-r--r--src/multimedia/audio/qaudiooutput_alsa_p.h2
-rw-r--r--src/multimedia/audio/qaudiooutput_mac_p.h2
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.h6
-rw-r--r--src/multimedia/audio/qaudioprobe.h2
-rw-r--r--src/multimedia/audio/qaudiosystem.h2
-rw-r--r--src/multimedia/audio/qaudiosystemplugin.h2
-rw-r--r--src/multimedia/audio/qsamplecache_p.h2
-rw-r--r--src/multimedia/audio/qsound.h2
-rw-r--r--src/multimedia/audio/qsoundeffect.h2
-rw-r--r--src/multimedia/audio/qsoundeffect_pulse_p.h2
-rw-r--r--src/multimedia/audio/qsoundeffect_qaudio_p.h2
-rw-r--r--src/multimedia/audio/qwavedecoder_p.h2
-rw-r--r--src/multimedia/camera/qcamera.h2
-rw-r--r--src/multimedia/camera/qcameraexposure.h2
-rw-r--r--src/multimedia/camera/qcamerafocus.h2
-rw-r--r--src/multimedia/camera/qcameraimagecapture.h2
-rw-r--r--src/multimedia/camera/qcameraimageprocessing.h2
-rw-r--r--src/multimedia/controls/qaudiodecodercontrol.h2
-rw-r--r--src/multimedia/controls/qaudioencodersettingscontrol.h2
-rw-r--r--src/multimedia/controls/qaudioinputselectorcontrol.h2
-rw-r--r--src/multimedia/controls/qaudiooutputselectorcontrol.h2
-rw-r--r--src/multimedia/controls/qcameracapturebufferformatcontrol.h2
-rw-r--r--src/multimedia/controls/qcameracapturedestinationcontrol.h2
-rw-r--r--src/multimedia/controls/qcameracontrol.h2
-rw-r--r--src/multimedia/controls/qcameraexposurecontrol.h2
-rw-r--r--src/multimedia/controls/qcamerafeedbackcontrol.h2
-rw-r--r--src/multimedia/controls/qcameraflashcontrol.h2
-rw-r--r--src/multimedia/controls/qcamerafocuscontrol.h2
-rw-r--r--src/multimedia/controls/qcameraimagecapturecontrol.h2
-rw-r--r--src/multimedia/controls/qcameraimageprocessingcontrol.h2
-rw-r--r--src/multimedia/controls/qcameralockscontrol.h2
-rw-r--r--src/multimedia/controls/qcameraviewfindersettingscontrol.h2
-rw-r--r--src/multimedia/controls/qcamerazoomcontrol.h2
-rw-r--r--src/multimedia/controls/qimageencodercontrol.h2
-rw-r--r--src/multimedia/controls/qmediaaudioprobecontrol.h2
-rw-r--r--src/multimedia/controls/qmediaavailabilitycontrol.h2
-rw-r--r--src/multimedia/controls/qmediacontainercontrol.h2
-rw-r--r--src/multimedia/controls/qmediagaplessplaybackcontrol.h2
-rw-r--r--src/multimedia/controls/qmedianetworkaccesscontrol.h2
-rw-r--r--src/multimedia/controls/qmediaplayercontrol.h2
-rw-r--r--src/multimedia/controls/qmediaplaylistcontrol_p.h2
-rw-r--r--src/multimedia/controls/qmediaplaylistsourcecontrol_p.h2
-rw-r--r--src/multimedia/controls/qmediarecordercontrol.h2
-rw-r--r--src/multimedia/controls/qmediastreamscontrol.h2
-rw-r--r--src/multimedia/controls/qmediavideoprobecontrol.h2
-rw-r--r--src/multimedia/controls/qmetadatareadercontrol.h2
-rw-r--r--src/multimedia/controls/qmetadatawritercontrol.h2
-rw-r--r--src/multimedia/controls/qradiodatacontrol.h2
-rw-r--r--src/multimedia/controls/qradiotunercontrol.h2
-rw-r--r--src/multimedia/controls/qvideodeviceselectorcontrol.h2
-rw-r--r--src/multimedia/controls/qvideoencodersettingscontrol.h2
-rw-r--r--src/multimedia/controls/qvideorenderercontrol.h2
-rw-r--r--src/multimedia/controls/qvideowindowcontrol.h2
-rw-r--r--src/multimedia/doc/qtmultimedia.qdocconf5
-rw-r--r--src/multimedia/playback/qmediacontent.h2
-rw-r--r--src/multimedia/playback/qmedianetworkplaylistprovider_p.h2
-rw-r--r--src/multimedia/playback/qmediaplayer.h2
-rw-r--r--src/multimedia/playback/qmediaplaylist.h2
-rw-r--r--src/multimedia/playback/qmediaplaylist_p.h2
-rw-r--r--src/multimedia/playback/qmediaplaylistioplugin_p.h2
-rw-r--r--src/multimedia/playback/qmediaplaylistnavigator_p.h2
-rw-r--r--src/multimedia/playback/qmediaplaylistprovider_p.h2
-rw-r--r--src/multimedia/playback/qmediaresource.h2
-rw-r--r--src/multimedia/qmediabindableinterface.h2
-rw-r--r--src/multimedia/qmediacontrol.h2
-rw-r--r--src/multimedia/qmediacontrol_p.h2
-rw-r--r--src/multimedia/qmediaenumdebug.h2
-rw-r--r--src/multimedia/qmediaobject.h2
-rw-r--r--src/multimedia/qmediaobject_p.h2
-rw-r--r--src/multimedia/qmediapluginloader_p.h2
-rw-r--r--src/multimedia/qmediaresourcepolicy_p.h2
-rw-r--r--src/multimedia/qmediaresourcepolicyplugin_p.h2
-rw-r--r--src/multimedia/qmediaresourceset_p.h2
-rw-r--r--src/multimedia/qmediaservice.h2
-rw-r--r--src/multimedia/qmediaservice_p.h2
-rw-r--r--src/multimedia/qmediaserviceprovider_p.h2
-rw-r--r--src/multimedia/qmediaserviceproviderplugin.h2
-rw-r--r--src/multimedia/qmediatimerange.h2
-rw-r--r--src/multimedia/qtmedianamespace.h2
-rw-r--r--src/multimedia/qtmultimediadefs.h2
-rw-r--r--src/multimedia/qtmultimediaquicktools_headers/qsgvideonode_p.h2
-rw-r--r--src/multimedia/radio/qradiodata.h2
-rw-r--r--src/multimedia/radio/qradiotuner.h2
-rw-r--r--src/multimedia/recording/qaudiorecorder.h2
-rw-r--r--src/multimedia/recording/qmediaencodersettings.h2
-rw-r--r--src/multimedia/recording/qmediarecorder.cpp3
-rw-r--r--src/multimedia/recording/qmediarecorder.h2
-rw-r--r--src/multimedia/video/qabstractvideobuffer.h2
-rw-r--r--src/multimedia/video/qabstractvideobuffer_p.h2
-rw-r--r--src/multimedia/video/qabstractvideosurface.h2
-rw-r--r--src/multimedia/video/qimagevideobuffer_p.h2
-rw-r--r--src/multimedia/video/qmemoryvideobuffer_p.h2
-rw-r--r--src/multimedia/video/qvideoframe.h2
-rw-r--r--src/multimedia/video/qvideoprobe.h2
-rw-r--r--src/multimedia/video/qvideosurfaceformat.h2
-rw-r--r--src/multimedia/video/qvideosurfaceoutput_p.h2
-rw-r--r--src/multimediawidgets/qcameraviewfinder.h2
-rw-r--r--src/multimediawidgets/qeglimagetexturesurface_p.h2
-rw-r--r--src/multimediawidgets/qgraphicsvideoitem.h2
-rw-r--r--src/multimediawidgets/qpaintervideosurface_mac_p.h2
-rw-r--r--src/multimediawidgets/qpaintervideosurface_p.h2
-rw-r--r--src/multimediawidgets/qtmultimediawidgetdefs.h2
-rw-r--r--src/multimediawidgets/qvideowidget.cpp2
-rw-r--r--src/multimediawidgets/qvideowidget.h2
-rw-r--r--src/multimediawidgets/qvideowidget_p.h2
-rw-r--r--src/multimediawidgets/qvideowidgetcontrol.h2
-rw-r--r--src/plugins/avfoundation/avfoundation.pro3
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfdisplaylink.h84
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm159
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayer.json3
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h101
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm186
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h76
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm157
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h72
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm117
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h79
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm109
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h181
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm832
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h94
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm258
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideooutput.h62
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideooutput.mm (renamed from tests/auto/cmake/test_modules/main.cpp)16
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h92
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm213
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidget.h86
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidget.mm201
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h108
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm219
-rw-r--r--src/plugins/avfoundation/mediaplayer/mediaplayer.pro56
-rw-r--r--src/plugins/directshow/camera/camera.pri1
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp79
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h7
-rw-r--r--src/plugins/qt7/qt7movierenderer.mm2
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.h5
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.mm42
-rw-r--r--src/plugins/wmf/wmf.pro3
-rw-r--r--tests/auto/cmake/CMakeLists.txt7
-rw-r--r--tests/auto/cmake/test_modules/CMakeLists.txt28
-rw-r--r--tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp2
-rw-r--r--tests/auto/integration/qsoundeffect/qsoundeffect.pro3
-rw-r--r--tests/auto/unit/qmultimedia_common/mockaudiodecodercontrol.h2
164 files changed, 3719 insertions, 327 deletions
diff --git a/qtmultimedia.pro b/qtmultimedia.pro
index 0b7712f04..aeb97464d 100644
--- a/qtmultimedia.pro
+++ b/qtmultimedia.pro
@@ -6,6 +6,8 @@ win32 {
qtCompileTest(wmp)
qtCompileTest(wmf)
qtCompileTest(evr)
+} else:mac {
+ qtCompileTest(avfoundation)
} else {
qtCompileTest(alsa)
qtCompileTest(pulseaudio)
@@ -18,9 +20,5 @@ win32 {
qtCompileTest(xvideo)
}
-mac {
- qtCompileTest(avfoundation)
-}
-
load(qt_parts)
diff --git a/src/imports/audioengine/qdeclarative_audioengine_p.cpp b/src/imports/audioengine/qdeclarative_audioengine_p.cpp
index c47a711df..5c6848fd2 100644
--- a/src/imports/audioengine/qdeclarative_audioengine_p.cpp
+++ b/src/imports/audioengine/qdeclarative_audioengine_p.cpp
@@ -404,7 +404,7 @@ void QDeclarativeAudioEngine::appendFunction(QQmlListProperty<QObject> *property
QQmlListProperty<QObject> QDeclarativeAudioEngine::bank()
{
- return QQmlListProperty<QObject>(this, 0, appendFunction);
+ return QQmlListProperty<QObject>(this, 0, appendFunction, 0, 0, 0);
}
/*!
diff --git a/src/imports/audioengine/qdeclarative_sound_p.cpp b/src/imports/audioengine/qdeclarative_sound_p.cpp
index 441453fc7..87a0ccce2 100644
--- a/src/imports/audioengine/qdeclarative_sound_p.cpp
+++ b/src/imports/audioengine/qdeclarative_sound_p.cpp
@@ -363,7 +363,7 @@ void QDeclarativeSound::setCategoryObject(QDeclarativeAudioCategory *categoryObj
QQmlListProperty<QDeclarativePlayVariation> QDeclarativeSound::playVariationlist()
{
- return QQmlListProperty<QDeclarativePlayVariation>(this, 0, appendFunction);
+ return QQmlListProperty<QDeclarativePlayVariation>(this, 0, appendFunction, 0, 0, 0);
}
QList<QDeclarativePlayVariation*>& QDeclarativeSound::playlist()
diff --git a/src/imports/multimedia/qdeclarativevideooutput_window.cpp b/src/imports/multimedia/qdeclarativevideooutput_window.cpp
index 0fe32b399..527c08908 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_window.cpp
+++ b/src/imports/multimedia/qdeclarativevideooutput_window.cpp
@@ -41,7 +41,7 @@
#include "qdeclarativevideooutput_window_p.h"
#include "qdeclarativevideooutput_p.h"
-#include <QtQuick/qquickcanvas.h>
+#include <QtQuick/qquickwindow.h>
#include <QtMultimedia/qmediaservice.h>
#include <QtMultimedia/qvideowindowcontrol.h>
@@ -63,8 +63,8 @@ bool QDeclarativeVideoWindowBackend::init(QMediaService *service)
{
if (QMediaControl *control = service->requestControl(QVideoWindowControl_iid)) {
if ((m_videoWindowControl = qobject_cast<QVideoWindowControl *>(control))) {
- if (q->canvas())
- m_videoWindowControl->setWinId(q->canvas()->winId());
+ if (q->window())
+ m_videoWindowControl->setWinId(q->window()->winId());
m_service = service;
QObject::connect(m_videoWindowControl.data(), SIGNAL(nativeSizeChanged()),
q, SLOT(_q_updateNativeSize()));
diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h
index cfbb36a9a..f03411665 100644
--- a/src/multimedia/audio/qaudio.h
+++ b/src/multimedia/audio/qaudio.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
//QTM_SYNC_HEADER_EXPORT QAudio
// Class forward declaration required for QDoc bug
diff --git a/src/multimedia/audio/qaudio_mac_p.h b/src/multimedia/audio/qaudio_mac_p.h
index ccd138f3f..a677b06a2 100644
--- a/src/multimedia/audio/qaudio_mac_p.h
+++ b/src/multimedia/audio/qaudio_mac_p.h
@@ -65,8 +65,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
extern QAudioFormat toQAudioFormat(const AudioStreamBasicDescription& streamFormat);
extern AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat);
diff --git a/src/multimedia/audio/qaudiobuffer.h b/src/multimedia/audio/qaudiobuffer.h
index 77d7d0336..652dea73f 100644
--- a/src/multimedia/audio/qaudiobuffer.h
+++ b/src/multimedia/audio/qaudiobuffer.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractAudioBuffer;
class QAudioBufferPrivate;
class Q_MULTIMEDIA_EXPORT QAudioBuffer
diff --git a/src/multimedia/audio/qaudiobuffer_p.h b/src/multimedia/audio/qaudiobuffer_p.h
index 8f78ada86..dfdc98061 100644
--- a/src/multimedia/audio/qaudiobuffer_p.h
+++ b/src/multimedia/audio/qaudiobuffer_p.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/audio/qaudiodecoder.h b/src/multimedia/audio/qaudiodecoder.h
index 15c2c3d91..bf6bde40c 100644
--- a/src/multimedia/audio/qaudiodecoder.h
+++ b/src/multimedia/audio/qaudiodecoder.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioDecoderPrivate;
class Q_MULTIMEDIA_EXPORT QAudioDecoder : public QMediaObject
{
diff --git a/src/multimedia/audio/qaudiodevicefactory_p.h b/src/multimedia/audio/qaudiodevicefactory_p.h
index 061f96d65..75e14cd68 100644
--- a/src/multimedia/audio/qaudiodevicefactory_p.h
+++ b/src/multimedia/audio/qaudiodevicefactory_p.h
@@ -65,8 +65,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractAudioInput;
class QAbstractAudioOutput;
diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h
index e4189db08..d1bbcdeb3 100644
--- a/src/multimedia/audio/qaudiodeviceinfo.h
+++ b/src/multimedia/audio/qaudiodeviceinfo.h
@@ -59,8 +59,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioDeviceFactory;
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
index 85e7dde7b..cd27ce792 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
@@ -69,8 +69,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
const unsigned int MAX_SAMPLE_RATES = 5;
const unsigned int SAMPLE_RATES[] =
diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h
index 27c255dd3..d76d60b3d 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h
+++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h
@@ -62,8 +62,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo
{
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
index e72d6fda2..3c66d053e 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
@@ -51,14 +51,37 @@
//
-#include <windows.h>
+#include <QtCore/qt_windows.h>
#include <mmsystem.h>
#include "qaudiodeviceinfo_win32_p.h"
-#include <dshow.h>
#if defined(Q_CC_MINGW) && !defined(__MINGW64_VERSION_MAJOR)
+struct IBaseFilter; // Needed for strmif.h from stock MinGW.
+struct _DDPIXELFORMAT;
+typedef struct _DDPIXELFORMAT* LPDDPIXELFORMAT;
+#endif
+
+#include <strmif.h>
+#if !defined(Q_CC_MINGW) || defined(__MINGW64_VERSION_MAJOR)
+# include <uuids.h>
+#else
extern GUID CLSID_AudioInputDeviceCategory;
+extern GUID CLSID_AudioRendererCategory;
+extern GUID IID_ICreateDevEnum;
+extern GUID CLSID_SystemDeviceEnum;
+
+#ifndef __ICreateDevEnum_INTERFACE_DEFINED__
+#define __ICreateDevEnum_INTERFACE_DEFINED__
+
+DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)
+{
+ STDMETHOD(CreateClassEnumerator)(REFCLSID clsidDeviceClass,
+ IEnumMoniker **ppEnumMoniker,
+ DWORD dwFlags) PURE;
+};
+
+#endif // __ICreateDevEnum_INTERFACE_DEFINED__
#ifndef __IErrorLog_INTERFACE_DEFINED__
#define __IErrorLog_INTERFACE_DEFINED__
@@ -286,7 +309,7 @@ void QAudioDeviceInfoInternal::updateLists()
{
// redo all lists based on current settings
bool match = false;
- DWORD fmt = NULL;
+ DWORD fmt = 0;
if(mode == QAudio::AudioOutput) {
WAVEOUTCAPS woc;
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.h b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h
index 35d1e4eb8..2b3da88fc 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.h
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h
@@ -67,8 +67,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
const unsigned int MAX_SAMPLE_RATES = 5;
const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 };
diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h
index 20b00bc08..38076c784 100644
--- a/src/multimedia/audio/qaudioformat.h
+++ b/src/multimedia/audio/qaudioformat.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioFormatPrivate;
class Q_MULTIMEDIA_EXPORT QAudioFormat
diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h
index 0373e0b64..583eb1892 100644
--- a/src/multimedia/audio/qaudioinput.h
+++ b/src/multimedia/audio/qaudioinput.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractAudioInput;
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h
index 749bc3668..cb02e2717 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.h
+++ b/src/multimedia/audio/qaudioinput_alsa_p.h
@@ -71,8 +71,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class InputPrivate;
diff --git a/src/multimedia/audio/qaudioinput_mac_p.h b/src/multimedia/audio/qaudioinput_mac_p.h
index c5e66b2aa..6c319b061 100644
--- a/src/multimedia/audio/qaudioinput_mac_p.h
+++ b/src/multimedia/audio/qaudioinput_mac_p.h
@@ -72,8 +72,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QTimer;
class QIODevice;
diff --git a/src/multimedia/audio/qaudioinput_win32_p.h b/src/multimedia/audio/qaudioinput_win32_p.h
index 0f027a4a0..af9943bd1 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.h
+++ b/src/multimedia/audio/qaudioinput_win32_p.h
@@ -53,9 +53,7 @@
#ifndef QAUDIOINPUTWIN_H
#define QAUDIOINPUTWIN_H
-#define NOMINMAX
-
-#include <windows.h>
+#include <QtCore/qt_windows.h>
#include <mmsystem.h>
#include <QtCore/qfile.h>
@@ -75,8 +73,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// For compat with 4.6
#if !defined(QT_WIN_CALLBACK)
diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h
index 85891ff5b..98bf10628 100644
--- a/src/multimedia/audio/qaudiooutput.h
+++ b/src/multimedia/audio/qaudiooutput.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractAudioOutput;
diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.h b/src/multimedia/audio/qaudiooutput_alsa_p.h
index e953731b0..08b1783d0 100644
--- a/src/multimedia/audio/qaudiooutput_alsa_p.h
+++ b/src/multimedia/audio/qaudiooutput_alsa_p.h
@@ -70,8 +70,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class OutputPrivate;
diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h
index f5b0ae5ad..490de7ea0 100644
--- a/src/multimedia/audio/qaudiooutput_mac_p.h
+++ b/src/multimedia/audio/qaudiooutput_mac_p.h
@@ -72,8 +72,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QIODevice;
class QAbstractAudioDeviceInfo;
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.h b/src/multimedia/audio/qaudiooutput_win32_p.h
index 13c44c688..9558299a3 100644
--- a/src/multimedia/audio/qaudiooutput_win32_p.h
+++ b/src/multimedia/audio/qaudiooutput_win32_p.h
@@ -53,9 +53,7 @@
#ifndef QAUDIOOUTPUTWIN_H
#define QAUDIOOUTPUTWIN_H
-#define NOMINMAX
-
-#include <windows.h>
+#include <QtCore/qt_windows.h>
#include <mmsystem.h>
#include <QtCore/qdebug.h>
@@ -82,8 +80,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioOutputPrivate : public QAbstractAudioOutput
{
diff --git a/src/multimedia/audio/qaudioprobe.h b/src/multimedia/audio/qaudioprobe.h
index d916870b4..dd2525ae8 100644
--- a/src/multimedia/audio/qaudioprobe.h
+++ b/src/multimedia/audio/qaudioprobe.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaObject;
class QMediaRecorder;
diff --git a/src/multimedia/audio/qaudiosystem.h b/src/multimedia/audio/qaudiosystem.h
index cb2e3f2fb..0ad2f6b6a 100644
--- a/src/multimedia/audio/qaudiosystem.h
+++ b/src/multimedia/audio/qaudiosystem.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/audio/qaudiosystemplugin.h b/src/multimedia/audio/qaudiosystemplugin.h
index de1a00ccc..b07dacc09 100644
--- a/src/multimedia/audio/qaudiosystemplugin.h
+++ b/src/multimedia/audio/qaudiosystemplugin.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/audio/qsamplecache_p.h b/src/multimedia/audio/qsamplecache_p.h
index f4aaaaa49..ecae7d2f5 100644
--- a/src/multimedia/audio/qsamplecache_p.h
+++ b/src/multimedia/audio/qsamplecache_p.h
@@ -66,8 +66,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QIODevice;
class QNetworkAccessManager;
class QSampleCache;
diff --git a/src/multimedia/audio/qsound.h b/src/multimedia/audio/qsound.h
index 277cf124f..f179f5017 100644
--- a/src/multimedia/audio/qsound.h
+++ b/src/multimedia/audio/qsound.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSoundEffect;
class Q_MULTIMEDIA_EXPORT QSound : public QObject
diff --git a/src/multimedia/audio/qsoundeffect.h b/src/multimedia/audio/qsoundeffect.h
index cf24bcbe1..dfc4d485b 100644
--- a/src/multimedia/audio/qsoundeffect.h
+++ b/src/multimedia/audio/qsoundeffect.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSoundEffectPrivate;
diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h
index c17216c8d..78f3d1104 100644
--- a/src/multimedia/audio/qsoundeffect_pulse_p.h
+++ b/src/multimedia/audio/qsoundeffect_pulse_p.h
@@ -66,8 +66,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSoundEffectRef;
class QSoundEffectPrivate : public QObject
diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.h b/src/multimedia/audio/qsoundeffect_qaudio_p.h
index 15285db50..142d1046c 100644
--- a/src/multimedia/audio/qsoundeffect_qaudio_p.h
+++ b/src/multimedia/audio/qsoundeffect_qaudio_p.h
@@ -63,8 +63,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSoundEffectPrivate;
class PrivateSoundSource : public QIODevice
diff --git a/src/multimedia/audio/qwavedecoder_p.h b/src/multimedia/audio/qwavedecoder_p.h
index f32957684..3947ad515 100644
--- a/src/multimedia/audio/qwavedecoder_p.h
+++ b/src/multimedia/audio/qwavedecoder_p.h
@@ -61,8 +61,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QWaveDecoder : public QIODevice
diff --git a/src/multimedia/camera/qcamera.h b/src/multimedia/camera/qcamera.h
index bc9ce5263..e25a7d942 100644
--- a/src/multimedia/camera/qcamera.h
+++ b/src/multimedia/camera/qcamera.h
@@ -62,8 +62,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractVideoSurface;
class QVideoWidget;
diff --git a/src/multimedia/camera/qcameraexposure.h b/src/multimedia/camera/qcameraexposure.h
index 1238371dd..09d66248b 100644
--- a/src/multimedia/camera/qcameraexposure.h
+++ b/src/multimedia/camera/qcameraexposure.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QCamera;
class QCameraExposurePrivate;
diff --git a/src/multimedia/camera/qcamerafocus.h b/src/multimedia/camera/qcamerafocus.h
index 5865225eb..2b98257b9 100644
--- a/src/multimedia/camera/qcamerafocus.h
+++ b/src/multimedia/camera/qcamerafocus.h
@@ -56,8 +56,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QCamera;
diff --git a/src/multimedia/camera/qcameraimagecapture.h b/src/multimedia/camera/qcameraimagecapture.h
index 99e6c08c6..8aefa7dff 100644
--- a/src/multimedia/camera/qcameraimagecapture.h
+++ b/src/multimedia/camera/qcameraimagecapture.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSize;
QT_END_NAMESPACE
diff --git a/src/multimedia/camera/qcameraimageprocessing.h b/src/multimedia/camera/qcameraimageprocessing.h
index e746fc426..e48f6e42d 100644
--- a/src/multimedia/camera/qcameraimageprocessing.h
+++ b/src/multimedia/camera/qcameraimageprocessing.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QCamera;
diff --git a/src/multimedia/controls/qaudiodecodercontrol.h b/src/multimedia/controls/qaudiodecodercontrol.h
index ad806b903..9de943343 100644
--- a/src/multimedia/controls/qaudiodecodercontrol.h
+++ b/src/multimedia/controls/qaudiodecodercontrol.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QIODevice;
class Q_MULTIMEDIA_EXPORT QAudioDecoderControl : public QMediaControl
{
diff --git a/src/multimedia/controls/qaudioencodersettingscontrol.h b/src/multimedia/controls/qaudioencodersettingscontrol.h
index f58473fc8..38f990715 100644
--- a/src/multimedia/controls/qaudioencodersettingscontrol.h
+++ b/src/multimedia/controls/qaudioencodersettingscontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QStringList;
class QAudioFormat;
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qaudioinputselectorcontrol.h b/src/multimedia/controls/qaudioinputselectorcontrol.h
index bb055f8bb..bdf483719 100644
--- a/src/multimedia/controls/qaudioinputselectorcontrol.h
+++ b/src/multimedia/controls/qaudioinputselectorcontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Class forward declaration required for QDoc bug
class QString;
diff --git a/src/multimedia/controls/qaudiooutputselectorcontrol.h b/src/multimedia/controls/qaudiooutputselectorcontrol.h
index c8bd7142e..7ee20c07e 100644
--- a/src/multimedia/controls/qaudiooutputselectorcontrol.h
+++ b/src/multimedia/controls/qaudiooutputselectorcontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Class forward declaration required for QDoc bug
class QString;
diff --git a/src/multimedia/controls/qcameracapturebufferformatcontrol.h b/src/multimedia/controls/qcameracapturebufferformatcontrol.h
index 7cc096368..d4b395443 100644
--- a/src/multimedia/controls/qcameracapturebufferformatcontrol.h
+++ b/src/multimedia/controls/qcameracapturebufferformatcontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameracapturedestinationcontrol.h b/src/multimedia/controls/qcameracapturedestinationcontrol.h
index b4fadea34..d3068a10b 100644
--- a/src/multimedia/controls/qcameracapturedestinationcontrol.h
+++ b/src/multimedia/controls/qcameracapturedestinationcontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameracontrol.h b/src/multimedia/controls/qcameracontrol.h
index 02d642c68..416b84dcb 100644
--- a/src/multimedia/controls/qcameracontrol.h
+++ b/src/multimedia/controls/qcameracontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameraexposurecontrol.h b/src/multimedia/controls/qcameraexposurecontrol.h
index 20833e936..684a16709 100644
--- a/src/multimedia/controls/qcameraexposurecontrol.h
+++ b/src/multimedia/controls/qcameraexposurecontrol.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcamerafeedbackcontrol.h b/src/multimedia/controls/qcamerafeedbackcontrol.h
index 7e7b514c3..27532a64a 100644
--- a/src/multimedia/controls/qcamerafeedbackcontrol.h
+++ b/src/multimedia/controls/qcamerafeedbackcontrol.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameraflashcontrol.h b/src/multimedia/controls/qcameraflashcontrol.h
index 845d3756d..1f29c46e7 100644
--- a/src/multimedia/controls/qcameraflashcontrol.h
+++ b/src/multimedia/controls/qcameraflashcontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcamerafocuscontrol.h b/src/multimedia/controls/qcamerafocuscontrol.h
index 5a447b138..00bdf7c66 100644
--- a/src/multimedia/controls/qcamerafocuscontrol.h
+++ b/src/multimedia/controls/qcamerafocuscontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameraimagecapturecontrol.h b/src/multimedia/controls/qcameraimagecapturecontrol.h
index aa46c0cf8..085a42f89 100644
--- a/src/multimedia/controls/qcameraimagecapturecontrol.h
+++ b/src/multimedia/controls/qcameraimagecapturecontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QImage;
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qcameraimageprocessingcontrol.h b/src/multimedia/controls/qcameraimageprocessingcontrol.h
index f8539bbb3..1fe1cf762 100644
--- a/src/multimedia/controls/qcameraimageprocessingcontrol.h
+++ b/src/multimedia/controls/qcameraimageprocessingcontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameralockscontrol.h b/src/multimedia/controls/qcameralockscontrol.h
index 9b5de2da4..e85bf47b8 100644
--- a/src/multimedia/controls/qcameralockscontrol.h
+++ b/src/multimedia/controls/qcameralockscontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcameraviewfindersettingscontrol.h b/src/multimedia/controls/qcameraviewfindersettingscontrol.h
index 2e80f7824..297732f89 100644
--- a/src/multimedia/controls/qcameraviewfindersettingscontrol.h
+++ b/src/multimedia/controls/qcameraviewfindersettingscontrol.h
@@ -50,8 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qcamerazoomcontrol.h b/src/multimedia/controls/qcamerazoomcontrol.h
index d927a15c9..b60dc49bf 100644
--- a/src/multimedia/controls/qcamerazoomcontrol.h
+++ b/src/multimedia/controls/qcamerazoomcontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qimageencodercontrol.h b/src/multimedia/controls/qimageencodercontrol.h
index 493773331..4d6de65e0 100644
--- a/src/multimedia/controls/qimageencodercontrol.h
+++ b/src/multimedia/controls/qimageencodercontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QByteArray;
class QStringList;
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qmediaaudioprobecontrol.h b/src/multimedia/controls/qmediaaudioprobecontrol.h
index eeb201c5b..02846d1f5 100644
--- a/src/multimedia/controls/qmediaaudioprobecontrol.h
+++ b/src/multimedia/controls/qmediaaudioprobecontrol.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioBuffer;
class Q_MULTIMEDIA_EXPORT QMediaAudioProbeControl : public QMediaControl
{
diff --git a/src/multimedia/controls/qmediaavailabilitycontrol.h b/src/multimedia/controls/qmediaavailabilitycontrol.h
index 0c2cfc670..2cdc06196 100644
--- a/src/multimedia/controls/qmediaavailabilitycontrol.h
+++ b/src/multimedia/controls/qmediaavailabilitycontrol.h
@@ -50,8 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmediacontainercontrol.h b/src/multimedia/controls/qmediacontainercontrol.h
index 9c413e37c..888b7dc88 100644
--- a/src/multimedia/controls/qmediacontainercontrol.h
+++ b/src/multimedia/controls/qmediacontainercontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmediagaplessplaybackcontrol.h b/src/multimedia/controls/qmediagaplessplaybackcontrol.h
index fca896ce8..56eda7141 100644
--- a/src/multimedia/controls/qmediagaplessplaybackcontrol.h
+++ b/src/multimedia/controls/qmediagaplessplaybackcontrol.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmedianetworkaccesscontrol.h b/src/multimedia/controls/qmedianetworkaccesscontrol.h
index 948a1d500..1e595ccf5 100644
--- a/src/multimedia/controls/qmedianetworkaccesscontrol.h
+++ b/src/multimedia/controls/qmedianetworkaccesscontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmediaplayercontrol.h b/src/multimedia/controls/qmediaplayercontrol.h
index b15087ea5..7430418a1 100644
--- a/src/multimedia/controls/qmediaplayercontrol.h
+++ b/src/multimedia/controls/qmediaplayercontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylist;
diff --git a/src/multimedia/controls/qmediaplaylistcontrol_p.h b/src/multimedia/controls/qmediaplaylistcontrol_p.h
index a3fb9335b..9bd8a9585 100644
--- a/src/multimedia/controls/qmediaplaylistcontrol_p.h
+++ b/src/multimedia/controls/qmediaplaylistcontrol_p.h
@@ -63,8 +63,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylistProvider;
diff --git a/src/multimedia/controls/qmediaplaylistsourcecontrol_p.h b/src/multimedia/controls/qmediaplaylistsourcecontrol_p.h
index 0dc28c302..7be4b43a5 100644
--- a/src/multimedia/controls/qmediaplaylistsourcecontrol_p.h
+++ b/src/multimedia/controls/qmediaplaylistsourcecontrol_p.h
@@ -60,8 +60,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylist;
diff --git a/src/multimedia/controls/qmediarecordercontrol.h b/src/multimedia/controls/qmediarecordercontrol.h
index 7ea9c140d..a9bf5bcea 100644
--- a/src/multimedia/controls/qmediarecordercontrol.h
+++ b/src/multimedia/controls/qmediarecordercontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QUrl;
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qmediastreamscontrol.h b/src/multimedia/controls/qmediastreamscontrol.h
index 33ab358a6..a1b0f2855 100644
--- a/src/multimedia/controls/qmediastreamscontrol.h
+++ b/src/multimedia/controls/qmediastreamscontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmediavideoprobecontrol.h b/src/multimedia/controls/qmediavideoprobecontrol.h
index cfb59d840..0085ebd33 100644
--- a/src/multimedia/controls/qmediavideoprobecontrol.h
+++ b/src/multimedia/controls/qmediavideoprobecontrol.h
@@ -50,8 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVideoFrame;
class Q_MULTIMEDIA_EXPORT QMediaVideoProbeControl : public QMediaControl
{
diff --git a/src/multimedia/controls/qmetadatareadercontrol.h b/src/multimedia/controls/qmetadatareadercontrol.h
index 4a1b7678d..5d1972cd8 100644
--- a/src/multimedia/controls/qmetadatareadercontrol.h
+++ b/src/multimedia/controls/qmetadatareadercontrol.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qmetadatawritercontrol.h b/src/multimedia/controls/qmetadatawritercontrol.h
index eb608d88c..88de69e2b 100644
--- a/src/multimedia/controls/qmetadatawritercontrol.h
+++ b/src/multimedia/controls/qmetadatawritercontrol.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qradiodatacontrol.h b/src/multimedia/controls/qradiodatacontrol.h
index 240db7355..709794691 100644
--- a/src/multimedia/controls/qradiodatacontrol.h
+++ b/src/multimedia/controls/qradiodatacontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qradiotunercontrol.h b/src/multimedia/controls/qradiotunercontrol.h
index 364c5c2bd..72aac32c6 100644
--- a/src/multimedia/controls/qradiotunercontrol.h
+++ b/src/multimedia/controls/qradiotunercontrol.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qvideodeviceselectorcontrol.h b/src/multimedia/controls/qvideodeviceselectorcontrol.h
index 09418cf06..cee69c37e 100644
--- a/src/multimedia/controls/qvideodeviceselectorcontrol.h
+++ b/src/multimedia/controls/qvideodeviceselectorcontrol.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/controls/qvideoencodersettingscontrol.h b/src/multimedia/controls/qvideoencodersettingscontrol.h
index 6908583e7..88f4fc939 100644
--- a/src/multimedia/controls/qvideoencodersettingscontrol.h
+++ b/src/multimedia/controls/qvideoencodersettingscontrol.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QByteArray;
class QStringList;
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qvideorenderercontrol.h b/src/multimedia/controls/qvideorenderercontrol.h
index 097c3894e..e6a6994dc 100644
--- a/src/multimedia/controls/qvideorenderercontrol.h
+++ b/src/multimedia/controls/qvideorenderercontrol.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractVideoSurface;
class Q_MULTIMEDIA_EXPORT QVideoRendererControl : public QMediaControl
{
diff --git a/src/multimedia/controls/qvideowindowcontrol.h b/src/multimedia/controls/qvideowindowcontrol.h
index 83a42a5f8..556d1ebbf 100644
--- a/src/multimedia/controls/qvideowindowcontrol.h
+++ b/src/multimedia/controls/qvideowindowcontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/doc/qtmultimedia.qdocconf b/src/multimedia/doc/qtmultimedia.qdocconf
index 9ed3ee0b8..6f60049dc 100644
--- a/src/multimedia/doc/qtmultimedia.qdocconf
+++ b/src/multimedia/doc/qtmultimedia.qdocconf
@@ -76,9 +76,4 @@ sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
HTML.nobreadcrumbs = "true"
HTML.templatedir = .
-HTML.stylesheets = style/qtmultimedia.css
-HTML.headerstyles = " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/qtmultimedia.css\" />\n"
-HTML.endheader = "</head>\n<body>\n"
-
-HTML.footer = "<div class=\"footer\">Copyright (c) 2012 Digia Plc and/or its subsidiaries. All rights reserved.</div>\n"
diff --git a/src/multimedia/playback/qmediacontent.h b/src/multimedia/playback/qmediacontent.h
index b92a9d1df..fb16d4dc3 100644
--- a/src/multimedia/playback/qmediacontent.h
+++ b/src/multimedia/playback/qmediacontent.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylist;
class QMediaContentPrivate;
diff --git a/src/multimedia/playback/qmedianetworkplaylistprovider_p.h b/src/multimedia/playback/qmedianetworkplaylistprovider_p.h
index d948819e4..825c309a0 100644
--- a/src/multimedia/playback/qmedianetworkplaylistprovider_p.h
+++ b/src/multimedia/playback/qmedianetworkplaylistprovider_p.h
@@ -59,8 +59,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaNetworkPlaylistProviderPrivate;
class Q_MULTIMEDIA_EXPORT QMediaNetworkPlaylistProvider : public QMediaPlaylistProvider
diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h
index d5ac64d12..787f2d3e4 100644
--- a/src/multimedia/playback/qmediaplayer.h
+++ b/src/multimedia/playback/qmediaplayer.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractVideoSurface;
class QMediaPlaylist;
diff --git a/src/multimedia/playback/qmediaplaylist.h b/src/multimedia/playback/qmediaplaylist.h
index 038e9cd1f..f88b94e82 100644
--- a/src/multimedia/playback/qmediaplaylist.h
+++ b/src/multimedia/playback/qmediaplaylist.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylistProvider;
diff --git a/src/multimedia/playback/qmediaplaylist_p.h b/src/multimedia/playback/qmediaplaylist_p.h
index 76ee7623b..0b053dd8c 100644
--- a/src/multimedia/playback/qmediaplaylist_p.h
+++ b/src/multimedia/playback/qmediaplaylist_p.h
@@ -70,8 +70,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylistControl;
class QMediaPlaylistProvider;
diff --git a/src/multimedia/playback/qmediaplaylistioplugin_p.h b/src/multimedia/playback/qmediaplaylistioplugin_p.h
index eccf9b1b3..0a385613f 100644
--- a/src/multimedia/playback/qmediaplaylistioplugin_p.h
+++ b/src/multimedia/playback/qmediaplaylistioplugin_p.h
@@ -64,8 +64,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QString;
class QUrl;
class QByteArray;
diff --git a/src/multimedia/playback/qmediaplaylistnavigator_p.h b/src/multimedia/playback/qmediaplaylistnavigator_p.h
index 53e3f74a4..d0f3a371f 100644
--- a/src/multimedia/playback/qmediaplaylistnavigator_p.h
+++ b/src/multimedia/playback/qmediaplaylistnavigator_p.h
@@ -61,8 +61,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylistNavigatorPrivate;
class Q_MULTIMEDIA_EXPORT QMediaPlaylistNavigator : public QObject
diff --git a/src/multimedia/playback/qmediaplaylistprovider_p.h b/src/multimedia/playback/qmediaplaylistprovider_p.h
index 732746c8a..579590394 100644
--- a/src/multimedia/playback/qmediaplaylistprovider_p.h
+++ b/src/multimedia/playback/qmediaplaylistprovider_p.h
@@ -60,8 +60,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaPlaylistProviderPrivate
{
diff --git a/src/multimedia/playback/qmediaresource.h b/src/multimedia/playback/qmediaresource.h
index efce4efc0..805ce5c7c 100644
--- a/src/multimedia/playback/qmediaresource.h
+++ b/src/multimedia/playback/qmediaresource.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Class forward declaration required for QDoc bug
class QString;
class Q_MULTIMEDIA_EXPORT QMediaResource
diff --git a/src/multimedia/qmediabindableinterface.h b/src/multimedia/qmediabindableinterface.h
index 170cbc5de..b45c901d4 100644
--- a/src/multimedia/qmediabindableinterface.h
+++ b/src/multimedia/qmediabindableinterface.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaObject;
diff --git a/src/multimedia/qmediacontrol.h b/src/multimedia/qmediacontrol.h
index df3782457..0356fc5b5 100644
--- a/src/multimedia/qmediacontrol.h
+++ b/src/multimedia/qmediacontrol.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaControlPrivate;
class Q_MULTIMEDIA_EXPORT QMediaControl : public QObject
diff --git a/src/multimedia/qmediacontrol_p.h b/src/multimedia/qmediacontrol_p.h
index c4d7ebf71..9f362b320 100644
--- a/src/multimedia/qmediacontrol_p.h
+++ b/src/multimedia/qmediacontrol_p.h
@@ -59,8 +59,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaControl;
diff --git a/src/multimedia/qmediaenumdebug.h b/src/multimedia/qmediaenumdebug.h
index 6b2e54e9d..9acf612cb 100644
--- a/src/multimedia/qmediaenumdebug.h
+++ b/src/multimedia/qmediaenumdebug.h
@@ -58,8 +58,6 @@
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
#ifndef QT_NO_DEBUG_STREAM
#define Q_MEDIA_ENUM_DEBUG(Class,Enum) \
diff --git a/src/multimedia/qmediaobject.h b/src/multimedia/qmediaobject.h
index 4b7680e56..abfcff9dd 100644
--- a/src/multimedia/qmediaobject.h
+++ b/src/multimedia/qmediaobject.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaService;
class QMediaBindableInterface;
diff --git a/src/multimedia/qmediaobject_p.h b/src/multimedia/qmediaobject_p.h
index ccf82dcda..faddb94ff 100644
--- a/src/multimedia/qmediaobject_p.h
+++ b/src/multimedia/qmediaobject_p.h
@@ -63,8 +63,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMetaDataReaderControl;
class QMediaAvailabilityControl;
diff --git a/src/multimedia/qmediapluginloader_p.h b/src/multimedia/qmediapluginloader_p.h
index d580321a9..13dbd3cf8 100644
--- a/src/multimedia/qmediapluginloader_p.h
+++ b/src/multimedia/qmediapluginloader_p.h
@@ -65,8 +65,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QFactoryLoader;
class QMediaServiceProviderPlugin;
diff --git a/src/multimedia/qmediaresourcepolicy_p.h b/src/multimedia/qmediaresourcepolicy_p.h
index d0896ecda..d8b3443aa 100644
--- a/src/multimedia/qmediaresourcepolicy_p.h
+++ b/src/multimedia/qmediaresourcepolicy_p.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class Q_MULTIMEDIA_EXPORT QMediaResourcePolicy
{
public:
diff --git a/src/multimedia/qmediaresourcepolicyplugin_p.h b/src/multimedia/qmediaresourcepolicyplugin_p.h
index f20e64061..f594a3f05 100644
--- a/src/multimedia/qmediaresourcepolicyplugin_p.h
+++ b/src/multimedia/qmediaresourcepolicyplugin_p.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
struct Q_MULTIMEDIA_EXPORT QMediaResourceSetFactoryInterface
{
virtual QObject* create(const QString& interfaceId) = 0;
diff --git a/src/multimedia/qmediaresourceset_p.h b/src/multimedia/qmediaresourceset_p.h
index 653c5aa27..65acabe97 100644
--- a/src/multimedia/qmediaresourceset_p.h
+++ b/src/multimedia/qmediaresourceset_p.h
@@ -48,8 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
#define QMediaPlayerResourceSetInterface_iid \
"org.qt-project.qt.mediaplayerresourceset/5.0"
diff --git a/src/multimedia/qmediaservice.h b/src/multimedia/qmediaservice.h
index 376f2615a..0ca3e021f 100644
--- a/src/multimedia/qmediaservice.h
+++ b/src/multimedia/qmediaservice.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaServicePrivate;
class Q_MULTIMEDIA_EXPORT QMediaService : public QObject
diff --git a/src/multimedia/qmediaservice_p.h b/src/multimedia/qmediaservice_p.h
index 90668662e..3c95e8b40 100644
--- a/src/multimedia/qmediaservice_p.h
+++ b/src/multimedia/qmediaservice_p.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioDeviceControl;
diff --git a/src/multimedia/qmediaserviceprovider_p.h b/src/multimedia/qmediaserviceprovider_p.h
index df368ae40..c79ca33ba 100644
--- a/src/multimedia/qmediaserviceprovider_p.h
+++ b/src/multimedia/qmediaserviceprovider_p.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaService;
diff --git a/src/multimedia/qmediaserviceproviderplugin.h b/src/multimedia/qmediaserviceproviderplugin.h
index fec57411d..611f7d896 100644
--- a/src/multimedia/qmediaserviceproviderplugin.h
+++ b/src/multimedia/qmediaserviceproviderplugin.h
@@ -55,8 +55,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Required for QDoc workaround
class QString;
diff --git a/src/multimedia/qmediatimerange.h b/src/multimedia/qmediatimerange.h
index 931f155f0..ae4bd137e 100644
--- a/src/multimedia/qmediatimerange.h
+++ b/src/multimedia/qmediatimerange.h
@@ -50,8 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaTimeRangePrivate;
diff --git a/src/multimedia/qtmedianamespace.h b/src/multimedia/qtmedianamespace.h
index 2c4671d16..f85111ccc 100644
--- a/src/multimedia/qtmedianamespace.h
+++ b/src/multimedia/qtmedianamespace.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
// Class forward declaration required for QDoc bug
class QString;
diff --git a/src/multimedia/qtmultimediadefs.h b/src/multimedia/qtmultimediadefs.h
index 37560d012..03d4c3834 100644
--- a/src/multimedia/qtmultimediadefs.h
+++ b/src/multimedia/qtmultimediadefs.h
@@ -58,8 +58,6 @@
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
#ifndef QT_STATIC
# if defined(QT_BUILD_MULTIMEDIA_LIB)
# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
diff --git a/src/multimedia/qtmultimediaquicktools_headers/qsgvideonode_p.h b/src/multimedia/qtmultimediaquicktools_headers/qsgvideonode_p.h
index 84977e562..9a3923236 100644
--- a/src/multimedia/qtmultimediaquicktools_headers/qsgvideonode_p.h
+++ b/src/multimedia/qtmultimediaquicktools_headers/qsgvideonode_p.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
const QLatin1String QSGVideoNodeFactoryPluginKey("sgvideonodes");
class Q_MULTIMEDIAQUICK_EXPORT QSGVideoNode : public QSGGeometryNode
diff --git a/src/multimedia/radio/qradiodata.h b/src/multimedia/radio/qradiodata.h
index 18d66318f..6c6b0f411 100644
--- a/src/multimedia/radio/qradiodata.h
+++ b/src/multimedia/radio/qradiodata.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QRadioDataPrivate;
class Q_MULTIMEDIA_EXPORT QRadioData : public QObject, public QMediaBindableInterface
diff --git a/src/multimedia/radio/qradiotuner.h b/src/multimedia/radio/qradiotuner.h
index 857b29586..eda8bc86f 100644
--- a/src/multimedia/radio/qradiotuner.h
+++ b/src/multimedia/radio/qradiotuner.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QRadioData;
class QRadioTunerPrivate;
class Q_MULTIMEDIA_EXPORT QRadioTuner : public QMediaObject
diff --git a/src/multimedia/recording/qaudiorecorder.h b/src/multimedia/recording/qaudiorecorder.h
index 0f75901e0..1ab6a3479 100644
--- a/src/multimedia/recording/qaudiorecorder.h
+++ b/src/multimedia/recording/qaudiorecorder.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QString;
class QSize;
class QAudioFormat;
diff --git a/src/multimedia/recording/qmediaencodersettings.h b/src/multimedia/recording/qmediaencodersettings.h
index 89fdf2c62..c5cbf5aae 100644
--- a/src/multimedia/recording/qmediaencodersettings.h
+++ b/src/multimedia/recording/qmediaencodersettings.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAudioEncoderSettingsPrivate;
diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp
index fba8387d8..e6bbcdd7e 100644
--- a/src/multimedia/recording/qmediarecorder.cpp
+++ b/src/multimedia/recording/qmediarecorder.cpp
@@ -188,7 +188,8 @@ void QMediaRecorderPrivate::_q_applySettings()
void QMediaRecorderPrivate::_q_availabilityChanged(QtMultimedia::AvailabilityStatus availability)
{
Q_Q(QMediaRecorder);
- Q_UNUSED(error);
+ Q_UNUSED(error)
+ Q_UNUSED(availability)
// Really this should not always emit, but
// we can't really tell from here (isAvailable
diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h
index e77170934..39352ee34 100644
--- a/src/multimedia/recording/qmediarecorder.h
+++ b/src/multimedia/recording/qmediarecorder.h
@@ -54,8 +54,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QUrl;
class QSize;
class QAudioFormat;
diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h
index 57d366d40..9315605e1 100644
--- a/src/multimedia/video/qabstractvideobuffer.h
+++ b/src/multimedia/video/qabstractvideobuffer.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVariant;
diff --git a/src/multimedia/video/qabstractvideobuffer_p.h b/src/multimedia/video/qabstractvideobuffer_p.h
index 9f91fd764..b06847a43 100644
--- a/src/multimedia/video/qabstractvideobuffer_p.h
+++ b/src/multimedia/video/qabstractvideobuffer_p.h
@@ -64,8 +64,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractVideoBufferPrivate
{
public:
diff --git a/src/multimedia/video/qabstractvideosurface.h b/src/multimedia/video/qabstractvideosurface.h
index 3b4464567..d0fc919c1 100644
--- a/src/multimedia/video/qabstractvideosurface.h
+++ b/src/multimedia/video/qabstractvideosurface.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QRectF;
class QVideoSurfaceFormat;
diff --git a/src/multimedia/video/qimagevideobuffer_p.h b/src/multimedia/video/qimagevideobuffer_p.h
index 2e519543a..99f09b569 100644
--- a/src/multimedia/video/qimagevideobuffer_p.h
+++ b/src/multimedia/video/qimagevideobuffer_p.h
@@ -59,8 +59,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QImage;
diff --git a/src/multimedia/video/qmemoryvideobuffer_p.h b/src/multimedia/video/qmemoryvideobuffer_p.h
index 4b79cd476..d34be47f3 100644
--- a/src/multimedia/video/qmemoryvideobuffer_p.h
+++ b/src/multimedia/video/qmemoryvideobuffer_p.h
@@ -61,8 +61,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMemoryVideoBufferPrivate;
diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h
index ff4fc4db1..eb073cb66 100644
--- a/src/multimedia/video/qvideoframe.h
+++ b/src/multimedia/video/qvideoframe.h
@@ -52,8 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QSize;
class QVideoFramePrivate;
diff --git a/src/multimedia/video/qvideoprobe.h b/src/multimedia/video/qvideoprobe.h
index 6ff670746..34c315b53 100644
--- a/src/multimedia/video/qvideoprobe.h
+++ b/src/multimedia/video/qvideoprobe.h
@@ -49,8 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaObject;
class QMediaRecorder;
diff --git a/src/multimedia/video/qvideosurfaceformat.h b/src/multimedia/video/qvideosurfaceformat.h
index cd553f7e2..e0abf7148 100644
--- a/src/multimedia/video/qvideosurfaceformat.h
+++ b/src/multimedia/video/qvideosurfaceformat.h
@@ -53,8 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QDebug;
diff --git a/src/multimedia/video/qvideosurfaceoutput_p.h b/src/multimedia/video/qvideosurfaceoutput_p.h
index 29fa9f2c2..741f6325b 100644
--- a/src/multimedia/video/qvideosurfaceoutput_p.h
+++ b/src/multimedia/video/qvideosurfaceoutput_p.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QAbstractVideoSurface;
class QVideoRendererControl;
diff --git a/src/multimediawidgets/qcameraviewfinder.h b/src/multimediawidgets/qcameraviewfinder.h
index da8420062..b3e5065c3 100644
--- a/src/multimediawidgets/qcameraviewfinder.h
+++ b/src/multimediawidgets/qcameraviewfinder.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QCamera;
diff --git a/src/multimediawidgets/qeglimagetexturesurface_p.h b/src/multimediawidgets/qeglimagetexturesurface_p.h
index 8f7583690..011971f0c 100644
--- a/src/multimediawidgets/qeglimagetexturesurface_p.h
+++ b/src/multimediawidgets/qeglimagetexturesurface_p.h
@@ -69,8 +69,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QGLContext;
class QGLShaderProgram;
class QPainterVideoSurface;
diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h
index b0a69fb7b..367c434c2 100644
--- a/src/multimediawidgets/qgraphicsvideoitem.h
+++ b/src/multimediawidgets/qgraphicsvideoitem.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVideoSurfaceFormat;
QT_END_NAMESPACE
diff --git a/src/multimediawidgets/qpaintervideosurface_mac_p.h b/src/multimediawidgets/qpaintervideosurface_mac_p.h
index 9fbb388f5..b1d56dcd3 100644
--- a/src/multimediawidgets/qpaintervideosurface_mac_p.h
+++ b/src/multimediawidgets/qpaintervideosurface_mac_p.h
@@ -61,8 +61,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVideoSurfaceCoreGraphicsPainter : public QVideoSurfacePainter
{
diff --git a/src/multimediawidgets/qpaintervideosurface_p.h b/src/multimediawidgets/qpaintervideosurface_p.h
index 475414fa5..007cad44e 100644
--- a/src/multimediawidgets/qpaintervideosurface_p.h
+++ b/src/multimediawidgets/qpaintervideosurface_p.h
@@ -65,8 +65,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QGLContext;
QT_END_NAMESPACE
diff --git a/src/multimediawidgets/qtmultimediawidgetdefs.h b/src/multimediawidgets/qtmultimediawidgetdefs.h
index ceda53199..b5da320ff 100644
--- a/src/multimediawidgets/qtmultimediawidgetdefs.h
+++ b/src/multimediawidgets/qtmultimediawidgetdefs.h
@@ -58,8 +58,6 @@
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
#ifndef QT_STATIC
# if defined(QT_BUILD_MULTIMEDIAWIDGETS_LIB)
# define Q_MULTIMEDIAWIDGETS_EXPORT Q_DECL_EXPORT
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp
index 031193df4..ec073ec55 100644
--- a/src/multimediawidgets/qvideowidget.cpp
+++ b/src/multimediawidgets/qvideowidget.cpp
@@ -902,8 +902,6 @@ bool QVideoWidget::event(QEvent *event)
Q_D(QVideoWidget);
if (event->type() == QEvent::WindowStateChange) {
- Qt::WindowFlags flags = windowFlags();
-
if (windowState() & Qt::WindowFullScreen) {
if (d->currentControl)
d->currentControl->setFullScreen(true);
diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h
index 1d2f7446e..3c034d4af 100644
--- a/src/multimediawidgets/qvideowidget.h
+++ b/src/multimediawidgets/qvideowidget.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaObject;
diff --git a/src/multimediawidgets/qvideowidget_p.h b/src/multimediawidgets/qvideowidget_p.h
index 58c532ef5..6d968ed86 100644
--- a/src/multimediawidgets/qvideowidget_p.h
+++ b/src/multimediawidgets/qvideowidget_p.h
@@ -68,8 +68,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QMediaService;
diff --git a/src/multimediawidgets/qvideowidgetcontrol.h b/src/multimediawidgets/qvideowidgetcontrol.h
index 1eb8a7bb3..6615f8dfb 100644
--- a/src/multimediawidgets/qvideowidgetcontrol.h
+++ b/src/multimediawidgets/qvideowidgetcontrol.h
@@ -51,8 +51,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVideoWidgetControlPrivate;
diff --git a/src/plugins/avfoundation/avfoundation.pro b/src/plugins/avfoundation/avfoundation.pro
index 9a3dbf6e0..7f2ddb2fa 100644
--- a/src/plugins/avfoundation/avfoundation.pro
+++ b/src/plugins/avfoundation/avfoundation.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
-SUBDIRS += camera
+SUBDIRS += camera \
+ mediaplayer
diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h
new file mode 100644
index 000000000..d83f3447d
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFDISPLAYLINK_H
+#define AVFDISPLAYLINK_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+
+#include <QuartzCore/CVDisplayLink.h>
+
+QT_BEGIN_NAMESPACE
+
+class AVFDisplayLink : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AVFDisplayLink(QObject *parent = 0);
+ virtual ~AVFDisplayLink();
+ bool isValid() const;
+ bool isActive() const;
+
+public Q_SLOTS:
+ void start();
+ void stop();
+
+Q_SIGNALS:
+ void tick(const CVTimeStamp &ts);
+
+public:
+ void displayLinkEvent(const CVTimeStamp *);
+
+protected:
+ virtual bool event(QEvent *);
+
+private:
+ CVDisplayLinkRef m_displayLink;
+ QMutex m_displayLinkMutex;
+ bool m_pendingDisplayLinkEvent;
+ bool m_isActive;
+ CVTimeStamp m_frameTimeStamp;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFDISPLAYLINK_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
new file mode 100644
index 000000000..59fb3355f
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfdisplaylink.h"
+#include <QtCore/qcoreapplication.h>
+
+#ifdef QT_DEBUG_AVF
+#include <QtCore/qdebug.h>
+#endif
+
+QT_USE_NAMESPACE
+
+static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ Q_UNUSED(displayLink);
+ Q_UNUSED(inNow);
+ Q_UNUSED(flagsIn);
+ Q_UNUSED(flagsOut);
+
+ AVFDisplayLink *link = (AVFDisplayLink *)displayLinkContext;
+
+ link->displayLinkEvent(inOutputTime);
+ return kCVReturnSuccess;
+}
+
+AVFDisplayLink::AVFDisplayLink(QObject *parent)
+ : QObject(parent)
+ , m_pendingDisplayLinkEvent(false)
+ , m_isActive(false)
+{
+ // create display link for the main display
+ CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
+ if (m_displayLink) {
+ // set the current display of a display link.
+ CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay);
+
+ // set the renderer output callback function
+ CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this);
+ }
+}
+
+AVFDisplayLink::~AVFDisplayLink()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+
+ if (m_displayLink) {
+ CVDisplayLinkStop(m_displayLink);
+ CVDisplayLinkRelease(m_displayLink);
+ m_displayLink = NULL;
+ }
+}
+
+bool AVFDisplayLink::isValid() const
+{
+ return m_displayLink != 0;
+}
+
+bool AVFDisplayLink::isActive() const
+{
+ return m_isActive;
+}
+
+void AVFDisplayLink::start()
+{
+ if (m_displayLink && !m_isActive) {
+ CVDisplayLinkStart(m_displayLink);
+ m_isActive = true;
+ }
+}
+
+void AVFDisplayLink::stop()
+{
+ if (m_displayLink && m_isActive) {
+ CVDisplayLinkStop(m_displayLink);
+ m_isActive = false;
+ }
+}
+
+
+void AVFDisplayLink::displayLinkEvent(const CVTimeStamp *ts)
+{
+ // This function is called from a
+ // thread != gui thread. So we post the event.
+ // But we need to make sure that we don't post faster
+ // than the event loop can eat:
+ m_displayLinkMutex.lock();
+ bool pending = m_pendingDisplayLinkEvent;
+ m_pendingDisplayLinkEvent = true;
+ m_frameTimeStamp = *ts;
+ m_displayLinkMutex.unlock();
+
+ if (!pending)
+ qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
+}
+
+bool AVFDisplayLink::event(QEvent *event)
+{
+ switch (event->type()){
+ case QEvent::User: {
+ m_displayLinkMutex.lock();
+ m_pendingDisplayLinkEvent = false;
+ CVTimeStamp ts = m_frameTimeStamp;
+ m_displayLinkMutex.unlock();
+
+ Q_EMIT tick(ts);
+
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return QObject::event(event);
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json b/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json
new file mode 100644
index 000000000..c4a27ea01
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json
@@ -0,0 +1,3 @@
+{
+ "Keys": ["org.qt-project.qt.mediaplayer"]
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h
new file mode 100644
index 000000000..641e200c3
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFMEDIAPLAYERCONTROL_H
+#define AVFMEDIAPLAYERCONTROL_H
+
+#include <QtMultimedia/QMediaPlayerControl>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class AVFMediaPlayerSession;
+
+class AVFMediaPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ explicit AVFMediaPlayerControl(QObject *parent = 0);
+ ~AVFMediaPlayerControl();
+
+ void setSession(AVFMediaPlayerSession *session);
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent &content, QIODevice *stream);
+
+ qint64 position() const;
+ qint64 duration() const;
+
+ int bufferStatus() const;
+
+ int volume() const;
+ bool isMuted() const;
+
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ bool isSeekable() const;
+ QMediaTimeRange availablePlaybackRanges() const;
+
+ qreal playbackRate() const;
+ void setPlaybackRate(qreal rate);
+
+public Q_SLOTS:
+ void setPosition(qint64 pos);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+private:
+ AVFMediaPlayerSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFMEDIAPLAYERCONTROL_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm
new file mode 100644
index 000000000..c6c114fd0
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfmediaplayercontrol.h"
+#include "avfmediaplayersession.h"
+
+QT_USE_NAMESPACE
+
+AVFMediaPlayerControl::AVFMediaPlayerControl(QObject *parent) :
+ QMediaPlayerControl(parent)
+{
+}
+
+AVFMediaPlayerControl::~AVFMediaPlayerControl()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+}
+
+void AVFMediaPlayerControl::setSession(AVFMediaPlayerSession *session)
+{
+ m_session = session;
+
+ connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
+ connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+ connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SIGNAL(stateChanged(QMediaPlayer::State)));
+ connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
+ connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
+ connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool)));
+ connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool)));
+ connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+}
+
+QMediaPlayer::State AVFMediaPlayerControl::state() const
+{
+ return m_session->state();
+}
+
+QMediaPlayer::MediaStatus AVFMediaPlayerControl::mediaStatus() const
+{
+ return m_session->mediaStatus();
+}
+
+QMediaContent AVFMediaPlayerControl::media() const
+{
+ return m_session->media();
+}
+
+const QIODevice *AVFMediaPlayerControl::mediaStream() const
+{
+ return m_session->mediaStream();
+}
+
+void AVFMediaPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+ m_session->setMedia(content, stream);
+
+ Q_EMIT mediaChanged(content);
+}
+
+qint64 AVFMediaPlayerControl::position() const
+{
+ return m_session->position();
+}
+
+qint64 AVFMediaPlayerControl::duration() const
+{
+ return m_session->duration();
+}
+
+int AVFMediaPlayerControl::bufferStatus() const
+{
+ return m_session->bufferStatus();
+}
+
+int AVFMediaPlayerControl::volume() const
+{
+ return m_session->volume();
+}
+
+bool AVFMediaPlayerControl::isMuted() const
+{
+ return m_session->isMuted();
+}
+
+bool AVFMediaPlayerControl::isAudioAvailable() const
+{
+ return m_session->isAudioAvailable();
+}
+
+bool AVFMediaPlayerControl::isVideoAvailable() const
+{
+ return m_session->isVideoAvailable();
+}
+
+bool AVFMediaPlayerControl::isSeekable() const
+{
+ return m_session->isSeekable();
+}
+
+QMediaTimeRange AVFMediaPlayerControl::availablePlaybackRanges() const
+{
+ return m_session->availablePlaybackRanges();
+}
+
+qreal AVFMediaPlayerControl::playbackRate() const
+{
+ return m_session->playbackRate();
+}
+
+void AVFMediaPlayerControl::setPlaybackRate(qreal rate)
+{
+ m_session->setPlaybackRate(rate);
+}
+
+void AVFMediaPlayerControl::setPosition(qint64 pos)
+{
+ m_session->setPosition(pos);
+}
+
+void AVFMediaPlayerControl::play()
+{
+ m_session->play();
+}
+
+void AVFMediaPlayerControl::pause()
+{
+ m_session->pause();
+}
+
+void AVFMediaPlayerControl::stop()
+{
+ m_session->stop();
+}
+
+void AVFMediaPlayerControl::setVolume(int volume)
+{
+ m_session->setVolume(volume);
+}
+
+void AVFMediaPlayerControl::setMuted(bool muted)
+{
+ m_session->setMuted(muted);
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h
new file mode 100644
index 000000000..2a717ed85
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFMEDIAPLAYERMETADATACONTROL_H
+#define AVFMEDIAPLAYERMETADATACONTROL_H
+
+#include <QtMultimedia/QMetaDataReaderControl>
+
+QT_BEGIN_NAMESPACE
+
+class AVFMediaPlayerSession;
+
+class AVFMediaPlayerMetaDataControl : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ explicit AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent = 0);
+ virtual ~AVFMediaPlayerMetaDataControl();
+
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+
+ QVariant metaData(const QString &key) const;
+ QStringList availableMetaData() const;
+
+private Q_SLOTS:
+ void updateTags();
+
+private:
+ AVFMediaPlayerSession *m_session;
+ QMap<QString, QVariant> m_tags;
+ void *m_asset;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFMEDIAPLAYERMETADATACONTROL_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm
new file mode 100644
index 000000000..84a6bef98
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfmediaplayermetadatacontrol.h"
+#include "avfmediaplayersession.h"
+
+#include <QtMultimedia/qtmedianamespace.h>
+
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+AVFMediaPlayerMetaDataControl::AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent)
+ : QMetaDataReaderControl(parent)
+ , m_session(session)
+ , m_asset(0)
+{
+ QObject::connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(updateTags()));
+}
+
+AVFMediaPlayerMetaDataControl::~AVFMediaPlayerMetaDataControl()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+}
+
+bool AVFMediaPlayerMetaDataControl::isMetaDataAvailable() const
+{
+ return !m_tags.isEmpty();
+}
+
+bool AVFMediaPlayerMetaDataControl::isWritable() const
+{
+ return false;
+}
+
+QVariant AVFMediaPlayerMetaDataControl::metaData(const QString &key) const
+{
+ return m_tags.value(key);
+}
+
+QStringList AVFMediaPlayerMetaDataControl::availableMetaData() const
+{
+ return m_tags.keys();
+}
+
+void AVFMediaPlayerMetaDataControl::updateTags()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ AVAsset *currentAsset = (AVAsset*)m_session->currentAssetHandle();
+
+ //Don't read the tags from the same asset more than once
+ if (currentAsset == m_asset) {
+ return;
+ }
+
+ m_asset = currentAsset;
+
+ //Since we've changed assets, clear old tags
+ m_tags.clear();
+
+ NSArray *metadataFormats = [currentAsset availableMetadataFormats];
+ for ( NSString *format in metadataFormats) {
+#ifdef QT_DEBUG_AVF
+ qDebug() << "format: " << [format UTF8String];
+#endif
+ NSArray *metadataItems = [currentAsset metadataForFormat:format];
+ for (AVMetadataItem* item in metadataItems) {
+ NSString *keyString = [item commonKey];
+ NSString *value = [item stringValue];
+
+ if (keyString.length != 0) {
+ //Process "commonMetadata" tags here:
+ if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) {
+ m_tags.insert(QtMultimedia::MetaData::Title, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyCreator]) {
+ m_tags.insert(QtMultimedia::MetaData::Author, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) {
+ m_tags.insert(QtMultimedia::MetaData::SubTitle, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) {
+ m_tags.insert(QtMultimedia::MetaData::Description, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) {
+ m_tags.insert(QtMultimedia::MetaData::Publisher, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyContributor]) {
+ m_tags.insert(QtMultimedia::MetaData::ContributingArtist, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyCreationDate]) {
+ m_tags.insert(QtMultimedia::MetaData::Date, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyType]) {
+ m_tags.insert(QtMultimedia::MetaData::MediaType, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyLanguage]) {
+ m_tags.insert(QtMultimedia::MetaData::Language, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyCopyrights]) {
+ m_tags.insert(QtMultimedia::MetaData::Copyright, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyAlbumName]) {
+ m_tags.insert(QtMultimedia::MetaData::AlbumTitle, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyAuthor]) {
+ m_tags.insert(QtMultimedia::MetaData::Author, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) {
+ m_tags.insert(QtMultimedia::MetaData::AlbumArtist, QString([value UTF8String]));
+ } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) {
+ m_tags.insert(QtMultimedia::MetaData::PosterUrl, QString([value UTF8String]));
+ }
+ }
+
+ if ([format isEqualToString:AVMetadataFormatID3Metadata]) {
+ //TODO: Process ID3 metadata
+ } else if ([format isEqualToString:AVMetadataFormatiTunesMetadata]) {
+ //TODO: Process iTunes metadata
+ } else if ([format isEqualToString:AVMetadataFormatQuickTimeUserData]) {
+ //TODO: Process QuickTime metadata
+ }
+ }
+ }
+
+ Q_EMIT metaDataChanged();
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h
new file mode 100644
index 000000000..ec9666918
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFMEDIAPLAYERSERVICE_H
+#define AVFMEDIAPLAYERSERVICE_H
+
+#include <QtMultimedia/QMediaService>
+
+QT_BEGIN_NAMESPACE
+
+class AVFMediaPlayerSession;
+class AVFMediaPlayerControl;
+class AVFMediaPlayerMetaDataControl;
+class AVFVideoOutput;
+
+class AVFMediaPlayerService : public QMediaService
+{
+public:
+ explicit AVFMediaPlayerService(QObject *parent = 0);
+ ~AVFMediaPlayerService();
+
+ QMediaControl* requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+
+private:
+ AVFMediaPlayerSession *m_session;
+ AVFMediaPlayerControl *m_control;
+ QMediaControl *m_videoOutput;
+ AVFMediaPlayerMetaDataControl *m_playerMetaDataControl;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFMEDIAPLAYERSERVICE_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
new file mode 100644
index 000000000..2ea84758b
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfmediaplayerservice.h"
+#include "avfmediaplayersession.h"
+#include "avfmediaplayercontrol.h"
+#include "avfmediaplayermetadatacontrol.h"
+#include "avfvideooutput.h"
+#include "avfvideorenderercontrol.h"
+
+#ifndef QT_NO_WIDGETS
+#include "avfvideowidgetcontrol.h"
+#endif
+
+QT_USE_NAMESPACE
+
+AVFMediaPlayerService::AVFMediaPlayerService(QObject *parent)
+ : QMediaService(parent)
+ , m_videoOutput(0)
+{
+ m_session = new AVFMediaPlayerSession(this);
+ m_control = new AVFMediaPlayerControl(this);
+ m_control->setSession(m_session);
+ m_playerMetaDataControl = new AVFMediaPlayerMetaDataControl(m_session, this);
+
+ connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
+}
+
+AVFMediaPlayerService::~AVFMediaPlayerService()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ delete m_session;
+}
+
+QMediaControl *AVFMediaPlayerService::requestControl(const char *name)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << name;
+#endif
+
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+ return m_control;
+
+ if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
+ return m_playerMetaDataControl;
+
+ if (!m_videoOutput) {
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0)
+ m_videoOutput = new AVFVideoRendererControl(this);
+#ifndef QT_NO_WIDGETS
+ if (qstrcmp(name, QVideoWidgetControl_iid) == 0)
+ m_videoOutput = new AVFVideoWidgetControl(this);
+#endif
+ }
+ if (m_videoOutput) {
+ m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput));
+ return m_videoOutput;
+ }
+
+ return 0;
+}
+
+void AVFMediaPlayerService::releaseControl(QMediaControl *control)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << control;
+#endif
+
+ if (m_videoOutput == control) {
+ AVFVideoRendererControl *renderControl = qobject_cast<AVFVideoRendererControl*>(m_videoOutput);
+ if (renderControl)
+ renderControl->setSurface(0);
+ m_videoOutput = 0;
+ m_session->setVideoOutput(0);
+ delete control;
+ }
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h
new file mode 100644
index 000000000..464690675
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef AVFMEDIAPLAYERSERVICEPLUGIN_H
+#define AVFMEDIAPLAYERSERVICEPLUGIN_H
+
+#include <QtCore/qglobal.h>
+#include <QtMultimedia/qmediaserviceproviderplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class AVFMediaPlayerServicePlugin
+ : public QMediaServiceProviderPlugin
+ , public QMediaServiceSupportedFormatsInterface
+ , public QMediaServiceFeaturesInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
+ Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfmediaplayer.json")
+
+public:
+ explicit AVFMediaPlayerServicePlugin();
+
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+
+ QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
+ QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const;
+ QStringList supportedMimeTypes() const;
+
+private:
+ void buildSupportedTypes();
+
+ QStringList m_supportedMimeTypes;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFMEDIAPLAYERSERVICEPLUGIN_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm
new file mode 100644
index 000000000..cb75197c9
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfmediaplayerserviceplugin.h"
+#include <QtCore/QDebug>
+
+#include "avfmediaplayerservice.h"
+
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+AVFMediaPlayerServicePlugin::AVFMediaPlayerServicePlugin()
+{
+ buildSupportedTypes();
+}
+
+QMediaService *AVFMediaPlayerServicePlugin::create(const QString &key)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << "AVFMediaPlayerServicePlugin::create" << key;
+#endif
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
+ return new AVFMediaPlayerService;
+
+ qWarning() << "unsupported key: " << key;
+ return 0;
+}
+
+void AVFMediaPlayerServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+QMediaServiceProviderHint::Features AVFMediaPlayerServicePlugin::supportedFeatures(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_MEDIAPLAYER)
+ return QMediaServiceProviderHint::VideoSurface;
+ else
+ return QMediaServiceProviderHint::Features();
+}
+
+QtMultimedia::SupportEstimate AVFMediaPlayerServicePlugin::hasSupport(const QString &mimeType, const QStringList &codecs) const
+{
+ Q_UNUSED(codecs);
+
+ if (m_supportedMimeTypes.contains(mimeType))
+ return QtMultimedia::ProbablySupported;
+
+ return QtMultimedia::MaybeSupported;
+}
+
+QStringList AVFMediaPlayerServicePlugin::supportedMimeTypes() const
+{
+ return m_supportedMimeTypes;
+}
+
+void AVFMediaPlayerServicePlugin::buildSupportedTypes()
+{
+ //Populate m_supportedMimeTypes with mimetypes AVAsset supports
+ NSArray *mimeTypes = [AVURLAsset audiovisualMIMETypes];
+ for (NSString *mimeType in mimeTypes)
+ {
+ m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String]));
+ }
+#ifdef QT_DEBUG_AVF
+ qDebug() << "AVFMediaPlayerServicePlugin::buildSupportedTypes";
+ qDebug() << "Supported Types: " << m_supportedMimeTypes;
+#endif
+
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
new file mode 100644
index 000000000..3b70395f2
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFMEDIAPLAYERSESSION_H
+#define AVFMEDIAPLAYERSESSION_H
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QSet>
+#include <QtCore/QResource>
+
+#include <QtMultimedia/QMediaPlayerControl>
+#include <QtMultimedia/QMediaPlayer>
+
+QT_BEGIN_NAMESPACE
+
+class AVFMediaPlayerService;
+class AVFVideoOutput;
+
+class AVFMediaPlayerSession : public QObject
+{
+ Q_OBJECT
+public:
+ AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent = 0);
+ virtual ~AVFMediaPlayerSession();
+
+ void setVideoOutput(AVFVideoOutput *output);
+ void *currentAssetHandle();
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent &content, QIODevice *stream);
+
+ qint64 position() const;
+ qint64 duration() const;
+
+ int bufferStatus() const;
+
+ int volume() const;
+ bool isMuted() const;
+
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ bool isSeekable() const;
+ QMediaTimeRange availablePlaybackRanges() const;
+
+ qreal playbackRate() const;
+
+public Q_SLOTS:
+ void setPlaybackRate(qreal rate);
+
+ void setPosition(qint64 pos);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void processEOS();
+ void processLoadStateChange();
+ void processPositionChange();
+
+ void processCurrentItemChanged();
+
+Q_SIGNALS:
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool audioAvailable);
+ void videoAvailableChanged(bool videoAvailable);
+ void error(int error, const QString &errorString);
+
+private:
+ class ResourceHandler {
+ public:
+ ResourceHandler():resource(0) {}
+ ~ResourceHandler() { clear(); }
+ void setResourceFile(const QString &file) {
+ if (resource) {
+ if (resource->fileName() == file)
+ return;
+ delete resource;
+ rawData.clear();
+ }
+ resource = new QResource(file);
+ }
+ bool isValid() const { return resource && resource->isValid() && resource->data() != 0; }
+ const uchar *data() {
+ if (!isValid())
+ return 0;
+ if (resource->isCompressed()) {
+ if (rawData.size() == 0)
+ rawData = qUncompress(resource->data(), resource->size());
+ return (const uchar *)rawData.constData();
+ }
+ return resource->data();
+ }
+ qint64 size() {
+ if (data() == 0)
+ return 0;
+ return resource->isCompressed() ? rawData.size() : resource->size();
+ }
+ void clear() {
+ delete resource;
+ rawData.clear();
+ }
+ QResource *resource;
+ QByteArray rawData;
+ };
+
+ AVFMediaPlayerService *m_service;
+ AVFVideoOutput *m_videoOutput;
+
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ QIODevice *m_mediaStream;
+ QMediaContent m_resources;
+ ResourceHandler m_resourceHandler;
+
+ bool m_muted;
+ bool m_tryingAsync;
+ int m_volume;
+ qreal m_rate;
+
+ qint64 m_duration;
+ bool m_videoAvailable;
+ bool m_audioAvailable;
+
+ void *m_observer;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFMEDIAPLAYERSESSION_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
new file mode 100644
index 000000000..3fb935457
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
@@ -0,0 +1,832 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfmediaplayersession.h"
+#include "avfmediaplayerservice.h"
+#include "avfvideooutput.h"
+
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+//AVAsset Keys
+static NSString* const AVF_TRACKS_KEY = @"tracks";
+static NSString* const AVF_PLAYABLE_KEY = @"playable";
+
+//AVPlayerItem keys
+static NSString* const AVF_STATUS_KEY = @"status";
+
+//AVPlayer keys
+static NSString* const AVF_RATE_KEY = @"rate";
+static NSString* const AVF_CURRENT_ITEM_KEY = @"currentItem";
+
+static void *AVFMediaPlayerSessionObserverRateObservationContext = &AVFMediaPlayerSessionObserverRateObservationContext;
+static void *AVFMediaPlayerSessionObserverStatusObservationContext = &AVFMediaPlayerSessionObserverStatusObservationContext;
+static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext;
+
+@interface AVFMediaPlayerSessionObserver : NSObject
+{
+@private
+ AVFMediaPlayerSession *m_session;
+ AVPlayer *m_player;
+ AVPlayerItem *m_playerItem;
+ AVPlayerLayer *m_playerLayer;
+ NSURL *m_URL;
+ bool m_audioAvailable;
+ bool m_videoAvailable;
+}
+
+@property (readonly, getter=player) AVPlayer* m_player;
+@property (readonly, getter=playerItem) AVPlayerItem* m_playerItem;
+@property (readonly, getter=playerLayer) AVPlayerLayer* m_playerLayer;
+@property (readonly, getter=audioAvailable) bool m_audioAvailable;
+@property (readonly, getter=videoAvailable) bool m_videoAvailable;
+@property (readonly, getter=session) AVFMediaPlayerSession* m_session;
+
+- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session;
+- (void) setURL:(NSURL *)url;
+- (void) unloadMedia;
+- (void) prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys;
+- (void) assetFailedToPrepareForPlayback:(NSError *)error;
+- (void) playerItemDidReachEnd:(NSNotification *)notification;
+- (void) playerItemTimeJumped:(NSNotification *)notification;
+- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
+ change:(NSDictionary *)change context:(void *)context;
+- (void) detatchSession;
+- (void) dealloc;
+@end
+
+@implementation AVFMediaPlayerSessionObserver
+
+@synthesize m_player, m_playerItem, m_playerLayer, m_audioAvailable, m_videoAvailable, m_session;
+
+- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session
+{
+ if (!(self = [super init]))
+ return nil;
+
+ self->m_session = session;
+ return self;
+}
+
+- (void) setURL:(NSURL *)url
+{
+ if (m_URL != url)
+ {
+ [m_URL release];
+ m_URL = [url copy];
+
+ //Create an asset for inspection of a resource referenced by a given URL.
+ //Load the values for the asset keys "tracks", "playable".
+
+ AVURLAsset *asset = [AVURLAsset URLAssetWithURL:m_URL options:nil];
+ NSArray *requestedKeys = [NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil];
+
+ // Tells the asset to load the values of any of the specified keys that are not already loaded.
+ [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
+ ^{
+ dispatch_async( dispatch_get_main_queue(),
+ ^{
+ [self prepareToPlayAsset:asset withKeys:requestedKeys];
+ });
+ }];
+ }
+}
+
+- (void) unloadMedia
+{
+ [m_player setRate:0.0];
+ [m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:AVPlayerItemDidPlayToEndTimeNotification
+ object:m_playerItem];
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:AVPlayerItemTimeJumpedNotification
+ object:m_playerItem];
+ m_playerItem = 0;
+}
+
+- (void) prepareToPlayAsset:(AVURLAsset *)asset
+ withKeys:(NSArray *)requestedKeys
+{
+ //Make sure that the value of each key has loaded successfully.
+ for (NSString *thisKey in requestedKeys)
+ {
+ NSError *error = nil;
+ AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << [thisKey UTF8String] << " status: " << keyStatus;
+#endif
+ if (keyStatus == AVKeyValueStatusFailed)
+ {
+ [self assetFailedToPrepareForPlayback:error];
+ return;
+ }
+ }
+
+ //Use the AVAsset playable property to detect whether the asset can be played.
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << "isPlayable: " << [asset isPlayable];
+#endif
+ if (!asset.playable)
+ {
+ //Generate an error describing the failure.
+ NSString *localizedDescription = NSLocalizedString(@"Item cannot be played", @"Item cannot be played description");
+ NSString *localizedFailureReason = NSLocalizedString(@"The assets tracks were loaded, but could not be made playable.", @"Item cannot be played failure reason");
+ NSDictionary *errorDict = [NSDictionary dictionaryWithObjectsAndKeys:
+ localizedDescription, NSLocalizedDescriptionKey,
+ localizedFailureReason, NSLocalizedFailureReasonErrorKey,
+ nil];
+ NSError *assetCannotBePlayedError = [NSError errorWithDomain:@"StitchedStreamPlayer" code:0 userInfo:errorDict];
+
+ [self assetFailedToPrepareForPlayback:assetCannotBePlayedError];
+
+ return;
+ }
+
+ m_audioAvailable = false;
+ m_videoAvailable = false;
+
+ //Check each track of asset for audio and video content
+ NSArray *tracks = [asset tracks];
+ for (AVAssetTrack *track in tracks) {
+ if ([track hasMediaCharacteristic:AVMediaCharacteristicAudible])
+ m_audioAvailable = true;
+ if ([track hasMediaCharacteristic:AVMediaCharacteristicVisual])
+ m_videoAvailable = true;
+ }
+
+ //At this point we're ready to set up for playback of the asset.
+ //Stop observing our prior AVPlayerItem, if we have one.
+ if (m_playerItem)
+ {
+ //Remove existing player item key value observers and notifications.
+ [self unloadMedia];
+ }
+
+ //Create a new instance of AVPlayerItem from the now successfully loaded AVAsset.
+ m_playerItem = [AVPlayerItem playerItemWithAsset:asset];
+
+ //Observe the player item "status" key to determine when it is ready to play.
+ [m_playerItem addObserver:self
+ forKeyPath:AVF_STATUS_KEY
+ options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
+ context:AVFMediaPlayerSessionObserverStatusObservationContext];
+
+ //When the player item has played to its end time we'll toggle
+ //the movie controller Pause button to be the Play button
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(playerItemDidReachEnd:)
+ name:AVPlayerItemDidPlayToEndTimeNotification
+ object:m_playerItem];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(playerItemTimeJumped:)
+ name:AVPlayerItemTimeJumpedNotification
+ object:m_playerItem];
+
+
+ //Clean up old player if we have one
+ if (m_player) {
+ [m_player setRate:0.0];
+ [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY];
+ [m_player removeObserver:self forKeyPath:AVF_RATE_KEY];
+ [m_player release];
+ m_player = 0;
+ [m_playerLayer release];
+ m_playerLayer = 0; //Will have been released
+ }
+
+ //Get a new AVPlayer initialized to play the specified player item.
+ m_player = [AVPlayer playerWithPlayerItem:m_playerItem];
+ [m_player retain];
+
+ //Set the initial volume on new player object
+ if (self.session)
+ m_player.volume = m_session->volume() / 100.0f;
+
+ //Create a new player layer if we don't have one already
+ if (!m_playerLayer)
+ {
+ m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:m_player];
+ [m_playerLayer retain];
+ m_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
+
+ //Get the native size of the new item, and reset the bounds of the player layer
+ AVAsset *asset = m_playerItem.asset;
+ if (asset) {
+ NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
+ if ([tracks count]) {
+ AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
+ m_playerLayer.anchorPoint = NSMakePoint(0.0f, 0.0f);
+ m_playerLayer.bounds = NSMakeRect(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
+ }
+ }
+
+ }
+
+ //Observe the AVPlayer "currentItem" property to find out when any
+ //AVPlayer replaceCurrentItemWithPlayerItem: replacement will/did
+ //occur.
+ [m_player addObserver:self
+ forKeyPath:AVF_CURRENT_ITEM_KEY
+ options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
+ context:AVFMediaPlayerSessionObserverCurrentItemObservationContext];
+
+ //Observe the AVPlayer "rate" property to update the scrubber control.
+ [m_player addObserver:self
+ forKeyPath:AVF_RATE_KEY
+ options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
+ context:AVFMediaPlayerSessionObserverRateObservationContext];
+
+}
+
+-(void) assetFailedToPrepareForPlayback:(NSError *)error
+{
+ Q_UNUSED(error)
+ //TODO: Let the session know that the assest failed to prepare for playback
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << [[error localizedDescription] UTF8String];
+ qDebug() << [[error localizedFailureReason] UTF8String];
+ qDebug() << [[error localizedRecoverySuggestion] UTF8String];
+#endif
+}
+
+- (void) playerItemDidReachEnd:(NSNotification *)notification
+{
+ Q_UNUSED(notification)
+ if (self.session)
+ QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection);
+}
+
+- (void) playerItemTimeJumped:(NSNotification *)notification
+{
+ Q_UNUSED(notification)
+ if (self.session)
+ QMetaObject::invokeMethod(m_session, "processPositionChange", Qt::AutoConnection);
+}
+
+- (void) observeValueForKeyPath:(NSString*) path
+ ofObject:(id)object
+ change:(NSDictionary*)change
+ context:(void*)context
+{
+ //AVPlayerItem "status" property value observer.
+ if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
+ {
+ AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ switch (status)
+ {
+ //Indicates that the status of the player is not yet known because
+ //it has not tried to load new media resources for playback
+ case AVPlayerStatusUnknown:
+ {
+ //QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
+ }
+ break;
+
+ case AVPlayerStatusReadyToPlay:
+ {
+ //Once the AVPlayerItem becomes ready to play, i.e.
+ //[playerItem status] == AVPlayerItemStatusReadyToPlay,
+ //its duration can be fetched from the item.
+ if (self.session)
+ QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
+ }
+ break;
+
+ case AVPlayerStatusFailed:
+ {
+ AVPlayerItem *playerItem = (AVPlayerItem *)object;
+ [self assetFailedToPrepareForPlayback:playerItem.error];
+
+ if (self.session)
+ QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
+ }
+ break;
+ }
+ }
+ //AVPlayer "rate" property value observer.
+ else if (context == AVFMediaPlayerSessionObserverRateObservationContext)
+ {
+ //QMetaObject::invokeMethod(m_session, "setPlaybackRate", Qt::AutoConnection, Q_ARG(qreal, [m_player rate]));
+ }
+ //AVPlayer "currentItem" property observer.
+ //Called when the AVPlayer replaceCurrentItemWithPlayerItem:
+ //replacement will/did occur.
+ else if (context == AVFMediaPlayerSessionObserverCurrentItemObservationContext)
+ {
+ AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey];
+ if (m_playerItem != newPlayerItem);
+ {
+ m_playerItem = newPlayerItem;
+
+ //Get the native size of the new item, and reset the bounds of the player layer
+ //AVAsset *asset = m_playerItem.asset;
+ AVAsset *asset = [m_playerItem asset];
+ if (asset) {
+ NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
+ if ([tracks count]) {
+ AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
+ m_playerLayer.anchorPoint = NSMakePoint(0.0f, 0.0f);
+ m_playerLayer.bounds = NSMakeRect(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
+ }
+ }
+
+ }
+ if (self.session)
+ QMetaObject::invokeMethod(m_session, "processCurrentItemChanged", Qt::AutoConnection);
+ }
+ else
+ {
+ [super observeValueForKeyPath:path ofObject:object change:change context:context];
+ }
+}
+
+- (void) detatchSession
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ m_session = 0;
+}
+
+- (void) dealloc
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY];
+ [m_player removeObserver:self forKeyPath:AVF_RATE_KEY];
+ [m_player release];
+
+ [m_playerLayer release];
+
+ [self unloadMedia];
+ [m_URL release];
+
+ [super dealloc];
+}
+
+@end
+
+AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent)
+ : QObject(parent)
+ , m_service(service)
+ , m_videoOutput(0)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_mediaStream(0)
+ , m_muted(false)
+ , m_tryingAsync(false)
+ , m_volume(100)
+ , m_rate(1.0)
+ , m_duration(0)
+ , m_videoAvailable(false)
+ , m_audioAvailable(false)
+{
+ m_observer = [[AVFMediaPlayerSessionObserver alloc] initWithMediaPlayerSession:this];
+}
+
+AVFMediaPlayerSession::~AVFMediaPlayerSession()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ //Detatch the session from the sessionObserver (which could still be alive trying to communicate with this session).
+ [(AVFMediaPlayerSessionObserver*)m_observer detatchSession];
+ [(AVFMediaPlayerSessionObserver*)m_observer release];
+}
+
+void AVFMediaPlayerSession::setVideoOutput(AVFVideoOutput *output)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << output;
+#endif
+
+ if (m_videoOutput == output)
+ return;
+
+ //Set the current ouput layer to null to stop rendering
+ if (m_videoOutput) {
+ m_videoOutput->setLayer(0);
+ }
+
+ m_videoOutput = output;
+
+ if (m_videoOutput && m_state != QMediaPlayer::StoppedState)
+ m_videoOutput->setLayer([(AVFMediaPlayerSessionObserver*)m_observer playerLayer]);
+}
+
+void *AVFMediaPlayerSession::currentAssetHandle()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ AVAsset *currentAsset = [[(AVFMediaPlayerSessionObserver*)m_observer playerItem] asset];
+ return currentAsset;
+}
+
+QMediaPlayer::State AVFMediaPlayerSession::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus AVFMediaPlayerSession::mediaStatus() const
+{
+ return m_mediaStatus;
+}
+
+QMediaContent AVFMediaPlayerSession::media() const
+{
+ return m_resources;
+}
+
+const QIODevice *AVFMediaPlayerSession::mediaStream() const
+{
+ return m_mediaStream;
+}
+
+void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << content.canonicalUrl();
+#endif
+
+ m_resources = content;
+ m_mediaStream = stream;
+
+ QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
+
+ if (content.isNull() || content.canonicalUrl().isEmpty()) {
+ [(AVFMediaPlayerSessionObserver*)m_observer unloadMedia];
+ m_mediaStatus = QMediaPlayer::NoMedia;
+ if (m_state != QMediaPlayer::StoppedState)
+ Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
+
+ if (m_mediaStatus != oldMediaStatus)
+ Q_EMIT mediaStatusChanged(m_mediaStatus);
+ Q_EMIT positionChanged(position());
+ return;
+ } else {
+
+ m_mediaStatus = QMediaPlayer::LoadingMedia;
+ if (m_mediaStatus != oldMediaStatus)
+ Q_EMIT mediaStatusChanged(m_mediaStatus);
+ }
+ //Load AVURLAsset
+ //initialize asset using content's URL
+ NSString *urlString = [NSString stringWithUTF8String:content.canonicalUrl().toEncoded().constData()];
+ NSURL *url = [NSURL URLWithString:urlString];
+ [(AVFMediaPlayerSessionObserver*)m_observer setURL:url];
+}
+
+qint64 AVFMediaPlayerSession::position() const
+{
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+
+ if (!playerItem)
+ return 0;
+
+ CMTime time = [playerItem currentTime];
+ return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f);
+}
+
+qint64 AVFMediaPlayerSession::duration() const
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+
+ if (!playerItem)
+ return 0;
+
+ CMTime time = [playerItem duration];
+ return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f);
+}
+
+int AVFMediaPlayerSession::bufferStatus() const
+{
+ //BUG: bufferStatus may be relevant?
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ return 100;
+}
+
+int AVFMediaPlayerSession::volume() const
+{
+ return m_volume;
+}
+
+bool AVFMediaPlayerSession::isMuted() const
+{
+ return m_muted;
+}
+
+bool AVFMediaPlayerSession::isAudioAvailable() const
+{
+ return [(AVFMediaPlayerSessionObserver*)m_observer audioAvailable];
+}
+
+bool AVFMediaPlayerSession::isVideoAvailable() const
+{
+ return [(AVFMediaPlayerSessionObserver*)m_observer videoAvailable];
+}
+
+bool AVFMediaPlayerSession::isSeekable() const
+{
+ return true;
+}
+
+QMediaTimeRange AVFMediaPlayerSession::availablePlaybackRanges() const
+{
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+
+ if (playerItem) {
+ QMediaTimeRange timeRanges;
+
+ NSArray *ranges = [playerItem loadedTimeRanges];
+ for (NSValue *timeRange in ranges) {
+ CMTimeRange currentTimeRange = [timeRange CMTimeRangeValue];
+ qint64 startTime = qint64(float(currentTimeRange.start.value) / currentTimeRange.start.timescale * 1000.0);
+ timeRanges.addInterval(startTime, startTime + qint64(float(currentTimeRange.duration.value) / currentTimeRange.duration.timescale * 1000.0));
+ }
+ if (!timeRanges.isEmpty())
+ return timeRanges;
+ }
+ return QMediaTimeRange(0, duration());
+}
+
+qreal AVFMediaPlayerSession::playbackRate() const
+{
+ return m_rate;
+}
+
+void AVFMediaPlayerSession::setPlaybackRate(qreal rate)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << rate;
+#endif
+
+ if (qFuzzyCompare(m_rate, rate))
+ return;
+
+ m_rate = rate;
+
+ AVPlayer *player = [(AVFMediaPlayerSessionObserver*)m_observer player];
+
+ if (player != 0 && m_state == QMediaPlayer::PlayingState) {
+ [player setRate:m_rate];
+ }
+}
+
+void AVFMediaPlayerSession::setPosition(qint64 pos)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << pos;
+#endif
+
+ if ( !isSeekable() || pos == position())
+ return;
+
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+
+ if (!playerItem)
+ return;
+
+ if (duration() > 0)
+ pos = qMin(pos, duration());
+
+ CMTime newTime = [playerItem currentTime];
+ newTime.value = (pos / 1000.0f) * newTime.timescale;
+ [playerItem seekToTime:newTime];
+
+ //reset the EndOfMedia status position is changed after playback is finished
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia)
+ processLoadStateChange();
+}
+
+void AVFMediaPlayerSession::play()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << "currently: " << m_state;
+#endif
+
+ if (m_state == QMediaPlayer::PlayingState)
+ return;
+
+ m_state = QMediaPlayer::PlayingState;
+
+ if (m_videoOutput) {
+ m_videoOutput->setLayer([(AVFMediaPlayerSessionObserver*)m_observer playerLayer]);
+ }
+
+ //reset the EndOfMedia status if the same file is played again
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
+ setPosition(0);
+ processLoadStateChange();
+ }
+
+ if (m_mediaStatus == QMediaPlayer::LoadedMedia || m_mediaStatus == QMediaPlayer::BufferedMedia)
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] play];
+
+ //processLoadStateChange();
+ Q_EMIT stateChanged(m_state);
+}
+
+void AVFMediaPlayerSession::pause()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << "currently: " << m_state;
+#endif
+
+ if (m_state == QMediaPlayer::PausedState)
+ return;
+
+ m_state = QMediaPlayer::PausedState;
+
+ if (m_videoOutput) {
+ m_videoOutput->setLayer([(AVFMediaPlayerSessionObserver*)m_observer playerLayer]);
+ }
+
+ //reset the EndOfMedia status if the same file is played again
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia)
+ processLoadStateChange();
+
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] pause];
+
+ //processLoadStateChange();
+ Q_EMIT stateChanged(m_state);
+}
+
+void AVFMediaPlayerSession::stop()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << "currently: " << m_state;
+#endif
+
+ if (m_state == QMediaPlayer::StoppedState)
+ return;
+
+ m_state = QMediaPlayer::StoppedState;
+ m_rate = 0.0f;
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] setRate:m_rate];
+ setPosition(0);
+
+ if (m_videoOutput) {
+ m_videoOutput->setLayer(0);
+ }
+
+ processLoadStateChange();
+ Q_EMIT stateChanged(m_state);
+ Q_EMIT positionChanged(position());
+}
+
+void AVFMediaPlayerSession::setVolume(int volume)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << volume;
+#endif
+
+ if (m_volume == volume)
+ return;
+
+ m_volume = volume;
+
+ AVPlayer *player = [(AVFMediaPlayerSessionObserver*)m_observer player];
+ if (player) {
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] setVolume:m_volume / 100.0f];
+ }
+
+ Q_EMIT volumeChanged(m_volume);
+}
+
+void AVFMediaPlayerSession::setMuted(bool muted)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << muted;
+#endif
+ if (m_muted == muted)
+ return;
+
+ m_muted = muted;
+
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] setMuted:m_muted];
+
+ Q_EMIT mutedChanged(muted);
+}
+
+void AVFMediaPlayerSession::processEOS()
+{
+ //AVPlayerItem has reached end of track/stream
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ Q_EMIT positionChanged(position());
+ m_mediaStatus = QMediaPlayer::EndOfMedia;
+
+ Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
+ Q_EMIT mediaStatusChanged(m_mediaStatus);
+}
+
+void AVFMediaPlayerSession::processLoadStateChange()
+{
+ AVPlayerStatus currentStatus = [[(AVFMediaPlayerSessionObserver*)m_observer player] status];
+
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << currentStatus;
+#endif
+
+ QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
+ bool isPlaying = (m_state != QMediaPlayer::StoppedState);
+
+ if (currentStatus == AVPlayerStatusReadyToPlay) {
+ qint64 currentDuration = duration();
+ if (m_duration != currentDuration)
+ Q_EMIT durationChanged(m_duration = currentDuration);
+
+ if (m_audioAvailable != isAudioAvailable())
+ Q_EMIT audioAvailableChanged(m_audioAvailable = !m_audioAvailable);
+
+ if (m_videoAvailable != isVideoAvailable())
+ Q_EMIT videoAvailableChanged(m_videoAvailable = !m_videoAvailable);
+
+ newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
+
+ if (m_state == QMediaPlayer::PlayingState && [(AVFMediaPlayerSessionObserver*)m_observer player]) {
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] setRate:m_rate];
+ [[(AVFMediaPlayerSessionObserver*)m_observer player] play];
+ }
+
+ } else {
+ Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media"));
+ Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
+ Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
+
+ return;
+ }
+
+ if (newStatus != m_mediaStatus)
+ Q_EMIT mediaStatusChanged(m_mediaStatus = newStatus);
+}
+
+void AVFMediaPlayerSession::processPositionChange()
+{
+ Q_EMIT positionChanged(position());
+}
+
+void AVFMediaPlayerSession::processCurrentItemChanged()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+
+ AVPlayerLayer *playerLayer = [(AVFMediaPlayerSessionObserver*)m_observer playerLayer];
+
+ if (m_videoOutput && m_state != QMediaPlayer::StoppedState) {
+ m_videoOutput->setLayer(playerLayer);
+ }
+
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h
new file mode 100644
index 000000000..01c39c013
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFVIDEOFRAMERENDERER_H
+#define AVFVIDEOFRAMERENDERER_H
+
+#include <QtCore/QObject>
+#include <QtGui/QImage>
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QSize>
+
+@class CARenderer;
+@class AVPlayerLayer;
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLFramebufferObject;
+class QWindow;
+class QOpenGLContext;
+class QAbstractVideoSurface;
+class QGLWidget;
+
+class AVFVideoFrameRenderer : public QObject
+{
+public:
+ AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent = 0);
+#ifndef QT_NO_WIDGETS
+ AVFVideoFrameRenderer(QGLWidget *glWidget, const QSize &size, QObject *parent = 0);
+#endif
+
+ virtual ~AVFVideoFrameRenderer();
+
+ GLuint renderLayerToTexture(AVPlayerLayer *layer);
+ QImage renderLayerToImage(AVPlayerLayer *layer);
+
+private:
+ QOpenGLFramebufferObject* initRenderer(AVPlayerLayer *layer);
+ void renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo);
+
+ CARenderer *m_videoLayerRenderer;
+#ifndef QT_NO_WIDGETS
+ QGLWidget *m_glWidget;
+#endif
+ QAbstractVideoSurface *m_surface;
+ QOpenGLFramebufferObject *m_fbo[2];
+ QWindow *m_offscreenSurface;
+ QOpenGLContext *m_glContext;
+ QSize m_targetSize;
+
+ uint m_currentBuffer;
+ bool m_isContextShared;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFVIDEOFRAMERENDERER_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
new file mode 100644
index 000000000..ea787dc16
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfvideoframerenderer.h"
+
+#include <QtMultimedia/qabstractvideosurface.h>
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QWindow>
+
+#ifndef QT_NO_WIDGETS
+#include <QtOpenGL/QGLWidget>
+#endif
+
+#ifdef QT_DEBUG_AVF
+#include <QtCore/qdebug.h>
+#endif
+
+#import <CoreVideo/CVBase.h>
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent)
+ : QObject(parent)
+ , m_videoLayerRenderer(0)
+ , m_surface(surface)
+ , m_glContext(0)
+ , m_currentBuffer(1)
+ , m_isContextShared(true)
+{
+ m_fbo[0] = 0;
+ m_fbo[1] = 0;
+
+ //Create Hidden QWindow surface to create context in this thread
+ m_offscreenSurface = new QWindow();
+ m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface);
+ //Needs geometry to be a valid surface, but size is not important
+ m_offscreenSurface->setGeometry(0, 0, 1, 1);
+ m_offscreenSurface->create();
+}
+#ifndef QT_NO_WIDGETS
+AVFVideoFrameRenderer::AVFVideoFrameRenderer(QGLWidget *glWidget, const QSize &size, QObject *parent)
+ : QObject(parent)
+ , m_videoLayerRenderer(0)
+ , m_glWidget(glWidget)
+ , m_surface(0)
+ , m_offscreenSurface(0)
+ , m_glContext(0)
+ , m_targetSize(size)
+ , m_currentBuffer(1)
+ , m_isContextShared(true)
+{
+ m_fbo[0] = 0;
+ m_fbo[1] = 0;
+
+ //Create Hidden QWindow surface to create context in this thread
+ m_offscreenSurface = new QWindow();
+ m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface);
+ //Needs geometry to be a valid surface, but size is not important
+ m_offscreenSurface->setGeometry(0, 0, 1, 1);
+ m_offscreenSurface->create();
+
+
+}
+#endif
+
+AVFVideoFrameRenderer::~AVFVideoFrameRenderer()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+
+ [m_videoLayerRenderer release];
+ delete m_fbo[0];
+ delete m_fbo[1];
+ delete m_offscreenSurface;
+ delete m_glContext;
+}
+
+GLuint AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer)
+{
+ //Is layer valid
+ if (!layer)
+ return 0;
+
+ //If the glContext isn't shared, it doesn't make sense to return a texture for us
+ if (m_offscreenSurface && !m_isContextShared)
+ return 0;
+
+ QOpenGLFramebufferObject *fbo = initRenderer(layer);
+
+ if (!fbo)
+ return 0;
+
+ renderLayerToFBO(layer, fbo);
+
+ return fbo->texture();
+}
+
+QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer)
+{
+ //Is layer valid
+ if (!layer) {
+ return QImage();
+ }
+
+ QOpenGLFramebufferObject *fbo = initRenderer(layer);
+
+ if (!fbo)
+ return QImage();
+
+ renderLayerToFBO(layer, fbo);
+
+ return fbo->toImage();
+}
+
+QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *layer)
+{
+
+ //Get size from AVPlayerLayer
+ m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height);
+
+ //Make sure we have an OpenGL context to make current
+ if (!m_glContext) {
+ //Create OpenGL context and set share context from surface
+ QOpenGLContext *shareContext = 0;
+ if (m_surface) {
+ //QOpenGLContext *renderThreadContext = 0;
+ shareContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
+#ifndef QT_NO_WIDGETS
+ } else {
+ shareContext = m_glWidget->context()->contextHandle();
+#endif
+ }
+ m_glContext = new QOpenGLContext();
+ m_glContext->setFormat(m_offscreenSurface->requestedFormat());
+
+ if (shareContext) {
+ m_glContext->setShareContext(shareContext);
+ m_isContextShared = true;
+ } else {
+#ifdef QT_DEBUG_AVF
+ qWarning("failed to get Render Thread context");
+ m_isContextShared = false;
+#endif
+ }
+ if (!m_glContext->create()) {
+ qWarning("failed to create QOpenGLContext");
+ return 0;
+ }
+ }
+
+ //Need current context
+ m_glContext->makeCurrent(m_offscreenSurface);
+
+ //Create the CARenderer if needed
+ if (!m_videoLayerRenderer) {
+ m_videoLayerRenderer = [CARenderer rendererWithCGLContext: CGLGetCurrentContext() options: nil];
+ [m_videoLayerRenderer retain];
+ }
+
+ //Set/Change render source if needed
+ if (m_videoLayerRenderer.layer != layer) {
+ m_videoLayerRenderer.layer = layer;
+ m_videoLayerRenderer.bounds = layer.bounds;
+ }
+
+ //Do we have FBO's already?
+ if ((!m_fbo[0] && !m_fbo[0]) || (m_fbo[0]->size() != m_targetSize)) {
+ delete m_fbo[0];
+ delete m_fbo[1];
+ m_fbo[0] = new QOpenGLFramebufferObject(m_targetSize);
+ m_fbo[1] = new QOpenGLFramebufferObject(m_targetSize);
+ }
+
+ //Switch buffer target
+ m_currentBuffer = !m_currentBuffer;
+ return m_fbo[m_currentBuffer];
+}
+
+void AVFVideoFrameRenderer::renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo)
+{
+ //Start Rendering
+ //NOTE: This rendering method will NOT work on iOS as there is no CARenderer in iOS
+ if (!fbo->bind()) {
+ qWarning("AVFVideoRender FBO failed to bind");
+ return;
+ }
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glViewport(0, 0, m_targetSize.width(), m_targetSize.height());
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glOrtho(0.0f, m_targetSize.width(), m_targetSize.height(), 0.0f, 0.0f, 1.0f);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL];
+ [m_videoLayerRenderer addUpdateRect:layer.bounds];
+ [m_videoLayerRenderer render];
+ [m_videoLayerRenderer endFrame];
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glFinish(); //Rendering needs to be done before passing texture to video frame
+
+ fbo->release();
+
+ m_glContext->doneCurrent();
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideooutput.h b/src/plugins/avfoundation/mediaplayer/avfvideooutput.h
new file mode 100644
index 000000000..1d9eb2188
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideooutput.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFVIDEOOUTPUT_H
+#define AVFVIDEOOUTPUT_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class AVFVideoOutput
+{
+public:
+ virtual ~AVFVideoOutput() {}
+ virtual void setLayer(void *playerLayer) = 0;
+};
+
+#define AVFVideoOutput_iid \
+ "org.qt-project.qt.AVFVideoOuput/5.0"
+Q_DECLARE_INTERFACE(AVFVideoOutput, AVFVideoOutput_iid)
+
+QT_END_NAMESPACE
+
+#endif // AVFVIDEOOUTPUT_H
diff --git a/tests/auto/cmake/test_modules/main.cpp b/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm
index 8d146d06b..1055169f9 100644
--- a/tests/auto/cmake/test_modules/main.cpp
+++ b/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the test suite of the Qt Toolkit.
+** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,14 +39,6 @@
**
****************************************************************************/
-#include <QCamera>
-#include <QVideoWidget>
+#include "avfvideooutput.h"
-int main(int argc, char **argv)
-{
- QCamera camera;
-
- QVideoWidget videoWidget;
-
- return 0;
-}
+QT_USE_NAMESPACE
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h
new file mode 100644
index 000000000..19916bd1a
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFVIDEORENDERERCONTROL_H
+#define AVFVIDEORENDERERCONTROL_H
+
+#include <QtMultimedia/QVideoRendererControl>
+#include <QtCore/QMutex>
+#include <QtCore/QSize>
+
+#include "avfvideooutput.h"
+
+#import <CoreVideo/CVBase.h>
+
+QT_BEGIN_NAMESPACE
+
+class AVFDisplayLink;
+class AVFVideoFrameRenderer;
+
+class AVFVideoRendererControl : public QVideoRendererControl, public AVFVideoOutput
+{
+ Q_OBJECT
+ Q_INTERFACES(AVFVideoOutput)
+public:
+ explicit AVFVideoRendererControl(QObject *parent = 0);
+ virtual ~AVFVideoRendererControl();
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+ void setLayer(void *playerLayer);
+
+private Q_SLOTS:
+ void updateVideoFrame(const CVTimeStamp &ts);
+
+Q_SIGNALS:
+ void surfaceChanged(QAbstractVideoSurface *surface);
+
+private:
+ void setupVideoOutput();
+
+ QMutex m_mutex;
+ QAbstractVideoSurface *m_surface;
+
+ void *m_playerLayer;
+
+ AVFVideoFrameRenderer *m_frameRenderer;
+ AVFDisplayLink *m_displayLink;
+ QSize m_nativeSize;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFVIDEORENDERERCONTROL_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
new file mode 100644
index 000000000..e7d99cd00
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfvideorenderercontrol.h"
+#include "avfdisplaylink.h"
+#include "avfvideoframerenderer.h"
+
+#include <QtMultimedia/qabstractvideobuffer.h>
+#include <QtMultimedia/qabstractvideosurface.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+#include <QtCore/qdebug.h>
+
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+class TextureVideoBuffer : public QAbstractVideoBuffer
+{
+public:
+ TextureVideoBuffer(GLuint textureId)
+ : QAbstractVideoBuffer(GLTextureHandle)
+ , m_textureId(textureId)
+ {}
+
+ virtual ~TextureVideoBuffer() {}
+
+ MapMode mapMode() const { return NotMapped; }
+ uchar *map(MapMode, int*, int*) { return 0; }
+ void unmap() {}
+
+ QVariant handle() const
+ {
+ return QVariant::fromValue<unsigned int>(m_textureId);
+ }
+
+private:
+ GLuint m_textureId;
+};
+
+AVFVideoRendererControl::AVFVideoRendererControl(QObject *parent)
+ : QVideoRendererControl(parent)
+ , m_surface(0)
+ , m_playerLayer(0)
+ , m_frameRenderer(0)
+
+{
+ m_displayLink = new AVFDisplayLink(this);
+ connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
+}
+
+AVFVideoRendererControl::~AVFVideoRendererControl()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ m_displayLink->stop();
+ if (m_playerLayer)
+ [(AVPlayerLayer*)m_playerLayer release];
+}
+
+QAbstractVideoSurface *AVFVideoRendererControl::surface() const
+{
+ return m_surface;
+}
+
+void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << "Set video surface" << surface;
+#endif
+
+ //When we have a valid surface, we can setup a frame renderer
+ //and schedule surface updates with the display link.
+ if (surface == m_surface)
+ return;
+
+ QMutexLocker locker(&m_mutex);
+
+ if (m_surface && m_surface->isActive())
+ m_surface->stop();
+
+ m_surface = surface;
+
+ //If the surface changed, then the current frame renderer is no longer valid
+ if (m_frameRenderer)
+ delete m_frameRenderer;
+
+ //If there is now no surface to render too
+ if (m_surface == 0) {
+ m_displayLink->stop();
+ return;
+ }
+
+ //Surface changed, so we need a new frame renderer
+ m_frameRenderer = new AVFVideoFrameRenderer(m_surface, this);
+
+ //If we already have a layer, but changed surfaces start rendering again
+ if (m_playerLayer && !m_displayLink->isActive()) {
+ m_displayLink->start();
+ }
+
+}
+
+void AVFVideoRendererControl::setLayer(void *playerLayer)
+{
+ if (m_playerLayer == playerLayer)
+ return;
+
+ [(AVPlayerLayer*)playerLayer retain];
+ [(AVPlayerLayer*)m_playerLayer release];
+
+ m_playerLayer = playerLayer;
+
+ //If there is no layer to render, stop scheduling updates
+ if (m_playerLayer == 0) {
+ m_displayLink->stop();
+ return;
+ }
+
+ setupVideoOutput();
+
+ //If we now have both a valid surface and layer, start scheduling updates
+ if (m_surface && !m_displayLink->isActive()) {
+ m_displayLink->start();
+ }
+}
+
+void AVFVideoRendererControl::updateVideoFrame(const CVTimeStamp &ts)
+{
+ Q_UNUSED(ts)
+
+ AVPlayerLayer *playerLayer = (AVPlayerLayer*)m_playerLayer;
+
+ if (!playerLayer) {
+ qWarning("updateVideoFrame called without AVPlayerLayer (which shouldn't happen");
+ return;
+ }
+
+ if (!playerLayer.readyForDisplay)
+ return;
+
+ GLuint textureId = m_frameRenderer->renderLayerToTexture(playerLayer);
+
+ //Make sure we got a valid texture
+ if (textureId == 0) {
+ qWarning("renderLayerToTexture failed");
+ return;
+ }
+
+ QAbstractVideoBuffer *buffer = new TextureVideoBuffer(textureId);
+ QVideoFrame frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_BGR32);
+
+ if (m_surface && frame.isValid()) {
+ if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat())
+ m_surface->stop();
+
+ if (!m_surface->isActive()) {
+ QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::GLTextureHandle);
+
+ if (!m_surface->start(format)) {
+ qWarning("Failed to activate video surface");
+ }
+ }
+
+ if (m_surface->isActive())
+ m_surface->present(frame);
+ }
+}
+
+void AVFVideoRendererControl::setupVideoOutput()
+{
+ AVPlayerLayer *playerLayer = (AVPlayerLayer*)m_playerLayer;
+ if (playerLayer)
+ m_nativeSize = QSize(playerLayer.bounds.size.width, playerLayer.bounds.size.height);
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.h b/src/plugins/avfoundation/mediaplayer/avfvideowidget.h
new file mode 100644
index 000000000..57b1fe96b
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidget.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFVIDEOWIDGET_H
+#define AVFVIDEOWIDGET_H
+
+#include <QtOpenGL/QGLWidget>
+#include <QtGui/QMatrix4x4>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+
+class AVFVideoWidget : public QGLWidget
+{
+public:
+ AVFVideoWidget(QWidget *parent, const QGLFormat &format);
+ virtual ~AVFVideoWidget();
+
+ void initializeGL();
+ void resizeGL(int w, int h);
+ void paintGL();
+
+ void setTexture(GLuint texture);
+
+ QSize sizeHint() const;
+ void setNativeSize(const QSize &size);
+
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+private:
+ QRect displayRect() const;
+
+ GLuint m_textureId;
+ QSize m_nativeSize;
+ Qt::AspectRatioMode m_aspectRatioMode;
+
+ QOpenGLShaderProgram *m_shaderProgram;
+ QMatrix4x4 m_transformMatrix;
+
+ int m_matrixLocation;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFVIDEOWIDGET_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
new file mode 100644
index 000000000..307539851
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfvideowidget.h"
+#include <QtCore/QDebug>
+#include <QtGui/QOpenGLShaderProgram>
+
+QT_USE_NAMESPACE
+
+AVFVideoWidget::AVFVideoWidget(QWidget *parent, const QGLFormat &format)
+ : QGLWidget(format, parent)
+ , m_textureId(0)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_shaderProgram(0)
+{
+ setAutoFillBackground(false);
+}
+
+AVFVideoWidget::~AVFVideoWidget()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ delete m_shaderProgram;
+}
+
+void AVFVideoWidget::initializeGL()
+{
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ m_shaderProgram = new QOpenGLShaderProgram;
+
+ static const char *textureVertexProgram =
+ "uniform highp mat4 matrix;\n"
+ "attribute highp vec3 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = matrix * vec4(vertexCoordEntry, 1);\n"
+ "}\n";
+
+ static const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, textureCoord);\n"
+ "}\n";
+
+ m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_shaderProgram->link();
+}
+
+void AVFVideoWidget::resizeGL(int w, int h)
+{
+ glViewport(0, 0, GLsizei(w), GLsizei(h));
+ updateGL();
+}
+
+void AVFVideoWidget::paintGL()
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+ if (!m_textureId)
+ return;
+
+ QRect targetRect = displayRect();
+ int x1 = targetRect.left();
+ int x2 = targetRect.right();
+ int y1 = targetRect.bottom();
+ int y2 = targetRect.top();
+ int zValue = 0;
+
+ const GLfloat textureCoordinates[] = {
+ 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+
+ const GLfloat vertexCoordinates[] = {
+ x1, y1, zValue,
+ x2, y1, zValue,
+ x2, y2, zValue,
+ x1, y2, zValue
+ };
+
+ //Set matrix to transfrom geometry values into gl coordinate space.
+ m_transformMatrix.setToIdentity();
+ m_transformMatrix.scale( 2.0f / size().width(), 2.0f / size().height() );
+ m_transformMatrix.translate(-size().width() / 2.0f, -size().height() / 2.0f);
+
+ m_shaderProgram->bind();
+
+ m_vertexCoordEntry = m_shaderProgram->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_shaderProgram->attributeLocation("textureCoordEntry");
+ m_matrixLocation = m_shaderProgram->uniformLocation("matrix");
+
+ //attach the data!
+ glEnableVertexAttribArray(m_vertexCoordEntry);
+ glEnableVertexAttribArray(m_textureCoordEntry);
+
+ glVertexAttribPointer(m_vertexCoordEntry, 3, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_shaderProgram->setUniformValue(m_matrixLocation, m_transformMatrix);
+
+ glBindTexture(GL_TEXTURE_2D, m_textureId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glDisableVertexAttribArray(m_vertexCoordEntry);
+ glDisableVertexAttribArray(m_textureCoordEntry);
+
+ m_shaderProgram->release();
+}
+
+void AVFVideoWidget::setTexture(GLuint texture)
+{
+ m_textureId = texture;
+
+ if (isVisible()) {
+ makeCurrent();
+ updateGL();
+ }
+}
+
+QSize AVFVideoWidget::sizeHint() const
+{
+ return m_nativeSize;
+}
+
+void AVFVideoWidget::setNativeSize(const QSize &size)
+{
+ m_nativeSize = size;
+}
+
+void AVFVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ if (m_aspectRatioMode != mode) {
+ m_aspectRatioMode = mode;
+ update();
+ }
+}
+
+QRect AVFVideoWidget::displayRect() const
+{
+ QRect displayRect = rect();
+
+ if (m_aspectRatioMode == Qt::KeepAspectRatio) {
+ QSize size = m_nativeSize;
+ size.scale(displayRect.size(), Qt::KeepAspectRatio);
+
+ displayRect = QRect(QPoint(0, 0), size);
+ displayRect.moveCenter(rect().center());
+ }
+ return displayRect;
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h
new file mode 100644
index 000000000..d27da77d3
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFVIDEOWIDGETCONTROL_H
+#define AVFVIDEOWIDGETCONTROL_H
+
+#include <qvideowidgetcontrol.h>
+#include "avfvideooutput.h"
+
+#import <CoreVideo/CVBase.h>
+
+QT_BEGIN_NAMESPACE
+
+class AVFDisplayLink;
+class AVFVideoWidget;
+class AVFVideoFrameRenderer;
+
+class AVFVideoWidgetControl : public QVideoWidgetControl, public AVFVideoOutput
+{
+ Q_OBJECT
+ Q_INTERFACES(AVFVideoOutput)
+public:
+ AVFVideoWidgetControl(QObject *parent = 0);
+ virtual ~AVFVideoWidgetControl();
+
+ void setLayer(void *playerLayer);
+
+ QWidget *videoWidget();
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+private Q_SLOTS:
+ void updateVideoFrame(const CVTimeStamp &ts);
+
+private:
+ void setupVideoOutput();
+
+ AVFDisplayLink *m_displayLink;
+ AVFVideoWidget *m_videoWidget;
+ AVFVideoFrameRenderer *m_frameRenderer;
+ QSize m_nativeSize;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ bool m_fullscreen;
+ int m_brightness;
+ int m_contrast;
+ int m_hue;
+ int m_saturation;
+
+ void *m_playerLayer;
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFVIDEOWIDGETCONTROL_H
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm
new file mode 100644
index 000000000..b8cd7821a
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfvideowidgetcontrol.h"
+
+#include "avfvideowidget.h"
+#include "avfvideoframerenderer.h"
+#include "avfdisplaylink.h"
+
+#ifdef QT_DEBUG_AVF
+#include <QtCore/QDebug>
+#endif
+
+#import <AVFoundation/AVFoundation.h>
+
+QT_USE_NAMESPACE
+
+AVFVideoWidgetControl::AVFVideoWidgetControl(QObject *parent)
+ : QVideoWidgetControl(parent)
+ , m_frameRenderer(0)
+ , m_aspectRatioMode(Qt::KeepAspectRatio)
+ , m_fullscreen(false)
+ , m_brightness(0)
+ , m_contrast(0)
+ , m_hue(0)
+ , m_saturation(0)
+ , m_playerLayer(0)
+{
+ QGLFormat format = QGLFormat::defaultFormat();
+ format.setSwapInterval(1); // Vertical sync (avoid tearing)
+ format.setDoubleBuffer(true);
+ m_videoWidget = new AVFVideoWidget(0, format);
+
+ m_displayLink = new AVFDisplayLink(this);
+ connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), this, SLOT(updateVideoFrame(CVTimeStamp)));
+}
+
+AVFVideoWidgetControl::~AVFVideoWidgetControl()
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO;
+#endif
+ m_displayLink->stop();
+ if (m_playerLayer)
+ [(AVPlayerLayer*)m_playerLayer release];
+
+ delete m_videoWidget;
+}
+
+void AVFVideoWidgetControl::setLayer(void *playerLayer)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << playerLayer;
+#endif
+
+ if (m_playerLayer == playerLayer)
+ return;
+
+ [(AVPlayerLayer*)playerLayer retain];
+ [(AVPlayerLayer*)m_playerLayer release];
+
+ m_playerLayer = playerLayer;
+
+ //If there is no layer to render, stop scheduling updates
+ if (m_playerLayer == 0) {
+ m_displayLink->stop();
+ return;
+ }
+
+ setupVideoOutput();
+
+ //make sure we schedule updates
+ if (!m_displayLink->isActive()) {
+ m_displayLink->start();
+ }
+}
+
+QWidget *AVFVideoWidgetControl::videoWidget()
+{
+ return m_videoWidget;
+}
+
+bool AVFVideoWidgetControl::isFullScreen() const
+{
+ return m_fullscreen;
+}
+
+void AVFVideoWidgetControl::setFullScreen(bool fullScreen)
+{
+ m_fullscreen = fullScreen;
+}
+
+Qt::AspectRatioMode AVFVideoWidgetControl::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void AVFVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+ m_videoWidget->setAspectRatioMode(mode);
+}
+
+int AVFVideoWidgetControl::brightness() const
+{
+ return m_brightness;
+}
+
+void AVFVideoWidgetControl::setBrightness(int brightness)
+{
+ m_brightness = brightness;
+}
+
+int AVFVideoWidgetControl::contrast() const
+{
+ return m_contrast;
+}
+
+void AVFVideoWidgetControl::setContrast(int contrast)
+{
+ m_contrast = contrast;
+}
+
+int AVFVideoWidgetControl::hue() const
+{
+ return m_hue;
+}
+
+void AVFVideoWidgetControl::setHue(int hue)
+{
+ m_hue = hue;
+}
+
+int AVFVideoWidgetControl::saturation() const
+{
+ return m_saturation;
+}
+
+void AVFVideoWidgetControl::setSaturation(int saturation)
+{
+ m_saturation = saturation;
+}
+
+void AVFVideoWidgetControl::updateVideoFrame(const CVTimeStamp &ts)
+{
+ Q_UNUSED(ts)
+
+ AVPlayerLayer *playerLayer = (AVPlayerLayer*)m_playerLayer;
+
+ if (!playerLayer) {
+ qWarning("updateVideoFrame called without AVPlayerLayer (which shouldn't happen)");
+ return;
+ }
+
+ //Don't try to render a layer that is not ready
+ if (!playerLayer.readyForDisplay)
+ return;
+
+ GLuint textureId = m_frameRenderer->renderLayerToTexture(playerLayer);
+
+ //Make sure we have a valid texture
+ if (textureId == 0) {
+ qWarning("renderLayerToTexture failed");
+ return;
+ }
+
+ m_videoWidget->setTexture(textureId);
+}
+
+void AVFVideoWidgetControl::setupVideoOutput()
+{
+ NSRect layerBounds = [(AVPlayerLayer*)m_playerLayer bounds];
+ m_nativeSize = QSize(layerBounds.size.width, layerBounds.size.height);
+ m_videoWidget->setNativeSize(m_nativeSize);
+
+ if (m_frameRenderer)
+ delete m_frameRenderer;
+
+ m_frameRenderer = new AVFVideoFrameRenderer(m_videoWidget, m_nativeSize, this);
+}
+
diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro
new file mode 100644
index 000000000..ae320ac1f
--- /dev/null
+++ b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro
@@ -0,0 +1,56 @@
+load(qt_build_config)
+
+#DEFINES += QT_DEBUG_AVF
+# Avoid clash with a variable named `slots' in a Quartz header
+CONFIG += no_keywords
+
+TARGET = qavfmediaplayer
+QT += multimedia-private network
+
+PLUGIN_TYPE = mediaservice
+
+load(qt_plugin)
+DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE}
+
+LIBS += -framework AVFoundation -framework CoreMedia
+
+target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
+INSTALLS += target
+
+DEFINES += QMEDIA_AVF_MEDIAPLAYER
+
+HEADERS += \
+ avfmediaplayercontrol.h \
+ avfmediaplayermetadatacontrol.h \
+ avfmediaplayerservice.h \
+ avfmediaplayersession.h \
+ avfmediaplayerserviceplugin.h \
+ avfvideorenderercontrol.h \
+ avfdisplaylink.h \
+ avfvideoframerenderer.h \
+ avfvideooutput.h
+
+OBJECTIVE_SOURCES += \
+ avfmediaplayercontrol.mm \
+ avfmediaplayermetadatacontrol.mm \
+ avfmediaplayerservice.mm \
+ avfmediaplayerserviceplugin.mm \
+ avfmediaplayersession.mm \
+ avfvideorenderercontrol.mm \
+ avfdisplaylink.mm \
+ avfvideoframerenderer.mm \
+ avfvideooutput.mm
+
+!isEmpty(QT.widgets.name) {
+ QT += multimediawidgets-private opengl
+ HEADERS += \
+ avfvideowidgetcontrol.h \
+ avfvideowidget.h
+
+ OBJECTIVE_SOURCES += \
+ avfvideowidgetcontrol.mm \
+ avfvideowidget.mm
+}
+
+OTHER_FILES += \
+ avfmediaplayer.json
diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri
index 83b681920..b576a852f 100644
--- a/src/plugins/directshow/camera/camera.pri
+++ b/src/plugins/directshow/camera/camera.pri
@@ -13,7 +13,6 @@ HEADERS += \
$$PWD/dsvideodevicecontrol.h \
$$PWD/dsimagecapturecontrol.h \
$$PWD/dscamerasession.h \
- $$PWD/dscameraservice.h \
$$PWD/directshowglobal.h
SOURCES += \
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
index cad7a444c..a7e84acb7 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
@@ -77,6 +77,19 @@ typedef enum {
GST_PLAY_FLAG_BUFFERING = 0x000000100
} GstPlayFlags;
+#define DEFAULT_RAW_CAPS \
+ "video/x-raw-yuv; " \
+ "video/x-raw-rgb; " \
+ "video/x-raw-gray; " \
+ "video/x-surface; " \
+ "audio/x-raw-int; " \
+ "audio/x-raw-float; " \
+ "text/plain; " \
+ "text/x-pango-markup; " \
+ "video/x-dvd-subpicture; " \
+ "subpicture/x-pgs"
+static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
+
QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
:QObject(parent),
m_state(QMediaPlayer::StoppedState),
@@ -1548,6 +1561,63 @@ void QGstreamerPlayerSession::updateMuted()
}
}
+#if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
+static gboolean factory_can_src_any_caps (GstElementFactory *factory, const GstCaps *caps)
+{
+ GList *templates;
+
+ g_return_val_if_fail(factory != NULL, FALSE);
+ g_return_val_if_fail(caps != NULL, FALSE);
+
+ templates = factory->staticpadtemplates;
+
+ while (templates) {
+ GstStaticPadTemplate *templ = (GstStaticPadTemplate *)templates->data;
+
+ if (templ->direction == GST_PAD_SRC) {
+ GstCaps *templcaps = gst_static_caps_get(&templ->static_caps);
+
+ if (gst_caps_can_intersect(caps, templcaps)) {
+ gst_caps_unref(templcaps);
+ return TRUE;
+ }
+ gst_caps_unref(templcaps);
+ }
+ templates = g_list_next(templates);
+ }
+
+ return FALSE;
+}
+#endif
+
+GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session)
+{
+ Q_UNUSED(bin);
+ Q_UNUSED(pad);
+ Q_UNUSED(caps);
+
+ GstAutoplugSelectResult res = GST_AUTOPLUG_SELECT_TRY;
+
+ // if VAAPI is available and can be used to decode but the current video sink cannot handle
+ // the decoded format, don't use it
+ const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
+ if (g_str_has_prefix(factoryName, "vaapi")) {
+ GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
+ GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
+
+#if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
+ if (!factory_can_src_any_caps(factory, sinkCaps))
+#else
+ if (!gst_element_factory_can_src_any_caps(factory, sinkCaps))
+#endif
+ res = GST_AUTOPLUG_SELECT_SKIP;
+
+ gst_object_unref(sinkPad);
+ gst_caps_unref(sinkCaps);
+ }
+
+ return res;
+}
void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session)
{
@@ -1573,6 +1643,15 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
}
} else if (g_str_has_prefix(elementName, "uridecodebin") ||
g_str_has_prefix(elementName, "decodebin2")) {
+
+ if (g_str_has_prefix(elementName, "uridecodebin")) {
+ // Add video/x-surface (VAAPI) to default raw formats
+ g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL);
+ // listen for uridecodebin autoplug-select to skip VAAPI usage when the current
+ // video sink doesn't support it
+ g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
+ }
+
//listen for queue2 element added to uridecodebin/decodebin2 as well.
//Don't touch other bins since they may have unrelated queues
g_signal_connect(element, "element-added",
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
index a9194d446..0b4041f58 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
@@ -66,6 +66,12 @@ class QGstreamerVideoRendererInterface;
class QGstreamerVideoProbeControl;
class QGstreamerAudioProbeControl;
+typedef enum {
+ GST_AUTOPLUG_SELECT_TRY,
+ GST_AUTOPLUG_SELECT_EXPOSE,
+ GST_AUTOPLUG_SELECT_SKIP
+} GstAutoplugSelectResult;
+
class QGstreamerPlayerSession : public QObject,
public QGstreamerBusMessageFilter
{
@@ -182,6 +188,7 @@ private:
static void insertColorSpaceElement(GstElement *element, gpointer data);
static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session);
static void handleStreamsChange(GstBin *bin, gpointer user_data);
+ static GstAutoplugSelectResult handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session);
void processInvalidMedia(QMediaPlayer::Error errorCode, const QString& errorString);
diff --git a/src/plugins/qt7/qt7movierenderer.mm b/src/plugins/qt7/qt7movierenderer.mm
index 7fa36a544..f1508294a 100644
--- a/src/plugins/qt7/qt7movierenderer.mm
+++ b/src/plugins/qt7/qt7movierenderer.mm
@@ -55,6 +55,8 @@
#include <qabstractvideosurface.h>
#include <qvideosurfaceformat.h>
+#include <QtOpenGl/QGLContext>
+
QT_USE_NAMESPACE
//#define USE_MAIN_MONITOR_COLOR_SPACE 1
diff --git a/src/plugins/qt7/qt7movieviewrenderer.h b/src/plugins/qt7/qt7movieviewrenderer.h
index ade492948..00b658b30 100644
--- a/src/plugins/qt7/qt7movieviewrenderer.h
+++ b/src/plugins/qt7/qt7movieviewrenderer.h
@@ -61,6 +61,8 @@ class QT7PlayerSession;
class QT7PlayerService;
class QGLWidget;
class QGLFramebufferObject;
+class QWindow;
+class QOpenGLContext;
class QT7MovieViewRenderer : public QT7VideoRendererControl
{
@@ -88,7 +90,8 @@ private:
QSize m_nativeSize;
QAbstractVideoSurface *m_surface;
QVideoFrame m_currentFrame;
- QGLWidget *m_glWidget;
+ QWindow *m_window;
+ QOpenGLContext *m_context;
QGLFramebufferObject *m_fbo;
CIContext *m_ciContext;
diff --git a/src/plugins/qt7/qt7movieviewrenderer.mm b/src/plugins/qt7/qt7movieviewrenderer.mm
index 4a157567a..8578eb365 100644
--- a/src/plugins/qt7/qt7movieviewrenderer.mm
+++ b/src/plugins/qt7/qt7movieviewrenderer.mm
@@ -137,7 +137,7 @@ private:
@interface HiddenQTMovieView : QTMovieView
{
@private
- QWidget *m_window;
+ QWindow *m_window;
QT7MovieViewRenderer *m_renderer;
QReadWriteLock m_rendererLock;
}
@@ -160,10 +160,10 @@ private:
QWriteLocker lock(&self->m_rendererLock);
self->m_renderer = renderer;
- self->m_window = new QWidget;
- self->m_window->setWindowOpacity(0.0);
- self->m_window->show();
- self->m_window->hide();
+ self->m_window = new QWindow;
+ self->m_window->setOpacity(0.0);
+ self->m_window->setGeometry(0,0,1,1);
+ self->m_window->create();
[(NSView *)(self->m_window->winId()) addSubview:self];
[self setDrawRect:QRect(0,0,1,1)];
@@ -173,7 +173,7 @@ private:
- (void) dealloc
{
- delete self->m_window;
+ self->m_window->deleteLater();
[super dealloc];
}
@@ -273,7 +273,8 @@ QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
m_movie(0),
m_movieView(0),
m_surface(0),
- m_glWidget(0),
+ m_window(0),
+ m_context(0),
m_fbo(0),
m_ciContext(0),
m_pendingRenderEvent(false)
@@ -289,7 +290,7 @@ QT7MovieViewRenderer::~QT7MovieViewRenderer()
[(HiddenQTMovieView*)m_movieView release];
[m_ciContext release];
delete m_fbo;
- delete m_glWidget;
+ delete m_window;
}
void QT7MovieViewRenderer::setupVideoOutput()
@@ -364,24 +365,35 @@ QVideoFrame QT7MovieViewRenderer::convertCIImageToGLTexture(const QVideoFrame &f
if (frame.handleType() != QAbstractVideoBuffer::CoreImageHandle)
return QVideoFrame();
- if (!m_glWidget) {
+ if (!m_window) {
QOpenGLContext *qGlContext = 0;
if (m_surface)
qGlContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
if (qGlContext) {
- QGLContext *surfaceContext = QGLContext::fromOpenGLContext(qGlContext);
- m_glWidget = new QGLWidget();
+ m_window = new QWindow();
- QGLContext *context = new QGLContext(surfaceContext->format());
- m_glWidget->setContext(context, surfaceContext);
+ QSurfaceFormat format(qGlContext->format());
+
+ m_context = new QOpenGLContext(m_window);
+ m_context->setShareContext(qGlContext);
+ m_context->setFormat(format);
+ m_context->create();
+
+ m_window->setFormat(format);
+ m_window->setGeometry(0, 0, 1, 1);
+ m_window->setSurfaceType(QWindow::OpenGLSurface);
+ m_window->create();
} else {
return QVideoFrame();
}
}
- m_glWidget->makeCurrent();
+ if (!m_context)
+ return QVideoFrame();
+
+ m_context->makeCurrent(m_window);
if (!m_fbo || m_fbo->size() != frame.size()) {
delete m_fbo;
@@ -414,6 +426,7 @@ QVideoFrame QT7MovieViewRenderer::convertCIImageToGLTexture(const QVideoFrame &f
[m_ciContext drawImage:ciImg inRect:dRect fromRect:sRect];
}
+
p.endNativePainting();
QAbstractVideoBuffer *buffer = new TextureVideoBuffer(m_fbo->texture());
@@ -462,7 +475,6 @@ void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface)
void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
{
-
QMutexLocker locker(&m_mutex);
m_currentFrame = frame;
diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro
index 4dc410ba2..f22af94af 100644
--- a/src/plugins/wmf/wmf.pro
+++ b/src/plugins/wmf/wmf.pro
@@ -30,5 +30,8 @@ SOURCES += \
include (player/player.pri)
include (decoder/decoder.pri)
+target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
+INSTALLS += target
+
OTHER_FILES += \
wmf.json
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index 4f15a69ec..dd0648211 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -9,4 +9,9 @@ find_package(Qt5Core REQUIRED)
include("${_Qt5CTestMacros}")
-expect_pass(test_modules)
+set(Qt5_MODULE_TEST_DEPENDS Network Widgets)
+
+test_module_includes(
+ Multimedia QCamera
+ MultimediaWidgets QVideoWidget
+)
diff --git a/tests/auto/cmake/test_modules/CMakeLists.txt b/tests/auto/cmake/test_modules/CMakeLists.txt
deleted file mode 100644
index bcfa96c45..000000000
--- a/tests/auto/cmake/test_modules/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-cmake_minimum_required(VERSION 2.8)
-
-project(test_modules)
-
-find_package(Qt5Network REQUIRED)
-find_package(Qt5Widgets REQUIRED)
-
-find_package(Qt5Multimedia REQUIRED)
-find_package(Qt5MultimediaWidgets REQUIRED)
-
-include_directories(
- ${Qt5Multimedia_INCLUDE_DIRS}
- ${Qt5MultimediaWidgets_INCLUDE_DIRS}
-)
-
-add_definitions(
- ${Qt5Multimedia_DEFINITIONS}
- ${Qt5MultimediaWidgets_DEFINITIONS}
-)
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
-
-add_executable(mainapp main.cpp)
-target_link_libraries(mainapp
- ${Qt5Multimedia_LIBRARIES}
- ${Qt5MultimediaWidgets_LIBRARIES}
-)
diff --git a/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp b/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp
index 55e00ad05..8613753d6 100644
--- a/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp
+++ b/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp
@@ -226,7 +226,7 @@ void tst_QDeclarativeVideoOutputWindow::initTestCase()
m_rootItem.reset(qobject_cast<QQuickItem *>(component.create()));
m_videoItem = m_rootItem->findChild<QQuickItem *>("videoOutput");
QVERIFY(m_videoItem);
- m_rootItem->setParentItem(m_view.rootItem());
+ m_rootItem->setParentItem(m_view.contentItem());
m_videoItem->setProperty("source", QVariant::fromValue<QObject *>(&m_sourceObject));
m_windowControl.setNativeSize(QSize(400, 200));
diff --git a/tests/auto/integration/qsoundeffect/qsoundeffect.pro b/tests/auto/integration/qsoundeffect/qsoundeffect.pro
index e3200ce5a..2fffaf716 100644
--- a/tests/auto/integration/qsoundeffect/qsoundeffect.pro
+++ b/tests/auto/integration/qsoundeffect/qsoundeffect.pro
@@ -16,5 +16,6 @@ unix:!mac {
TESTDATA += test.wav
-win32: CONFIG += insignificant_test
+win32:CONFIG += insignificant_test # QTBUG-26509
+linux-*:CONFIG += insignificant_test # QTBUG-26748
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/unit/qmultimedia_common/mockaudiodecodercontrol.h b/tests/auto/unit/qmultimedia_common/mockaudiodecodercontrol.h
index 61b8ac1b5..1d44fed47 100644
--- a/tests/auto/unit/qmultimedia_common/mockaudiodecodercontrol.h
+++ b/tests/auto/unit/qmultimedia_common/mockaudiodecodercontrol.h
@@ -57,8 +57,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class MockAudioDecoderControl : public QAudioDecoderControl
{
Q_OBJECT