diff options
author | Jerome Pasion <jerome.pasion@digia.com> | 2012-11-02 15:40:51 +0100 |
---|---|---|
committer | Jerome Pasion <jerome.pasion@digia.com> | 2012-11-02 15:41:00 +0100 |
commit | a5947906d3aac7ec2f21a9621f7ad67a761a4560 (patch) | |
tree | b67a28ecfdf01a0ca71ec51e00ee45ee1491eeaf | |
parent | 962e99534d8955ae6c3c3524c5005f518b4e01bc (diff) | |
parent | 79f585b9e90c311f2c7b905426318d345b1bf641 (diff) | |
download | qtmultimedia-a5947906d3aac7ec2f21a9621f7ad67a761a4560.tar.gz |
Merge branch 'master' of ssh://codereview.qt-project.org/qt/qtmultimedia into newdocs
Change-Id: Idb607da32f80784d94556443be6740c6d7223411
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 |