summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2014-11-07 13:30:29 +0100
committerYoann Lopes <yoann.lopes@theqtcompany.com>2014-11-07 17:19:09 +0100
commit31d57b6d9d39d7fdc03526c9703d0b4010d512c5 (patch)
tree9471839273c0505026c9564c57070c609dbd20b7
parent58cbea0f93af1e613eeeffec68d00c4df0ae4bf9 (diff)
parentc3f5a15f24f4421e0a096b2272273d9a85f70851 (diff)
downloadqtmultimedia-31d57b6d9d39d7fdc03526c9703d0b4010d512c5.tar.gz
Merge remote-tracking branch 'origin/dev' into wip/gstreamer-1.0
Conflicts: qtmultimedia.pro src/gsttools/qvideosurfacegstsink.cpp src/plugins/gstreamer/camerabin/camerabinsession.cpp src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp Change-Id: Ib533c187c010f97f96e44eb765281afd55763a8f
-rw-r--r--config.tests/linux_v4l/linux_v4l.pro1
-rw-r--r--config.tests/linux_v4l/main.cpp (renamed from src/plugins/qt7/qt7backend.mm)21
-rw-r--r--config.tests/wmp/main.cpp5
-rw-r--r--config.tests/wmp/wmp.pro3
-rw-r--r--dist/changes-5.3.265
-rw-r--r--examples/multimedia/audiodevices/doc/src/audiodevices.qdoc9
-rw-r--r--examples/multimedia/audioengine/doc/src/audioengine.qdoc5
-rw-r--r--examples/multimedia/audioinput/audioinput.cpp19
-rw-r--r--examples/multimedia/audioinput/audioinput.h2
-rw-r--r--examples/multimedia/audioinput/doc/src/audioinput.qdoc5
-rw-r--r--examples/multimedia/audiooutput/audiooutput.cpp18
-rw-r--r--examples/multimedia/audiooutput/audiooutput.h2
-rw-r--r--examples/multimedia/audiooutput/doc/src/audiooutput.qdoc5
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.cpp57
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.h1
-rw-r--r--examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc6
-rw-r--r--examples/multimedia/spectrum/doc/src/spectrum.qdoc7
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-menu.jpgbin0 -> 21959 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-menu.pngbin64550 -> 0 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-overlay.jpgbin0 -> 23787 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-overlay.pngbin65432 -> 0 bytes
-rw-r--r--examples/multimedia/video/doc/src/qmlvideo.qdoc14
-rw-r--r--examples/multimedia/video/doc/src/qmlvideofx.qdoc10
-rw-r--r--examples/multimedia/video/qmlvideo/images/close.pngbin1799 -> 0 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/folder.pngbin1841 -> 1829 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/progress_handle.svg35
-rw-r--r--examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg35
-rw-r--r--examples/multimedia/video/qmlvideo/images/titlebar.pngbin1436 -> 0 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/titlebar.sci5
-rw-r--r--examples/multimedia/video/qmlvideo/images/up.pngbin662 -> 1268 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/main.cpp7
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml21
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml8
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml42
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml8
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml174
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml11
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml4
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml3
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml3
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml3
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml2
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml6
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml107
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml30
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml6
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml26
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml10
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml6
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml71
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.qrc6
-rw-r--r--examples/multimedia/video/qmlvideofx/filereader.cpp2
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml7
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml43
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml43
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml4
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml4
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml2
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml6
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.qrc2
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/magnify.fsh3
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/ripple.fsh3
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp2
-rw-r--r--examples/multimediawidgets/camera/camera.cpp27
-rw-r--r--examples/multimediawidgets/camera/camera.h2
-rw-r--r--examples/multimediawidgets/player/doc/src/player.qdoc13
-rw-r--r--examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc6
-rw-r--r--examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc6
-rw-r--r--qtmultimedia.pro6
-rw-r--r--src/gsttools/gsttools.pro2
-rw-r--r--src/gsttools/qgstutils.cpp8
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp85
-rw-r--r--src/imports/multimedia/qdeclarativeradiodata.cpp3
-rw-r--r--src/multimedia/audio/qsoundeffect_qaudio_p.cpp3
-rw-r--r--src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h13
-rw-r--r--src/multimedia/playback/playlistfileparser.cpp149
-rw-r--r--src/multimedia/qmediaopenglhelper_p.h4
-rw-r--r--src/plugins/alsa/qalsaaudioinput.cpp2
-rw-r--r--src/plugins/alsa/qalsaaudiooutput.cpp2
-rw-r--r--src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java20
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp185
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h5
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp4
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp10
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h4
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp32
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp133
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h4
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp45
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp28
-rw-r--r--src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp28
-rw-r--r--src/plugins/avfoundation/camera/avfcameraservice.mm4
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm5
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h5
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm126
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidget.mm4
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm4
-rw-r--r--src/plugins/coreaudio/coreaudiodeviceinfo.mm1
-rw-r--r--src/plugins/coreaudio/coreaudioinput.h1
-rw-r--r--src/plugins/coreaudio/coreaudioinput.mm1
-rw-r--r--src/plugins/coreaudio/coreaudiooutput.h1
-rw-r--r--src/plugins/coreaudio/coreaudiooutput.mm5
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp24
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.h2
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp56
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp42
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.h2
-rw-r--r--src/plugins/gstreamer/mediacapture/mediacapture.pro21
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp9
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h2
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp11
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp99
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h3
-rw-r--r--src/plugins/opensles/qopenslesaudioinput.cpp2
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.cpp101
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.h4
-rw-r--r--src/plugins/plugins.pro6
-rw-r--r--src/plugins/pulseaudio/qaudioinput_pulse.cpp2
-rw-r--r--src/plugins/pulseaudio/qaudiooutput_pulse.cpp2
-rw-r--r--src/plugins/qnx-audio/audio/qnxaudioinput.cpp2
-rw-r--r--src/plugins/qnx-audio/audio/qnxaudiooutput.cpp2
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp1
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp2
-rw-r--r--src/plugins/qt7/mediaplayer/mediaplayer.pri16
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playercontrol.h98
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playercontrol.mm191
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playermetadata.h66
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playermetadata.mm250
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playerservice.h73
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playerservice.mm128
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playersession.h183
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playersession.mm751
-rw-r--r--src/plugins/qt7/qcvdisplaylink.h80
-rw-r--r--src/plugins/qt7/qcvdisplaylink.mm156
-rw-r--r--src/plugins/qt7/qt7.json4
-rw-r--r--src/plugins/qt7/qt7.pro67
-rw-r--r--src/plugins/qt7/qt7backend.h60
-rw-r--r--src/plugins/qt7/qt7ciimagevideobuffer.h78
-rw-r--r--src/plugins/qt7/qt7ciimagevideobuffer.mm107
-rw-r--r--src/plugins/qt7/qt7movierenderer.h98
-rw-r--r--src/plugins/qt7/qt7movierenderer.mm481
-rw-r--r--src/plugins/qt7/qt7movievideowidget.h117
-rw-r--r--src/plugins/qt7/qt7movievideowidget.mm437
-rw-r--r--src/plugins/qt7/qt7movieviewoutput.h107
-rw-r--r--src/plugins/qt7/qt7movieviewoutput.mm339
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.h96
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.mm509
-rw-r--r--src/plugins/qt7/qt7serviceplugin.h69
-rw-r--r--src/plugins/qt7/qt7videooutput.h109
-rw-r--r--src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp30
-rw-r--r--src/plugins/windowsaudio/qwindowsaudioinput.cpp2
-rw-r--r--src/plugins/windowsaudio/qwindowsaudiooutput.cpp2
-rw-r--r--src/plugins/windowsaudio/windowsaudio.pro3
-rw-r--r--src/plugins/winrt/qwinrtcameracontrol.cpp783
-rw-r--r--src/plugins/winrt/qwinrtcameracontrol.h111
-rw-r--r--src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp280
-rw-r--r--src/plugins/winrt/qwinrtcameraimagecapturecontrol.h (renamed from src/plugins/qt7/qt7serviceplugin.mm)96
-rw-r--r--src/plugins/winrt/qwinrtcamerainfocontrol.cpp (renamed from src/plugins/qt7/qt7videooutput.mm)49
-rw-r--r--src/plugins/winrt/qwinrtcamerainfocontrol.h61
-rw-r--r--src/plugins/winrt/qwinrtcameraservice.cpp104
-rw-r--r--src/plugins/winrt/qwinrtcameraservice.h66
-rw-r--r--src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp204
-rw-r--r--src/plugins/winrt/qwinrtcameravideorenderercontrol.h74
-rw-r--r--src/plugins/winrt/qwinrtserviceplugin.cpp39
-rw-r--r--src/plugins/winrt/qwinrtserviceplugin.h14
-rw-r--r--src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp383
-rw-r--r--src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h94
-rw-r--r--src/plugins/winrt/winrt.json2
-rw-r--r--src/plugins/winrt/winrt.pro18
-rw-r--r--src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp3
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp56
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp116
-rw-r--r--src/plugins/wmf/samplegrabber.cpp3
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_rgb.cpp2
-rw-r--r--tests/auto/integration/qmediaplayerbackend/testdata/nokia-tune.mp3bin61472 -> 62715 bytes
-rw-r--r--tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp284
-rw-r--r--tests/auto/unit/qmediaplaylist/testdata/empty.pls (renamed from tests/auto/unit/qmediaplaylist/testdata/trash.pls)0
-rw-r--r--tests/auto/unit/qmediaplaylist/testdata/test.pls2
-rw-r--r--tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp23
181 files changed, 3862 insertions, 6106 deletions
diff --git a/config.tests/linux_v4l/linux_v4l.pro b/config.tests/linux_v4l/linux_v4l.pro
new file mode 100644
index 000000000..28dcadcbf
--- /dev/null
+++ b/config.tests/linux_v4l/linux_v4l.pro
@@ -0,0 +1 @@
+SOURCES += main.cpp
diff --git a/src/plugins/qt7/qt7backend.mm b/config.tests/linux_v4l/main.cpp
index 136220cef..0a3040be5 100644
--- a/src/plugins/qt7/qt7backend.mm
+++ b/config.tests/linux_v4l/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
@@ -39,22 +39,9 @@
**
****************************************************************************/
-#include "qt7backend.h"
+#include <linux/videodev2.h>
-#import <Foundation/NSAutoreleasePool.h>
-#include <CoreFoundation/CFBase.h>
-
-
-QT_BEGIN_NAMESPACE
-
-AutoReleasePool::AutoReleasePool()
+int main(int argc, char** argv)
{
- pool = (void*)[[NSAutoreleasePool alloc] init];
+ return 0;
}
-
-AutoReleasePool::~AutoReleasePool()
-{
- [(NSAutoreleasePool*)pool release];
-}
-
-QT_END_NAMESPACE
diff --git a/config.tests/wmp/main.cpp b/config.tests/wmp/main.cpp
index b06037ca0..0eb86cfe2 100644
--- a/config.tests/wmp/main.cpp
+++ b/config.tests/wmp/main.cpp
@@ -30,8 +30,11 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
+#ifndef _WIN32_WCE
#include <wmp.h>
+#else
+#include <wmpcore.h>
+#endif
int main(int, char**)
{
diff --git a/config.tests/wmp/wmp.pro b/config.tests/wmp/wmp.pro
index b16509cc4..563de1453 100644
--- a/config.tests/wmp/wmp.pro
+++ b/config.tests/wmp/wmp.pro
@@ -3,4 +3,5 @@ CONFIG += console
SOURCES += main.cpp
-LIBS += -lstrmiids -lole32 -lOleaut32 -luser32 -lgdi32
+LIBS += -lstrmiids -lole32 -lOleaut32
+!wince*:LIBS += -luser32 -lgdi32
diff --git a/dist/changes-5.3.2 b/dist/changes-5.3.2
new file mode 100644
index 000000000..b427bb809
--- /dev/null
+++ b/dist/changes-5.3.2
@@ -0,0 +1,65 @@
+Qt 5.3.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.3.0 and 5.3.1.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ http://qt-project.org/doc/qt-5.3
+
+The Qt version 5.3 series is binary compatible with the 5.2.x series.
+Applications compiled for 5.2 will continue to run with 5.3.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ http://bugreports.qt-project.org/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+Android
+-------
+
+ - Fixed regression causing videos recorded with the camera not to be registered with the Android
+ media scanner, making them invisible to media browsing apps.
+ - Fixed crash when unloading a QCamera while a recording is active.
+ - [QTBUG-39307] Setting camera parameters on the QML Camera type (e.g. digitalZoom, flashMode)
+ now works correctly when set before the camera is loaded.
+ - [QTBUG-40208] QAudioOutput::setNotifyInterval() can now be used when the output is active.
+ - [QTBUG-40274] Fixed metadata not being loaded by the MediaPlayer when playing a remote media,
+ from a qrc file or from assets.
+
+iOS
+---
+
+ - [QTBUG-39036] Audio played using SoundEffect or QAudioOutput is now correctly muted when the
+ device is set to silent mode or when the screen is locked.
+ - [QTBUG-39385] The last video frame displayed in a QML VideoOutput doesn't remain on screen
+ anymore after destroying the VideoOutput.
+
+Linux
+-----
+
+ - MediaPlayer's loops property now works correctly when playing a media from a qrc file.
+ - [QTBUG-29742] Fixed Qt apps hanging when audio APIs are used and PulseAudio is not running.
+ - [QTBUG-39949] Fixed QMediaRecorder::setOutputLocation() not working with QUrl::fromLocalFile().
+
+OS X
+----
+
+ - Application doesn't freeze anymore when changing the system audio output device while audio
+ is being played with QSoundEffect or QAudioOutput.
+ - [QTBUG-38666] Video frames are now correctly positioned on screen when playing a live stream
+ in a QVideoWidget. This also applies to iOS.
+ - [QTBUG-38668] Fixed crash when setting QMediaRecorder's output location to a URL containing
+ nonstandard characters.
+
+Windows
+-------
+
+ - The DirectShow camera backend has been almost entirely rewritten. It doesn't provide any new
+ feature but it now works as it should.
diff --git a/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
index bdf1590fe..3c6a4e4d6 100644
--- a/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
+++ b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
@@ -29,12 +29,11 @@
\example audiodevices
\title Audio Devices Example
\ingroup multimedia_examples
- \brief The Audio Devices example shows the application of the audio devices
- APIs.
+ \brief Testing the available audio devices and their configuration.
- This example shows how to create a simple application to list and test
- the configuration for the various audio devices available on the device
- or machine. This is done using the QtMobility Multimedia API.
+ \e{Audio Devices} demonstrates how to create a simple application to list
+ and test the configuration for the various audio devices available on the
+ target device or desktop PC.
\image audiodevices.png
diff --git a/examples/multimedia/audioengine/doc/src/audioengine.qdoc b/examples/multimedia/audioengine/doc/src/audioengine.qdoc
index 52a377130..19e903b2b 100644
--- a/examples/multimedia/audioengine/doc/src/audioengine.qdoc
+++ b/examples/multimedia/audioengine/doc/src/audioengine.qdoc
@@ -29,10 +29,9 @@
\example audioengine
\title AudioEngine Example
\ingroup multimedia_examples
- \brief The Audio Engine example demonstrates 3D sound control using
- the Qt Audio Engine API.
+ \brief Enabling 3D sound control using the Qt Audio Engine API.
- The Audio Engine example demonstrates 3D sound control using the
+ \e{Audio Engine} demonstrates 3D sound control using the
\l{Qt Audio Engine QML Types}{Qt Audio Engine} API.
\include examples-run.qdocinc
diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp
index 09f571b0c..87d7963aa 100644
--- a/examples/multimedia/audioinput/audioinput.cpp
+++ b/examples/multimedia/audioinput/audioinput.cpp
@@ -315,20 +315,11 @@ void InputTest::initializeAudio()
void InputTest::createAudioInput()
{
m_audioInput = new QAudioInput(m_device, m_format, this);
- connect(m_audioInput, SIGNAL(notify()), SLOT(notified()));
- connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(handleStateChanged(QAudio::State)));
m_volumeSlider->setValue(m_audioInput->volume() * 100);
m_audioInfo->start();
m_audioInput->start(m_audioInfo);
}
-void InputTest::notified()
-{
- qWarning() << "bytesReady = " << m_audioInput->bytesReady()
- << ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs()
- << ", " << "processedUSecs = "<<m_audioInput->processedUSecs();
-}
-
void InputTest::readMore()
{
if (!m_audioInput)
@@ -364,27 +355,19 @@ void InputTest::toggleSuspend()
{
// toggle suspend/resume
if (m_audioInput->state() == QAudio::SuspendedState) {
- qWarning() << "status: Suspended, resume()";
m_audioInput->resume();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
} else if (m_audioInput->state() == QAudio::ActiveState) {
- qWarning() << "status: Active, suspend()";
m_audioInput->suspend();
m_suspendResumeButton->setText(tr(RESUME_LABEL));
} else if (m_audioInput->state() == QAudio::StoppedState) {
- qWarning() << "status: Stopped, resume()";
m_audioInput->resume();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
} else if (m_audioInput->state() == QAudio::IdleState) {
- qWarning() << "status: IdleState";
+ // no-op
}
}
-void InputTest::handleStateChanged(QAudio::State state)
-{
- qWarning() << "state = " << state;
-}
-
void InputTest::refreshDisplay()
{
m_canvas->setLevel(m_audioInfo->level());
diff --git a/examples/multimedia/audioinput/audioinput.h b/examples/multimedia/audioinput/audioinput.h
index 82def563b..df26104b9 100644
--- a/examples/multimedia/audioinput/audioinput.h
+++ b/examples/multimedia/audioinput/audioinput.h
@@ -110,11 +110,9 @@ private:
private slots:
void refreshDisplay();
- void notified();
void readMore();
void toggleMode();
void toggleSuspend();
- void handleStateChanged(QAudio::State state);
void deviceChanged(int index);
void sliderChanged(int value);
diff --git a/examples/multimedia/audioinput/doc/src/audioinput.qdoc b/examples/multimedia/audioinput/doc/src/audioinput.qdoc
index 11a513a99..fad40aa6e 100644
--- a/examples/multimedia/audioinput/doc/src/audioinput.qdoc
+++ b/examples/multimedia/audioinput/doc/src/audioinput.qdoc
@@ -29,8 +29,9 @@
\example audioinput
\title Audio Input Example
\ingroup multimedia_examples
- \brief The Audio Input Example shows the use of the QAudioInput class.
- The example demonstrates the basic use cases of the QAudioInput class.
+ \brief Recording audio using the QAudioInput class
+
+ \e{Audio Input} demonstrates the basic use cases of QAudioInput.
\image audioinput-example.png
diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp
index daa7bfdf6..7911b580a 100644
--- a/examples/multimedia/audiooutput/audiooutput.cpp
+++ b/examples/multimedia/audiooutput/audiooutput.cpp
@@ -247,8 +247,6 @@ void AudioTest::createAudioOutput()
delete m_audioOutput;
m_audioOutput = 0;
m_audioOutput = new QAudioOutput(m_device, m_format, this);
- connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
- connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(handleStateChanged(QAudio::State)));
m_generator->start();
m_audioOutput->start(m_generator);
m_volumeSlider->setValue(int(m_audioOutput->volume()*100.0f));
@@ -275,13 +273,6 @@ void AudioTest::volumeChanged(int value)
m_audioOutput->setVolume(qreal(value/100.0f));
}
-void AudioTest::notified()
-{
- qWarning() << "bytesFree = " << m_audioOutput->bytesFree()
- << ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs()
- << ", " << "processedUSecs = " << m_audioOutput->processedUSecs();
-}
-
void AudioTest::pullTimerExpired()
{
if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
@@ -319,23 +310,16 @@ void AudioTest::toggleMode()
void AudioTest::toggleSuspendResume()
{
if (m_audioOutput->state() == QAudio::SuspendedState) {
- qWarning() << "status: Suspended, resume()";
m_audioOutput->resume();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
} else if (m_audioOutput->state() == QAudio::ActiveState) {
- qWarning() << "status: Active, suspend()";
m_audioOutput->suspend();
m_suspendResumeButton->setText(tr(RESUME_LABEL));
} else if (m_audioOutput->state() == QAudio::StoppedState) {
- qWarning() << "status: Stopped, resume()";
m_audioOutput->resume();
m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
} else if (m_audioOutput->state() == QAudio::IdleState) {
- qWarning() << "status: IdleState";
+ // no-op
}
}
-void AudioTest::handleStateChanged(QAudio::State state)
-{
- qWarning() << "state = " << state;
-}
diff --git a/examples/multimedia/audiooutput/audiooutput.h b/examples/multimedia/audiooutput/audiooutput.h
index 30cf35369..80d6d3279 100644
--- a/examples/multimedia/audiooutput/audiooutput.h
+++ b/examples/multimedia/audiooutput/audiooutput.h
@@ -110,11 +110,9 @@ private:
QByteArray m_buffer;
private slots:
- void notified();
void pullTimerExpired();
void toggleMode();
void toggleSuspendResume();
- void handleStateChanged(QAudio::State state);
void deviceChanged(int index);
void volumeChanged(int);
};
diff --git a/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
index 60c9d00d4..c9c69ed99 100644
--- a/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
+++ b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
@@ -29,10 +29,9 @@
\example audiooutput
\title Audio Output Example
\ingroup multimedia_examples
- \brief The Audio Output Example show the use of the QAudioOutput API.
+ \brief Enabling audio playback using the QAudioOutput class.
- The example demonstrates the basic use cases of the QAudioOutput class from
- \l{Qt Multimedia}.
+ \e{Audio Output} demonstrates the basic use cases of QAudioOutput.
\image audiooutput-example.png
diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp
index 2291fed52..7d942255a 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.cpp
+++ b/examples/multimedia/audiorecorder/audiorecorder.cpp
@@ -114,6 +114,8 @@ AudioRecorder::AudioRecorder(QWidget *parent) :
SLOT(updateProgress(qint64)));
connect(audioRecorder, SIGNAL(statusChanged(QMediaRecorder::Status)), this,
SLOT(updateStatus(QMediaRecorder::Status)));
+ connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)),
+ this, SLOT(onStateChanged(QMediaRecorder::State)));
connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this,
SLOT(displayErrorMessage()));
}
@@ -138,47 +140,44 @@ void AudioRecorder::updateStatus(QMediaRecorder::Status status)
switch (status) {
case QMediaRecorder::RecordingStatus:
- if (audioLevels.count() != audioRecorder->audioSettings().channelCount()) {
- qDeleteAll(audioLevels);
- audioLevels.clear();
- for (int i = 0; i < audioRecorder->audioSettings().channelCount(); ++i) {
- QAudioLevel *level = new QAudioLevel(ui->centralwidget);
- audioLevels.append(level);
- ui->levelsLayout->addWidget(level);
- }
- }
-
- ui->recordButton->setText(tr("Stop"));
- ui->pauseButton->setText(tr("Pause"));
- if (audioRecorder->outputLocation().isEmpty())
- statusMessage = tr("Recording");
- else
- statusMessage = tr("Recording to %1").arg(
- audioRecorder->outputLocation().toString());
+ statusMessage = tr("Recording to %1").arg(audioRecorder->actualLocation().toString());
break;
case QMediaRecorder::PausedStatus:
clearAudioLevels();
- ui->recordButton->setText(tr("Stop"));
- ui->pauseButton->setText(tr("Resume"));
statusMessage = tr("Paused");
break;
case QMediaRecorder::UnloadedStatus:
case QMediaRecorder::LoadedStatus:
clearAudioLevels();
- ui->recordButton->setText(tr("Record"));
- ui->pauseButton->setText(tr("Pause"));
statusMessage = tr("Stopped");
default:
break;
}
- ui->pauseButton->setEnabled(audioRecorder->state()
- != QMediaRecorder::StoppedState);
-
if (audioRecorder->error() == QMediaRecorder::NoError)
ui->statusbar->showMessage(statusMessage);
}
+void AudioRecorder::onStateChanged(QMediaRecorder::State state)
+{
+ switch (state) {
+ case QMediaRecorder::RecordingState:
+ ui->recordButton->setText(tr("Stop"));
+ ui->pauseButton->setText(tr("Pause"));
+ break;
+ case QMediaRecorder::PausedState:
+ ui->recordButton->setText(tr("Stop"));
+ ui->pauseButton->setText(tr("Resume"));
+ break;
+ case QMediaRecorder::StoppedState:
+ ui->recordButton->setText(tr("Record"));
+ ui->pauseButton->setText(tr("Pause"));
+ break;
+ }
+
+ ui->pauseButton->setEnabled(audioRecorder->state() != QMediaRecorder::StoppedState);
+}
+
static QVariant boxValue(const QComboBox *box)
{
int idx = box->currentIndex();
@@ -347,6 +346,16 @@ QVector<qreal> getBufferLevels(const T *buffer, int frames, int channels)
void AudioRecorder::processBuffer(const QAudioBuffer& buffer)
{
+ if (audioLevels.count() != buffer.format().channelCount()) {
+ qDeleteAll(audioLevels);
+ audioLevels.clear();
+ for (int i = 0; i < buffer.format().channelCount(); ++i) {
+ QAudioLevel *level = new QAudioLevel(ui->centralwidget);
+ audioLevels.append(level);
+ ui->levelsLayout->addWidget(level);
+ }
+ }
+
QVector<qreal> levels = getBufferLevels(buffer);
for (int i = 0; i < levels.count(); ++i)
audioLevels.at(i)->setLevel(levels.at(i));
diff --git a/examples/multimedia/audiorecorder/audiorecorder.h b/examples/multimedia/audiorecorder/audiorecorder.h
index 2c0a1e5ed..9d013ae7c 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.h
+++ b/examples/multimedia/audiorecorder/audiorecorder.h
@@ -71,6 +71,7 @@ private slots:
void toggleRecord();
void updateStatus(QMediaRecorder::Status);
+ void onStateChanged(QMediaRecorder::State);
void updateProgress(qint64 pos);
void displayErrorMessage();
diff --git a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
index 35f6c0511..317bd5835 100644
--- a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
+++ b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
@@ -29,10 +29,10 @@
\example audiorecorder
\title Audio Recorder Example
\ingroup multimedia_examples
- \brief The Audio Recorder Example shows how to create a simple audio recorder.
+ \brief Discovering the available devices and supported codecs.
- It demonstrates the discovery of the supported devices and codecs and the use
- of recording functions in the QAudioRecorder class.
+ \e{Audio Recorder} demonstrates how to identify the available devices and
+ supported codecs, and the use of QAudioRecorder class.
\image audiorecorder.png
diff --git a/examples/multimedia/spectrum/doc/src/spectrum.qdoc b/examples/multimedia/spectrum/doc/src/spectrum.qdoc
index 3c846afdc..b0adfac6b 100644
--- a/examples/multimedia/spectrum/doc/src/spectrum.qdoc
+++ b/examples/multimedia/spectrum/doc/src/spectrum.qdoc
@@ -29,10 +29,11 @@
\example spectrum
\title Spectrum Example
\ingroup multimedia_examples
- \brief The Spectrum Example uses a combination multimedia APIs to process microphone input.
+ \brief Analyzing a raw audio stream using the FFTReal library.
- The Spectrum Analyzer example shows how the \l{Qt Multimedia} module can be
- used to record and then play back an audio stream.
+ \e Spectrum demonstrates how the \l{Qt Multimedia} module can be used to
+ analyze an audio stream while recording it, and also play the recorded
+ stream.
\image spectrum-demo.png
diff --git a/examples/multimedia/video/doc/images/qmlvideo-menu.jpg b/examples/multimedia/video/doc/images/qmlvideo-menu.jpg
new file mode 100644
index 000000000..54ab877a1
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideo-menu.jpg
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideo-menu.png b/examples/multimedia/video/doc/images/qmlvideo-menu.png
deleted file mode 100644
index b2d773319..000000000
--- a/examples/multimedia/video/doc/images/qmlvideo-menu.png
+++ /dev/null
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideo-overlay.jpg b/examples/multimedia/video/doc/images/qmlvideo-overlay.jpg
new file mode 100644
index 000000000..6a0d48ae6
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideo-overlay.jpg
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideo-overlay.png b/examples/multimedia/video/doc/images/qmlvideo-overlay.png
deleted file mode 100644
index f5dc8390d..000000000
--- a/examples/multimedia/video/doc/images/qmlvideo-overlay.png
+++ /dev/null
Binary files differ
diff --git a/examples/multimedia/video/doc/src/qmlvideo.qdoc b/examples/multimedia/video/doc/src/qmlvideo.qdoc
index 1e80cd176..e50e5775a 100644
--- a/examples/multimedia/video/doc/src/qmlvideo.qdoc
+++ b/examples/multimedia/video/doc/src/qmlvideo.qdoc
@@ -29,13 +29,11 @@
\example video/qmlvideo
\title QML Video Example
\ingroup multimedia_examples
+\brief Transforming video and camera viewfinder content.
-\brief The QML Video Example demonstrates the various manipulations (move;
-resize; rotate; change aspect ratio) which can be applied to QML \l{VideoOutput}
-items.
-
-This example demonstrates the various manipulations (move; resize; rotate;
-change aspect ratio) which can be applied to QML \l{VideoOutput} items.
+\e{QML Video} demonstrates the various transformations (move; resize; rotate;
+change aspect ratio) that can be applied to QML \l VideoOutput and \l Camera
+types.
It also shows how native code can be combined with QML to implement more
advanced functionality - in this case, C++ code is used to calculate the QML
@@ -46,7 +44,7 @@ The following image shows the application executing the video-overlay scene,
which creates a dummy overlay item (just a semi-transparent \l{Rectangle}),
which moves across the \l{VideoOutput} item.
-\image qmlvideo-overlay.png
+\image qmlvideo-overlay.jpg
\include examples-run.qdocinc
@@ -67,7 +65,7 @@ the following items:
average over the past second.
\endlist
-\image qmlvideo-menu.png
+\image qmlvideo-menu.jpg
Each scene in the flickable list is implemented in its own QML file - for
example the video-basic scene (which just displays a static \l{VideoOutput}
diff --git a/examples/multimedia/video/doc/src/qmlvideofx.qdoc b/examples/multimedia/video/doc/src/qmlvideofx.qdoc
index b24114084..52b5d7843 100644
--- a/examples/multimedia/video/doc/src/qmlvideofx.qdoc
+++ b/examples/multimedia/video/doc/src/qmlvideofx.qdoc
@@ -30,23 +30,21 @@
\title QML Video Shader Effects Example
\ingroup multimedia_examples
-\brief The QML Video Shader Effects Example shows how \l {ShaderEffect}
-can be used to apply postprocessing effects, expressed in \c GLSL, to video
-and camera viewfinder content.
+\brief Applying shader effects on video and camera viewfinder content.
\include examples-run.qdocinc
\section1 Overview
-This example shows how a \l {ShaderEffect} can be used to apply
-postprocessing effects, expressed in GLSL, to QML \l {VideoOutput} items.
+\e{QML Video Shader Effects} demonstrates how a \l ShaderEffect can be used to
+apply postprocessing effects, expressed in GLSL, to QML \l VideoOutput type.
It also shows how native code can be combined with QML to implement more
advanced functionality - in this case, C++ code is used to calculate the QML
frame rate. This value is rendered in QML in a semi-transparent item
overlaid on the video content.
-The following screenshots show shader effects being applied. In each case,
+The following screenshots show shader effects being applied. In each case,
the effect is implemented using a fragment shader.
Here we see an edge detection algorithm being applied to a video clip
diff --git a/examples/multimedia/video/qmlvideo/images/close.png b/examples/multimedia/video/qmlvideo/images/close.png
deleted file mode 100644
index 6904df0e4..000000000
--- a/examples/multimedia/video/qmlvideo/images/close.png
+++ /dev/null
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/folder.png b/examples/multimedia/video/qmlvideo/images/folder.png
index e53e2ad46..62d97004f 100644
--- a/examples/multimedia/video/qmlvideo/images/folder.png
+++ b/examples/multimedia/video/qmlvideo/images/folder.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/progress_handle.svg b/examples/multimedia/video/qmlvideo/images/progress_handle.svg
deleted file mode 100644
index 7ad9014e3..000000000
--- a/examples/multimedia/video/qmlvideo/images/progress_handle.svg
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="10px"
- height="46px"
- version="1.1">
- <g>
- <defs>
- <linearGradient id="MyGradient1" x1="0%" y1="0%" x2="100%" y2="100%">
- <stop offset="0%" stop-color="lightcyan" />
- <stop offset="100%" stop-color="dodgerblue" />
- </linearGradient>
- </defs>
- <rect
- stroke="white"
- fill="url(#MyGradient1)"
- stroke-linecap="round"
- stroke-linejoin="round"
- stroke-width="2"
- width="8"
- height="44"
- x="1"
- y="1"
- rx="4"
- ry="4"/>
- </g>
-</svg>
diff --git a/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg b/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg
deleted file mode 100644
index c9c6c486c..000000000
--- a/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="10px"
- height="46px"
- version="1.1">
- <g>
- <defs>
- <linearGradient id="MyGradient1" x1="0%" y1="0%" x2="100%" y2="100%">
- <stop offset="0%" stop-color="skyblue" />
- <stop offset="100%" stop-color="darkblue" />
- </linearGradient>
- </defs>
- <rect
- stroke="white"
- fill="url(#MyGradient1)"
- stroke-linecap="round"
- stroke-linejoin="round"
- stroke-width="2"
- width="8"
- height="44"
- x="1"
- y="1"
- rx="4"
- ry="4"/>
- </g>
-</svg>
diff --git a/examples/multimedia/video/qmlvideo/images/titlebar.png b/examples/multimedia/video/qmlvideo/images/titlebar.png
deleted file mode 100644
index 51c90082d..000000000
--- a/examples/multimedia/video/qmlvideo/images/titlebar.png
+++ /dev/null
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/titlebar.sci b/examples/multimedia/video/qmlvideo/images/titlebar.sci
deleted file mode 100644
index 0418d94cd..000000000
--- a/examples/multimedia/video/qmlvideo/images/titlebar.sci
+++ /dev/null
@@ -1,5 +0,0 @@
-border.left: 10
-border.top: 12
-border.bottom: 12
-border.right: 10
-source: titlebar.png
diff --git a/examples/multimedia/video/qmlvideo/images/up.png b/examples/multimedia/video/qmlvideo/images/up.png
index b05f8025d..6823de004 100644
--- a/examples/multimedia/video/qmlvideo/images/up.png
+++ b/examples/multimedia/video/qmlvideo/images/up.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp
index 5d5b8b33d..3edee5ab6 100644
--- a/examples/multimedia/video/qmlvideo/main.cpp
+++ b/examples/multimedia/video/qmlvideo/main.cpp
@@ -123,13 +123,14 @@ int main(int argc, char *argv[])
const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
const QUrl videoPath =
- QUrl::fromLocalFile(moviesLocation.isEmpty() ?
- app.applicationDirPath() :
- moviesLocation.front());
+ QUrl::fromLocalFile(moviesLocation.isEmpty() ?
+ app.applicationDirPath() :
+ moviesLocation.front());
viewer.rootContext()->setContextProperty("videoPath", videoPath);
QMetaObject::invokeMethod(rootObject, "init");
+ viewer.setMinimumSize(QSize(640, 360));
viewer.show();
return app.exec();
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml
index ea686ea3f..4f5cbada4 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml
@@ -33,30 +33,31 @@
import QtQuick 2.0
-Rectangle {
+Item {
id: root
- color: textColor
- radius: 0.25 * height
property string text
- property color bgColor: "white"
- property color bgColorSelected: "red"
- property color textColor: "black"
+ property color bgColor: "#757575"
+ property color bgColorSelected: "#bdbdbd"
+ property color textColor: "white"
+ property color textColorSelected: "black"
property alias enabled: mouseArea.enabled
+ property alias radius: bgr.radius
signal clicked
Rectangle {
- anchors { fill: parent; margins: 1 }
+ id: bgr
+ anchors.fill: parent
color: mouseArea.pressed ? bgColorSelected : bgColor
- radius: 0.25 * height
+ radius: height / 15
Text {
id: text
anchors.centerIn: parent
text: root.text
- font.pixelSize: 0.5 * parent.height
- color: mouseArea.pressed ? bgColor : textColor
+ font.pixelSize: 0.4 * parent.height
+ color: mouseArea.pressed ? textColorSelected : textColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml
index 30b1e32b8..3094c1a3b 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml
@@ -97,21 +97,16 @@ Rectangle {
}
function initialize() {
- console.log("[qmlvideo] Content.initialize: contentType " + contentType)
if ("video" == contentType) {
- console.log("[qmlvideo] Content.initialize: loading VideoItem.qml")
contentLoader.source = "VideoItem.qml"
if (Loader.Error == contentLoader.status) {
- console.log("[qmlvideo] Content.initialize: loading VideoDummy.qml")
contentLoader.source = "VideoDummy.qml"
dummy = true
}
contentLoader.item.volume = volume
} else if ("camera" == contentType) {
- console.log("[qmlvideo] Content.initialize: loading CameraItem.qml")
contentLoader.source = "CameraItem.qml"
if (Loader.Error == contentLoader.status) {
- console.log("[qmlvideo] Content.initialize: loading CameraDummy.qml")
contentLoader.source = "CameraDummy.qml"
dummy = true
}
@@ -127,12 +122,10 @@ Rectangle {
if (root.autoStart)
root.start()
}
- console.log("[qmlvideo] Content.initialize: complete")
root.initialized()
}
function start() {
- console.log("[qmlvideo] Content.start")
if (contentLoader.item) {
if (root.contentType == "video")
contentLoader.item.mediaSource = root.source
@@ -142,7 +135,6 @@ Rectangle {
}
function stop() {
- console.log("[qmlvideo] Content.stop")
if (contentLoader.item) {
contentLoader.item.stop()
if (root.contentType == "video")
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml
deleted file mode 100644
index 74f951b13..000000000
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtSystemInfo 5.0
-// NOTE: The QtSystemInfo module is not yet part of Qt 5
-
-Item {
- ScreenSaver {
- screenSaverInhibited: true
- }
-}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml
index c9e7cd109..33a55ebd7 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml
@@ -38,6 +38,8 @@ Rectangle {
color: "transparent"
opacity: 0.0
property alias enabled: mouseArea.enabled
+ property int dialogWidth: 300
+ property int dialogHeight: 200
state: enabled ? "on" : "baseState"
states: [
@@ -70,9 +72,9 @@ Rectangle {
Rectangle {
anchors.centerIn: parent
- width: 300
- height: 200
- radius: 10
+ width: dialogWidth
+ height: dialogHeight
+ radius: 5
color: "white"
Text {
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml
index 466ea8b97..33109bd34 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml
@@ -40,6 +40,9 @@ Rectangle {
property string folder
+ property int itemHeight: Math.min(parent.width, parent.height) / 15
+ property int buttonHeight: Math.min(parent.width, parent.height) / 12
+
signal fileSelected(string file)
function selectFile(file) {
@@ -66,12 +69,12 @@ Rectangle {
Rectangle {
id: root
- color: "white"
+ color: "black"
property bool showFocusHighlight: false
property variant folders: folders1
property variant view: view1
property alias folder: folders1.folder
- property color textColor: "black"
+ property color textColor: "white"
FolderListModel {
id: folders1
@@ -103,34 +106,39 @@ Rectangle {
fileBrowser.selectFile(path)
}
width: root.width
- height: 52
+ height: folderImage.height
color: "transparent"
Rectangle {
- id: highlight; visible: false
+ id: highlight
+ visible: false
anchors.fill: parent
- color: palette.highlight
- gradient: Gradient {
- GradientStop { id: t1; position: 0.0; color: palette.highlight }
- GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
- }
+ anchors.leftMargin: 5
+ anchors.rightMargin: 5
+ color: "#212121"
}
Item {
- width: 48; height: 48
+ id: folderImage
+ width: itemHeight
+ height: itemHeight
Image {
+ id: folderPicture
source: "qrc:/folder.png"
- anchors.centerIn: parent
+ width: itemHeight * 0.9
+ height: itemHeight * 0.9
+ anchors.left: parent.left
+ anchors.margins: 5
visible: folders.isFolder(index)
}
}
Text {
id: nameText
- anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ anchors.fill: parent;
+ verticalAlignment: Text.AlignVCenter
text: fileName
- anchors.leftMargin: 54
- font.pixelSize: 32
+ anchors.leftMargin: itemHeight + 10
color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor
elide: Text.ElideRight
}
@@ -142,7 +150,7 @@ Rectangle {
root.showFocusHighlight = false;
wrapper.ListView.view.currentIndex = index;
}
- onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ onClicked: { if (folders === wrapper.ListView.view.model) launch() }
}
states: [
@@ -160,17 +168,12 @@ Rectangle {
id: view1
anchors.top: titleBar.bottom
anchors.bottom: cancelButton.top
- x: 0
width: parent.width
model: folders1
delegate: folderDelegate
highlight: Rectangle {
- color: palette.highlight
+ color: "#212121"
visible: root.showFocusHighlight && view1.count != 0
- gradient: Gradient {
- GradientStop { id: t1; position: 0.0; color: palette.highlight }
- GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
- }
width: view1.currentItem == null ? 0 : view1.currentItem.width
}
highlightMoveVelocity: 1000
@@ -215,12 +218,8 @@ Rectangle {
model: folders2
delegate: folderDelegate
highlight: Rectangle {
- color: palette.highlight
+ color: "#212121"
visible: root.showFocusHighlight && view2.count != 0
- gradient: Gradient {
- GradientStop { id: t1; position: 0.0; color: palette.highlight }
- GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
- }
width: view1.currentItem == null ? 0 : view1.currentItem.width
}
highlightMoveVelocity: 1000
@@ -254,19 +253,29 @@ Rectangle {
}
Rectangle {
- id: cancelButton
- width: 100
- height: titleBar.height - 7
+ width: parent.width
+ height: buttonHeight + 10
+ anchors.bottom: parent.bottom
color: "black"
- anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter }
+ }
+
+ Rectangle {
+ id: cancelButton
+ width: parent.width
+ height: buttonHeight
+ color: "#212121"
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: 5
+ radius: buttonHeight / 15
Text {
- anchors { fill: parent; margins: 4 }
+ anchors.fill: parent
text: "Cancel"
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- font.pixelSize: 20
}
MouseArea {
@@ -277,55 +286,66 @@ Rectangle {
Keys.onPressed: {
root.keyPressed(event.key);
- if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ if (event.key === Qt.Key_Return || event.key === Qt.Key_Select || event.key === Qt.Key_Right) {
view.currentItem.launch();
event.accepted = true;
- } else if (event.key == Qt.Key_Left) {
+ } else if (event.key === Qt.Key_Left) {
up();
}
}
- BorderImage {
- source: "qrc:/titlebar.sci";
- width: parent.width;
- height: 52
- y: -7
+
+ Rectangle {
id: titleBar
+ width: parent.width
+ height: buttonHeight + 10
+ anchors.top: parent.top
+ color: "black"
Rectangle {
- id: upButton
- width: 48
- height: titleBar.height - 7
- color: "transparent"
- Image { anchors.centerIn: parent; source: "qrc:/up.png" }
- MouseArea { id: upRegion; anchors.centerIn: parent
- width: 56
- height: 56
- onClicked: up()
- }
- states: [
- State {
- name: "pressed"
- when: upRegion.pressed
- PropertyChanges { target: upButton; color: palette.highlight }
- }
- ]
- }
+ width: parent.width;
+ height: buttonHeight
+ color: "#212121"
+ anchors.margins: 5
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ radius: buttonHeight / 15
- Rectangle {
- color: "gray"
- x: 48
- width: 1
- height: 44
- }
+ Rectangle {
+ id: upButton
+ width: buttonHeight
+ height: buttonHeight
+ color: "transparent"
+ Image {
+ width: itemHeight
+ height: itemHeight
+ anchors.centerIn: parent
+ source: "qrc:/up.png"
+ }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: buttonHeight
+ height: buttonHeight
+ onClicked: up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
- Text {
- anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
- anchors.leftMargin: 4; anchors.rightMargin: 4
- text: folders.folder
- color: "white"
- elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
- font.pixelSize: 32
+ Text {
+ anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 5; anchors.rightMargin: 5
+ text: folders.folder
+ color: "white"
+ elide: Text.ElideLeft;
+ horizontalAlignment: Text.AlignLeft;
+ verticalAlignment: Text.AlignVCenter
+ }
}
}
@@ -366,14 +386,14 @@ Rectangle {
function keyPressed(key) {
switch (key) {
- case Qt.Key_Up:
- case Qt.Key_Down:
- case Qt.Key_Left:
- case Qt.Key_Right:
- root.showFocusHighlight = true;
+ case Qt.Key_Up:
+ case Qt.Key_Down:
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.showFocusHighlight = true;
break;
- default:
- // do nothing
+ default:
+ // do nothing
break;
}
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml
index 5443dc846..04c852a96 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml
@@ -39,9 +39,9 @@ Rectangle {
property alias buttonHeight: closeButton.height
property string source1
property string source2
- property int contentWidth: 250
+ property int contentWidth: parent.width / 2
property real volume: 0.25
- property int margins: 10
+ property int margins: 5
property QtObject content
signal close
@@ -54,9 +54,12 @@ Rectangle {
right: parent.right
margins: root.margins
}
- width: 50
- height: 30
+ width: Math.max(parent.width, parent.height) / 12
+ height: Math.min(parent.width, parent.height) / 12
z: 2.0
+ bgColor: "#212121"
+ bgColorSelected: "#757575"
+ textColorSelected: "white"
text: "Back"
onClicked: root.close()
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml
index 560262db2..dd2dfaf54 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml
@@ -59,15 +59,13 @@ Scene {
}
text: content.started ? "Tap the screen to stop content"
: "Tap the screen to start content"
- color: "yellow"
- font.pixelSize: 20
+ color: "#e0e0e0"
z: 2.0
}
MouseArea {
anchors.fill: parent
onClicked: {
- console.log("[qmlvideo] SceneBasic.onClicked, started = " + content.started)
if (content.started)
content.stop()
else
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml
index aa2b42678..63f94de28 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml
@@ -86,8 +86,7 @@ Scene {
margins: 20
}
text: "Tap on the content to toggle full-screen mode"
- color: "yellow"
- font.pixelSize: 20
+ color: "#e0e0e0"
z: 2.0
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml
index 7824589e0..99159591d 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml
@@ -91,8 +91,7 @@ Scene {
margins: 20
}
text: "Tap on the content to toggle full-screen mode"
- color: "yellow"
- font.pixelSize: 20
+ color: "#e0e0e0"
z: 2.0
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml
index f31cc9580..042c609d3 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml
@@ -65,8 +65,7 @@ Scene {
margins: 20
}
text: content() ? content().started ? "Tap to stop" : "Tap to start" : ""
- color: "yellow"
- font.pixelSize: 20
+ color: "#e0e0e0"
}
MouseArea {
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml
index 1f4559a5f..bdeff4e19 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml
@@ -53,7 +53,7 @@ Scene {
y: 0.5 * parent.height
width: content.width
height: content.height
- color: "yellow"
+ color: "#e0e0e0"
opacity: 0.5
SequentialAnimation on x {
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml
index cfba508a2..2ad65f606 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml
@@ -56,7 +56,7 @@ Scene {
bottom: rotateNegativeButton.top
margins: parent.margins
}
- width: 90
+ width: Math.max(parent.width, parent.height) / 10
height: root.buttonHeight
text: "Rotate +" + delta
onClicked: content.rotation = content.rotation + delta
@@ -69,7 +69,7 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: 90
+ width: Math.max(parent.width, parent.height) / 10
height: root.buttonHeight
text: "Rotate -" + delta
onClicked: content.rotation = content.rotation - delta
@@ -82,7 +82,7 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: 30
+ width: Math.max(parent.width, parent.height) / 25
height: root.buttonHeight
enabled: false
text: content.rotation % 360
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml
index 976644b4b..8e6d11a86 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml
@@ -39,44 +39,64 @@ Rectangle {
property string sceneSource: ""
ListModel {
- id: list
- ListElement { name: "multi"; source: "SceneMulti.qml" }
- ListElement { name: "video"; source: "VideoBasic.qml" }
- ListElement { name: "video-drag"; source: "VideoDrag.qml" }
- ListElement { name: "video-fillmode"; source: "VideoFillMode.qml" }
- ListElement { name: "video-fullscreen"; source: "VideoFullScreen.qml" }
- ListElement { name: "video-fullscreen-inverted"; source: "VideoFullScreenInverted.qml" }
- ListElement { name: "video-metadata"; source: "VideoMetadata.qml" }
- ListElement { name: "video-move"; source: "VideoMove.qml" }
- ListElement { name: "video-overlay"; source: "VideoOverlay.qml" }
- ListElement { name: "video-playbackrate"; source: "VideoPlaybackRate.qml" }
- ListElement { name: "video-resize"; source: "VideoResize.qml" }
- ListElement { name: "video-rotate"; source: "VideoRotate.qml" }
- ListElement { name: "video-spin"; source: "VideoSpin.qml" }
- ListElement { name: "video-seek"; source: "VideoSeek.qml" }
- ListElement { name: "camera"; source: "CameraBasic.qml" }
- ListElement { name: "camera-drag"; source: "CameraDrag.qml" }
- ListElement { name: "camera-fullscreen"; source: "CameraFullScreen.qml" }
- ListElement { name: "camera-fullscreen-inverted"; source: "CameraFullScreenInverted.qml" }
- ListElement { name: "camera-move"; source: "CameraMove.qml" }
- ListElement { name: "camera-overlay"; source: "CameraOverlay.qml" }
- ListElement { name: "camera-resize"; source: "CameraResize.qml" }
- ListElement { name: "camera-rotate"; source: "CameraRotate.qml" }
- ListElement { name: "camera-spin"; source: "CameraSpin.qml" }
+ id: videolist
+ ListElement { name: "Multi"; source: "SceneMulti.qml" }
+ ListElement { name: "Video"; source: "VideoBasic.qml" }
+ ListElement { name: "Drag"; source: "VideoDrag.qml" }
+ ListElement { name: "Fillmode"; source: "VideoFillMode.qml" }
+ ListElement { name: "Fullscreen"; source: "VideoFullScreen.qml" }
+ ListElement { name: "Fullscreen-inverted"; source: "VideoFullScreenInverted.qml" }
+ ListElement { name: "Metadata"; source: "VideoMetadata.qml" }
+ ListElement { name: "Move"; source: "VideoMove.qml" }
+ ListElement { name: "Overlay"; source: "VideoOverlay.qml" }
+ ListElement { name: "Playback Rate"; source: "VideoPlaybackRate.qml" }
+ ListElement { name: "Resize"; source: "VideoResize.qml" }
+ ListElement { name: "Rotate"; source: "VideoRotate.qml" }
+ ListElement { name: "Spin"; source: "VideoSpin.qml" }
+ ListElement { name: "Seek"; source: "VideoSeek.qml" }
+ }
+
+ ListModel {
+ id: cameralist
+ ListElement { name: "Camera"; source: "CameraBasic.qml" }
+ ListElement { name: "Drag"; source: "CameraDrag.qml" }
+ ListElement { name: "Fullscreen"; source: "CameraFullScreen.qml" }
+ ListElement { name: "Fullscreen-inverted"; source: "CameraFullScreenInverted.qml" }
+ ListElement { name: "Move"; source: "CameraMove.qml" }
+ ListElement { name: "Overlay"; source: "CameraOverlay.qml" }
+ ListElement { name: "Resize"; source: "CameraResize.qml" }
+ ListElement { name: "Rotate"; source: "CameraRotate.qml" }
+ ListElement { name: "Spin"; source: "CameraSpin.qml" }
+ }
+
+ Component {
+ id: leftDelegate
+ Item {
+ width: root.width / 2
+ height: 0.8 * itemHeight
+
+ Button {
+ anchors.fill: parent
+ anchors.margins: 5
+ anchors.rightMargin: 2.5
+ anchors.bottomMargin: 0
+ text: name
+ onClicked: root.sceneSource = source
+ }
+ }
}
Component {
- id: delegate
+ id: rightDelegate
Item {
- id: delegateItem
- width: root.width
- height: itemHeight
+ width: root.width / 2
+ height: 0.8 * itemHeight
Button {
- id: selectorItem
- anchors.centerIn: parent
- width: 0.9 * parent.width
- height: 0.8 * itemHeight
+ anchors.fill: parent
+ anchors.margins: 5
+ anchors.leftMargin: 2.5
+ anchors.bottomMargin: 0
text: name
onClicked: root.sceneSource = source
}
@@ -85,20 +105,29 @@ Rectangle {
Flickable {
anchors.fill: parent
- contentHeight: (itemHeight * list.count) + layout.anchors.topMargin + layout.spacing
+ contentHeight: (itemHeight * videolist.count) + 10
clip: true
- Column {
+ Row {
id: layout
-
anchors {
fill: parent
- topMargin: 10
+ topMargin: 5
+ bottomMargin: 5
+ }
+
+ Column {
+ Repeater {
+ model: videolist
+ delegate: leftDelegate
+ }
}
- Repeater {
- model: list
- delegate: delegate
+ Column {
+ Repeater {
+ model: cameralist
+ delegate: rightDelegate
+ }
}
}
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml
index 9c3810134..f14fa402c 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml
@@ -35,7 +35,7 @@ import QtQuick 2.0
Item {
id: seekControl
- height: 46
+ height: Math.min(parent.width, parent.height) / 20
property int duration: 0
property int playPosition: 0
property int seekPosition: 0
@@ -45,8 +45,9 @@ Item {
Rectangle {
id: background
anchors.fill: parent
- color: "black"
+ color: "white"
opacity: 0.3
+ radius: parent.height / 15
}
Rectangle {
@@ -60,7 +61,6 @@ Item {
Text {
width: 90
anchors { left: parent.left; top: parent.top; bottom: parent.bottom; leftMargin: 10 }
- font { family: "Nokia Sans S60"; pixelSize: 24 }
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: "white"
@@ -71,7 +71,6 @@ Item {
Text {
width: 90
anchors { right: parent.right; top: parent.top; bottom: parent.bottom; rightMargin: 10 }
- font { family: "Nokia Sans S60"; pixelSize: 24 }
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
color: "white"
@@ -79,35 +78,36 @@ Item {
text: formatTime(duration)
}
- Image {
+ Rectangle {
id: progressHandle
- height: 46
- width: 10
- source: mouseArea.pressed ? "qrc:/images/progress_handle_pressed.svg" : "qrc:/images/progress_handle.svg"
+ height: parent.height
+ width: parent.height / 2
+ color: "white"
+ opacity: 0.5
anchors.verticalCenter: progressBar.verticalCenter
- x: seekControl.duration == 0 ? 0 : seekControl.playPosition / seekControl.duration * 630
+ x: seekControl.duration == 0 ? 0 : seekControl.playPosition / seekControl.duration * background.width
MouseArea {
id: mouseArea
anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom }
- height: 46+16
- width: height
+ height: parent.height
+ width: parent.height * 2
enabled: seekControl.enabled
drag {
target: progressHandle
axis: Drag.XAxis
minimumX: 0
- maximumX: 631
+ maximumX: background.width
}
onPressed: {
seekControl.seeking = true;
}
onCanceled: {
- seekControl.seekPosition = progressHandle.x * seekControl.duration / 630
+ seekControl.seekPosition = progressHandle.x * seekControl.duration / background.width
seekControl.seeking = false
}
onReleased: {
- seekControl.seekPosition = progressHandle.x * seekControl.duration / 630
+ seekControl.seekPosition = progressHandle.x * seekControl.duration / background.width
seekControl.seeking = false
mouse.accepted = true
}
@@ -120,7 +120,7 @@ Item {
interval: 300
running: seekControl.seeking
onTriggered: {
- seekControl.seekPosition = progressHandle.x*seekControl.duration/630
+ seekControl.seekPosition = progressHandle.x*seekControl.duration / background.width
}
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml
index f623aa412..b114d5bb4 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml
@@ -54,16 +54,16 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: 150
+ width: Math.max(parent.width, parent.height) / 5
height: root.buttonHeight
text: "PreserveAspectFit"
onClicked: {
if (!content.dummy) {
var video = content.contentItem()
- if (video.fillMode == VideoOutput.Stretch) {
+ if (video.fillMode === VideoOutput.Stretch) {
video.fillMode = VideoOutput.PreserveAspectFit
text = "PreserveAspectFit"
- } else if (video.fillMode == VideoOutput.PreserveAspectFit) {
+ } else if (video.fillMode === VideoOutput.PreserveAspectFit) {
video.fillMode = VideoOutput.PreserveAspectCrop
text = "PreserveAspectCrop"
} else {
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml
index 00580f782..05c6dd76c 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml
@@ -56,55 +56,55 @@ Scene {
Column {
anchors.fill: parent
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Title:" + content.contentItem().metaData.title
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Size:" + content.contentItem().metaData.size
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Resolution:" + content.contentItem().metaData.resolution
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Media type:" + content.contentItem().metaData.mediaType
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Video codec:" + content.contentItem().metaData.videoCodec
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Video bit rate:" + content.contentItem().metaData.videoBitRate
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Video frame rate:" +content.contentItem().metaData.videoFrameRate
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Audio codec:" + content.contentItem().metaData.audioCodec
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Audio bit rate:" + content.contentItem().metaData.audioBitRate
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Date:" + content.contentItem().metaData.date
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Description:" + content.contentItem().metaData.description
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Copyright:" + content.contentItem().metaData.copyright
}
Text {
- color: "yellow"
+ color: "#e0e0e0"
text: "Seekable:" + content.contentItem().metaData.seekable
}
}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml
index 5c1e6ab17..45d599b34 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml
@@ -56,12 +56,12 @@ Scene {
bottom: decreaseButton.top
margins: parent.margins
}
- width: 90
+ width: Math.max(parent.width, parent.height) / 10
height: root.buttonHeight
text: "Increase"
onClicked: {
var video = content.contentItem()
- video.playbackRate = video.playbackRate + delta
+ video.playbackRate += delta
}
}
@@ -72,12 +72,12 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: 90
+ width: Math.max(parent.width, parent.height) / 10
height: root.buttonHeight
text: "Decrease"
onClicked: {
var video = content.contentItem()
- video.playbackRate = video.playbackRate - delta
+ video.playbackRate -= delta
}
}
@@ -88,7 +88,7 @@ Scene {
verticalCenter: parent.verticalCenter
margins: parent.margins
}
- width: 50
+ width: Math.max(parent.width, parent.height) / 25
height: root.buttonHeight
enabled: false
text: Math.round(10 * content.contentItem().playbackRate) / 10
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml
index 2d43bdf6e..05a312e37 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml
@@ -36,6 +36,7 @@ import QtQuick 2.0
Scene {
id: root
property string contentType: "video"
+ contentWidth: parent.width
Content {
id: content
@@ -51,13 +52,12 @@ Scene {
anchors {
left: parent.left
right: parent.right
- leftMargin: 100
- rightMargin: 140
+ margins: 10
bottom: parent.bottom
}
duration: content.contentItem() ? content.contentItem().duration : 0
playPosition: content.contentItem() ? content.contentItem().position : 0
- onSeekPositionChanged: { content.contentItem().seek(seekPosition); }
+ onSeekPositionChanged: content.contentItem().seek(seekPosition);
}
Component.onCompleted: root.content = content
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml
index 4422648c0..96acb4bc4 100644
--- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml
@@ -35,28 +35,21 @@ import QtQuick 2.0
Rectangle {
id: root
- width: 640
- height: 360
+ anchors.fill: parent
color: "black"
property string source1
property string source2
- property color bgColor: "#002244"
+ property color bgColor: "black"
property real volume: 0.25
property bool perfMonitorsLogging: false
property bool perfMonitorsVisible: false
QtObject {
id: d
- property int itemHeight: 40
+ property int itemHeight: root.height > root.width ? root.width / 10 : root.height / 10
property int buttonHeight: 0.8 * itemHeight
- property int margins: 10
- }
-
- // Create ScreenSaver element via Loader, so this app will still run if the
- // SystemInfo module is not available
- Loader {
- source: "DisableScreenSaver.qml"
+ property int margins: 5
}
Loader {
@@ -71,7 +64,6 @@ Rectangle {
}
function init() {
- console.log("[qmlvideo] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible)
var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
source = enabled ? "../performancemonitor/PerformanceItem.qml" : ""
}
@@ -99,6 +91,9 @@ Rectangle {
right: exitButton.left
margins: d.margins
}
+ bgColor: "#212121"
+ bgColorSelected: "#757575"
+ textColorSelected: "white"
height: d.buttonHeight
text: (root.source1 == "") ? "Select file 1" : root.source1
onClicked: fileBrowser1.show()
@@ -112,6 +107,9 @@ Rectangle {
right: exitButton.left
margins: d.margins
}
+ bgColor: "#212121"
+ bgColorSelected: "#757575"
+ textColorSelected: "white"
height: d.buttonHeight
text: (root.source2 == "") ? "Select file 2" : root.source2
onClicked: fileBrowser2.show()
@@ -124,26 +122,58 @@ Rectangle {
right: parent.right
margins: d.margins
}
- width: 50
+ bgColor: "#212121"
+ bgColorSelected: "#757575"
+ textColorSelected: "white"
+ width: parent.width / 10
height: d.buttonHeight
text: "Exit"
onClicked: Qt.quit()
}
+ Row {
+ id: modes
+ anchors.top: openFile2Button.bottom
+ anchors.margins: 0
+ anchors.topMargin: 5
+ Button {
+ width: root.width / 2
+ height: 0.8 * d.itemHeight
+ bgColor: "#212121"
+ radius: 0
+ text: "Video Modes"
+ enabled: false
+ }
+ Button {
+ width: root.width / 2
+ height: 0.8 * d.itemHeight
+ bgColor: "#212121"
+ radius: 0
+ text: "Camera Modes"
+ enabled: false
+ }
+ }
+
+ Rectangle {
+ id: divider
+ height: 1
+ width: parent.width
+ color: "black"
+ anchors.top: modes.bottom
+ }
+
SceneSelectionPanel {
id: sceneSelectionPanel
itemHeight: d.itemHeight
- color: "#004444"
+ color: "#212121"
anchors {
- top: openFile2Button.bottom
+ top: divider.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
- margins: d.margins
}
- radius: 10
+ radius: 0
onSceneSourceChanged: {
- console.log("[qmlvideo] main.onSceneSourceChanged source " + sceneSource)
sceneLoader.source = sceneSource
var scene = null
var innerVisible = true
@@ -213,7 +243,9 @@ Rectangle {
ErrorDialog {
id: errorDialog
- anchors.fill: parent
+ anchors.fill: root
+ dialogWidth: d.itemHeight * 5
+ dialogHeight: d.itemHeight * 3
enabled: false
}
@@ -230,7 +262,6 @@ Rectangle {
}
function closeScene() {
- console.log("[qmlvideo] main.closeScene")
sceneSelectionPanel.sceneSource = ""
}
}
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.qrc b/examples/multimedia/video/qmlvideo/qmlvideo.qrc
index 5bf2df8af..6418215d0 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo.qrc
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.qrc
@@ -1,13 +1,8 @@
<RCC>
<qresource prefix="/">
<file alias="leaves.jpg">images/leaves.jpg</file>
- <file alias="close.png">images/close.png</file>
<file alias="folder.png">images/folder.png</file>
- <file alias="titlebar.png">images/titlebar.png</file>
- <file alias="titlebar.sci">images/titlebar.sci</file>
<file alias="up.png">images/up.png</file>
- <file alias="progress_handle.svg">images/progress_handle.svg</file>
- <file alias="progress_handle_pressed.svg">images/progress_handle_pressed.svg</file>
<file>qml/qmlvideo/Button.qml</file>
<file>qml/qmlvideo/CameraBasic.qml</file>
<file>qml/qmlvideo/CameraDrag.qml</file>
@@ -21,7 +16,6 @@
<file>qml/qmlvideo/CameraRotate.qml</file>
<file>qml/qmlvideo/CameraSpin.qml</file>
<file>qml/qmlvideo/Content.qml</file>
- <file>qml/qmlvideo/DisableScreenSaver.qml</file>
<file>qml/qmlvideo/ErrorDialog.qml</file>
<file>qml/qmlvideo/FileBrowser.qml</file>
<file>qml/qmlvideo/main.qml</file>
diff --git a/examples/multimedia/video/qmlvideofx/filereader.cpp b/examples/multimedia/video/qmlvideofx/filereader.cpp
index 5f5066f12..714c0914d 100644
--- a/examples/multimedia/video/qmlvideofx/filereader.cpp
+++ b/examples/multimedia/video/qmlvideofx/filereader.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "filereader.h"
-#include "trace.h"
#include <QCoreApplication>
#include <QDir>
@@ -42,7 +41,6 @@
QString FileReader::readFile(const QString &fileName)
{
- qtTrace() << "FileReader::readFile" << "fileName" << fileName;
QString content;
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
index 0a2a1584f..19785ce86 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
@@ -84,7 +84,6 @@ Rectangle {
}
onEffectSourceChanged: {
- console.log("[qmlvideofx] Content.onEffectSourceChanged " + effectSource)
effectLoader.source = effectSource
effectLoader.item.parent = root
effectLoader.item.targetWidth = root.width
@@ -96,7 +95,6 @@ Rectangle {
}
function init() {
- console.log("[qmlvideofx] Content.init")
openImage("qrc:/images/qt-logo.png")
root.effectSource = "EffectPassThrough.qml"
}
@@ -107,7 +105,6 @@ Rectangle {
}
function updateSource() {
- console.log("[qmlvideofx] Content.updateSource")
if (contentLoader.item) {
contentLoader.item.parent = root
contentLoader.item.anchors.fill = root
@@ -118,7 +115,6 @@ Rectangle {
}
function openImage(path) {
- console.log("[qmlvideofx] Content.openImage \"" + path + "\"")
stop()
contentLoader.source = "ContentImage.qml"
videoFramePaintedConnection.target = null
@@ -127,7 +123,6 @@ Rectangle {
}
function openVideo(path) {
- console.log("[qmlvideofx] Content.openVideo \"" + path + "\"")
stop()
contentLoader.source = "ContentVideo.qml"
videoFramePaintedConnection.target = contentLoader.item
@@ -138,7 +133,6 @@ Rectangle {
}
function openCamera() {
- console.log("[qmlvideofx] Content.openCamera")
stop()
contentLoader.source = "ContentCamera.qml"
videoFramePaintedConnection.target = contentLoader.item
@@ -146,7 +140,6 @@ Rectangle {
}
function stop() {
- console.log("[qmlvideofx] Content.stop")
if (contentLoader.source == "ContentVideo.qml")
contentLoader.item.stop()
theSource.sourceItem = null
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml
deleted file mode 100644
index fcf43f4b6..000000000
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtMultimedia 5.0
-
-VideoOutput {
- source: camera
-
- Camera {
- id: camera
- }
-}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml
deleted file mode 100644
index ccd852bff..000000000
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtMobility.systeminfo 1.1
-// NOTE: The QtSystemInfo module is not yet part of Qt 5
-
-Item {
- ScreenSaver {
- screenSaverInhibited: true
- }
-}
-
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml
index 65c019cf9..42af673f5 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml
@@ -31,7 +31,8 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.1
+import QtQuick.Window 2.1
Effect {
id: root
@@ -49,6 +50,7 @@ Effect {
property real posX: -1
property real posY: -1
+ property real pixDens: Screen.pixelDensity
QtObject {
id: d
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml
index ce301d6d9..c6c60bc29 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml
@@ -31,7 +31,8 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.1
+import QtQuick.Window 2.1
Effect {
parameters: ListModel {
@@ -48,6 +49,7 @@ Effect {
// Transform slider values, and bind result to shader uniforms
property real amplitude: parameters.get(0).value * 0.03
property real n: parameters.get(1).value * 7
+ property real pixDens: Screen.pixelDensity
property real time: 0
NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml
index ce1987320..58530eb4f 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml
@@ -43,7 +43,7 @@ ListModel {
ListElement { name: "Emboss"; source: "EffectEmboss.qml" }
ListElement { name: "Glow"; source: "EffectGlow.qml" }
ListElement { name: "Isolate"; source: "EffectIsolate.qml" }
- //ListElement { name: "Magnify"; source: "EffectMagnify.qml" }
+ ListElement { name: "Magnify"; source: "EffectMagnify.qml" }
ListElement { name: "Page curl"; source: "EffectPageCurl.qml" }
ListElement { name: "Pixelate"; source: "EffectPixelate.qml" }
ListElement { name: "Posterize"; source: "EffectPosterize.qml" }
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml
index 039e6c36f..b724ee3bd 100644
--- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml
@@ -160,7 +160,6 @@ Rectangle {
Loader {
id: performanceLoader
function init() {
- console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible)
var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
source = enabled ? "../performancemonitor/PerformanceItem.qml" : ""
}
@@ -249,11 +248,6 @@ Rectangle {
height = windowHeight
width = windowWidth
- console.log("[qmlvideofx] root.init")
- console.log("Height: ", Screen.desktopAvailableHeight)
- console.log("Width: ", Screen.desktopAvailableWidth)
- console.log("Pixels per mm: ", Math.ceil(Screen.pixelDensity))
- console.log("Orientation: ", Screen.orientation)
imageFileBrowser.folder = imagePath
videoFileBrowser.folder = videoPath
content.init()
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc
index e7a361246..e7978e39f 100644
--- a/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc
@@ -3,10 +3,8 @@
<file>images/qt-logo.png</file>
<file>qml/qmlvideofx/Button.qml</file>
<file>qml/qmlvideofx/Content.qml</file>
- <file>qml/qmlvideofx/ContentCamera.qml</file>
<file>qml/qmlvideofx/ContentImage.qml</file>
<file>qml/qmlvideofx/ContentVideo.qml</file>
- <file>qml/qmlvideofx/DisableScreenSaver.qml</file>
<file>qml/qmlvideofx/Divider.qml</file>
<file>qml/qmlvideofx/Effect.qml</file>
<file>qml/qmlvideofx/EffectBillboard.qml</file>
diff --git a/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh b/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh
index 0387d25d6..fb7e2a047 100644
--- a/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh
+++ b/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh
@@ -50,12 +50,15 @@ uniform float targetWidth;
uniform float targetHeight;
uniform float posX;
uniform float posY;
+uniform float pixDens;
void main()
{
vec2 tc = qt_TexCoord0;
vec2 center = vec2(posX, posY);
vec2 xy = gl_FragCoord.xy - center.xy;
+ xy.x -= (pixDens * 14.0);
+ xy.y -= (pixDens * 29.0);
float r = sqrt(xy.x * xy.x + xy.y * xy.y);
if (r < radius) {
float h = diffractionIndex * 0.5 * radius;
diff --git a/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh b/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh
index b70f36d92..428c041c7 100644
--- a/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh
+++ b/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh
@@ -55,12 +55,13 @@ const int ITER = 7;
const float RATE = 0.1;
uniform float amplitude;
uniform float n;
+uniform float pixDens;
void main()
{
vec2 uv = qt_TexCoord0.xy;
vec2 tc = uv;
- vec2 p = vec2(-1.0 + 2.0 * gl_FragCoord.x / targetWidth, -(-1.0 + 2.0 * gl_FragCoord.y / targetHeight));
+ vec2 p = vec2(-1.0 + 2.0 * (gl_FragCoord.x - (pixDens * 14.0)) / targetWidth, -(-1.0 + 2.0 * (gl_FragCoord.y - (pixDens * 29.0)) / targetHeight));
float diffx = 0.0;
float diffy = 0.0;
vec4 col;
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp
index 747ea6bdf..b165adada 100644
--- a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp
@@ -125,7 +125,6 @@ void FrequencyMonitorPrivate::calculateAverageFrequency()
void FrequencyMonitorPrivate::stalled()
{
if (m_instantaneousFrequency) {
- qtVerboseTrace() << "FrequencyMonitor::stalled";
m_instantaneousFrequency = 0;
emit q_ptr->instantaneousFrequencyChanged(m_instantaneousFrequency);
emit q_ptr->frequencyChanged();
@@ -136,7 +135,6 @@ FrequencyMonitor::FrequencyMonitor(QObject *parent)
: QObject(parent)
{
d_ptr = new FrequencyMonitorPrivate(this);
- qtTrace() << "FrequencyMonitor::FrequencyMonitor";
}
FrequencyMonitor::~FrequencyMonitor()
diff --git a/examples/multimediawidgets/camera/camera.cpp b/examples/multimediawidgets/camera/camera.cpp
index 3afe59324..714de7a4d 100644
--- a/examples/multimediawidgets/camera/camera.cpp
+++ b/examples/multimediawidgets/camera/camera.cpp
@@ -46,6 +46,7 @@
#include <QMediaService>
#include <QMediaRecorder>
#include <QCameraViewfinder>
+#include <QCameraInfo>
#include <QMediaMetaData>
#include <QMessageBox>
@@ -53,6 +54,8 @@
#include <QtWidgets>
+Q_DECLARE_METATYPE(QCameraInfo)
+
Camera::Camera(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Camera),
@@ -65,26 +68,23 @@ Camera::Camera(QWidget *parent) :
ui->setupUi(this);
//Camera devices:
- QByteArray cameraDevice;
QActionGroup *videoDevicesGroup = new QActionGroup(this);
videoDevicesGroup->setExclusive(true);
- foreach(const QByteArray &deviceName, QCamera::availableDevices()) {
- QString description = camera->deviceDescription(deviceName);
- QAction *videoDeviceAction = new QAction(description, videoDevicesGroup);
+ foreach (const QCameraInfo &cameraInfo, QCameraInfo::availableCameras()) {
+ QAction *videoDeviceAction = new QAction(cameraInfo.description(), videoDevicesGroup);
videoDeviceAction->setCheckable(true);
- videoDeviceAction->setData(QVariant(deviceName));
- if (cameraDevice.isEmpty()) {
- cameraDevice = deviceName;
+ videoDeviceAction->setData(QVariant::fromValue(cameraInfo));
+ if (cameraInfo == QCameraInfo::defaultCamera())
videoDeviceAction->setChecked(true);
- }
+
ui->menuDevices->addAction(videoDeviceAction);
}
connect(videoDevicesGroup, SIGNAL(triggered(QAction*)), SLOT(updateCameraDevice(QAction*)));
connect(ui->captureWidget, SIGNAL(currentChanged(int)), SLOT(updateCaptureMode()));
- setCamera(cameraDevice);
+ setCamera(QCameraInfo::defaultCamera());
}
Camera::~Camera()
@@ -94,16 +94,13 @@ Camera::~Camera()
delete camera;
}
-void Camera::setCamera(const QByteArray &cameraDevice)
+void Camera::setCamera(const QCameraInfo &cameraInfo)
{
delete imageCapture;
delete mediaRecorder;
delete camera;
- if (cameraDevice.isEmpty())
- camera = new QCamera;
- else
- camera = new QCamera(cameraDevice);
+ camera = new QCamera(cameraInfo);
connect(camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(updateCameraState(QCamera::State)));
connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(displayCameraError()));
@@ -398,7 +395,7 @@ void Camera::displayCameraError()
void Camera::updateCameraDevice(QAction *action)
{
- setCamera(action->data().toByteArray());
+ setCamera(qvariant_cast<QCameraInfo>(action->data()));
}
void Camera::displayViewfinder()
diff --git a/examples/multimediawidgets/camera/camera.h b/examples/multimediawidgets/camera/camera.h
index 52f03cbd3..faa02ccd7 100644
--- a/examples/multimediawidgets/camera/camera.h
+++ b/examples/multimediawidgets/camera/camera.h
@@ -60,7 +60,7 @@ public:
~Camera();
private slots:
- void setCamera(const QByteArray &cameraDevice);
+ void setCamera(const QCameraInfo &cameraInfo);
void startCamera();
void stopCamera();
diff --git a/examples/multimediawidgets/player/doc/src/player.qdoc b/examples/multimediawidgets/player/doc/src/player.qdoc
index 29121dce4..ac5d700da 100644
--- a/examples/multimediawidgets/player/doc/src/player.qdoc
+++ b/examples/multimediawidgets/player/doc/src/player.qdoc
@@ -29,10 +29,10 @@
\example player
\title Media Player Example
\ingroup multimedia_examples
- \brief Demonstrates the audio and video playback functionality
+ \brief Playing audio and video.
- This example creates a simple multimedia player. We can play audio and
- or video files using various codecs.
+ \e{Media Player} demonstrates a simple multimedia player that can play
+ audio and or video files using various codecs.
\include examples-run.qdocinc
@@ -40,10 +40,9 @@
control the video output. To give the application playlist capability
we also use a QPlayList object.
- To activate the various functions such as play and stop on the dialog
- we connect clicked() signals to slots that emit the play() and stop()
- signals and in turn which we connect to the play() and stop() slots in
- QMediaPlayer.
+ To activate the various functions such as play and stop on the dialog,
+ the button clicked events emit the play() and stop() signals, which
+ are connected to the play() and stop() slots of QMediaPlayer.
\code
connect(controls, SIGNAL(play()), player, SLOT(play()));
diff --git a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc
index 1e392ce8c..7cc2cdc87 100644
--- a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc
+++ b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc
@@ -29,10 +29,10 @@
\example videographicsitem
\title Video Graphics Item Example
\ingroup multimedia_examples
-\brief This example demonstrates how to stream video on a graphics scene.
+\brief Streaming video on a graphics scene.
- The Video Graphics Item example shows how to implement a QGraphicsItem that displays video on a
- graphics scene using \l{Qt Multimedia}'s QAbstractVideoSurface.
+ \e{Video Graphics Item} demonstrates how to implement a QGraphicsItem that
+ displays video on a graphics scene using QAbstractVideoSurface.
\image video-videographicsitem.png
diff --git a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc
index 6b93a3c19..2a991d0fa 100644
--- a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc
+++ b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc
@@ -29,10 +29,10 @@
\example videowidget
\title Video Widget Example
\ingroup multimedia_examples
- \brief This example is a simple video player
+ \brief Implementing a video player widget.
- The Video Widget example denonstrates how to implement a video widget using
- \l{Qt Multimedia}'s QAbstractVideoSurface.
+ \e{Video Widget} demonstrates how to implement a video widget using
+ QAbstractVideoSurface.
\image video-videowidget.png
diff --git a/qtmultimedia.pro b/qtmultimedia.pro
index 7b6baa5fd..84f254861 100644
--- a/qtmultimedia.pro
+++ b/qtmultimedia.pro
@@ -12,10 +12,6 @@ win32 {
qtCompileTest(evr)
} else:mac {
qtCompileTest(avfoundation)
-} else:android:!android-no-sdk {
- SDK_ROOT = $$(ANDROID_SDK_ROOT)
- isEmpty(SDK_ROOT): SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
- !exists($$SDK_ROOT/platforms/android-11/android.jar): error("QtMultimedia for Android requires API level 11")
} else:qnx {
qtCompileTest(mmrenderer)
} else {
@@ -29,6 +25,7 @@ win32 {
qtCompileTest(gstreamer_photography)
qtCompileTest(gstreamer_encodingprofiles)
qtCompileTest(gstreamer_appsrc)
+ qtCompileTest(linux_v4l)
} else {
gstver=1.0
cache(GST_VERSION, set, gstver);
@@ -38,6 +35,7 @@ win32 {
qtCompileTest(gstreamer_photography)
qtCompileTest(gstreamer_encodingprofiles)
qtCompileTest(gstreamer_appsrc)
+ qtCompileTest(linux_v4l)
}
}
}
diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro
index 7917b3036..c2aacdfb6 100644
--- a/src/gsttools/gsttools.pro
+++ b/src/gsttools/gsttools.pro
@@ -129,6 +129,8 @@ config_gstreamer_appsrc {
LIBS_PRIVATE += -lgstapp-$$GST_VERSION
}
+config_linux_v4l: DEFINES += USE_V4L
+
HEADERS += $$PRIVATE_HEADERS
DESTDIR = $$QT.multimedia.libs
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
index 4e1cf82ca..56e2b6d5d 100644
--- a/src/gsttools/qgstutils.cpp
+++ b/src/gsttools/qgstutils.cpp
@@ -49,8 +49,10 @@
template<typename T, int N> static int lengthOf(const T (&)[N]) { return N; }
-#include <private/qcore_unix_p.h>
-#include <linux/videodev2.h>
+#ifdef USE_V4L
+# include <private/qcore_unix_p.h>
+# include <linux/videodev2.h>
+#endif
#include "qgstreamervideoinputdevicecontrol_p.h"
@@ -571,6 +573,7 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
}
}
+#ifdef USE_V4L
QDir devDir(QStringLiteral("/dev"));
devDir.setFilter(QDir::System);
@@ -618,6 +621,7 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
}
qt_safe_close(fd);
}
+#endif // USE_V4L
return devices;
}
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index 46fd37d18..8c4fca78d 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -61,7 +61,6 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
: m_surface(surface)
, m_pool(0)
, m_renderReturn(GST_FLOW_ERROR)
- , m_lastPrerolledBuffer(0)
, m_bytesPerLine(0)
, m_startCanceled(false)
{
@@ -81,7 +80,6 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
{
- setLastPrerolledBuffer(0);
}
QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
@@ -218,23 +216,6 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
return m_renderReturn;
}
-void QVideoSurfaceGstDelegate::setLastPrerolledBuffer(GstBuffer *prerolledBuffer)
-{
- // discard previously stored buffer
- if (m_lastPrerolledBuffer) {
- gst_buffer_unref(m_lastPrerolledBuffer);
- m_lastPrerolledBuffer = 0;
- }
-
- if (!prerolledBuffer)
- return;
-
- // store a reference to the buffer
- Q_ASSERT(!m_lastPrerolledBuffer);
- m_lastPrerolledBuffer = prerolledBuffer;
- gst_buffer_ref(m_lastPrerolledBuffer);
-}
-
void QVideoSurfaceGstDelegate::queuedStart()
{
if (!m_startCanceled) {
@@ -322,8 +303,6 @@ QVideoSurfaceGstSink *QVideoSurfaceGstSink::createSink(QAbstractVideoSurface *su
sink->delegate = new QVideoSurfaceGstDelegate(surface);
- g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);
-
return sink;
}
@@ -359,16 +338,15 @@ void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
+ GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
+ video_sink_class->show_frame = QVideoSurfaceGstSink::show_frame;
+
GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps;
base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps;
base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
base_sink_class->start = QVideoSurfaceGstSink::start;
base_sink_class->stop = QVideoSurfaceGstSink::stop;
- // base_sink_class->unlock = QVideoSurfaceGstSink::unlock; // Not implemented.
- base_sink_class->event = QVideoSurfaceGstSink::event;
- base_sink_class->preroll = QVideoSurfaceGstSink::preroll;
- base_sink_class->render = QVideoSurfaceGstSink::render;
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
element_class->change_state = QVideoSurfaceGstSink::change_state;
@@ -512,27 +490,6 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
return FALSE;
}
-void QVideoSurfaceGstSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(d);
-
- gboolean value = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &value, NULL);
-
- GstBuffer *buffer = sink->delegate->lastPrerolledBuffer();
- // Render the stored prerolled buffer if requested.
- // e.g. player is in stopped mode, then seek operation is requested,
- // surface now stores a prerolled frame, but doesn't display it until
- // "show-preroll-frame" property is set to "true"
- // when switching to pause or playing state.
- if (value && buffer) {
- sink->delegate->render(buffer);
- sink->delegate->setLastPrerolledBuffer(0);
- }
-}
-
GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
{
@@ -644,43 +601,9 @@ gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base)
return TRUE;
}
-gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base)
-{
- Q_UNUSED(base);
-
- return TRUE;
-}
-
-gboolean QVideoSurfaceGstSink::event(GstBaseSink *base, GstEvent *event)
-{
- // discard prerolled frame
- if (event->type == GST_EVENT_FLUSH_START) {
- VO_SINK(base);
- sink->delegate->setLastPrerolledBuffer(0);
- }
- return TRUE;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
-
- gboolean value = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(base), "show-preroll-frame", &value, NULL);
- if (value) {
- sink->delegate->setLastPrerolledBuffer(0); // discard prerolled buffer
- return sink->delegate->render(buffer); // display frame
- }
-
- // otherwise keep a reference to the buffer to display it later
- sink->delegate->setLastPrerolledBuffer(buffer);
- return GST_FLOW_OK;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::render(GstBaseSink *base, GstBuffer *buffer)
+GstFlowReturn QVideoSurfaceGstSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
{
VO_SINK(base);
- sink->delegate->setLastPrerolledBuffer(0); // discard prerolled buffer
return sink->delegate->render(buffer);
}
diff --git a/src/imports/multimedia/qdeclarativeradiodata.cpp b/src/imports/multimedia/qdeclarativeradiodata.cpp
index e8673905f..6cc829ae9 100644
--- a/src/imports/multimedia/qdeclarativeradiodata.cpp
+++ b/src/imports/multimedia/qdeclarativeradiodata.cpp
@@ -281,6 +281,9 @@ void QDeclarativeRadioData::_q_availabilityChanged(QMultimedia::AvailabilityStat
void QDeclarativeRadioData::connectSignals()
{
+ if (!m_radioData)
+ return;
+
connect(m_radioData, SIGNAL(programTypeChanged(QRadioData::ProgramType)), this,
SLOT(_q_programTypeChanged(QRadioData::ProgramType)));
diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
index c9f12aeb6..38052de32 100644
--- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
@@ -45,9 +45,6 @@
#include "qsoundeffect_qaudio_p.h"
#include <QtCore/qcoreapplication.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
#include <QtCore/qiodevice.h>
//#include <QDebug>
diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
index 71b781682..0ea18c0ff 100644
--- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
+++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
@@ -96,9 +96,6 @@ public:
GstFlowReturn render(GstBuffer *buffer);
- GstBuffer *lastPrerolledBuffer() const { return m_lastPrerolledBuffer; }
- void setLastPrerolledBuffer(GstBuffer *lastPrerolledBuffer); // set prerolledBuffer to 0 to discard prerolled buffer
-
private slots:
void queuedStart();
void queuedStop();
@@ -120,8 +117,6 @@ private:
QVideoSurfaceFormat m_format;
QVideoFrame m_frame;
GstFlowReturn m_renderReturn;
- // this pointer is not 0 when there is a prerolled buffer waiting to be displayed
- GstBuffer *m_lastPrerolledBuffer;
int m_bytesPerLine;
bool m_started;
bool m_startCanceled;
@@ -134,8 +129,6 @@ public:
static QVideoSurfaceGstSink *createSink(QAbstractVideoSurface *surface);
- static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
-
private:
static GType get_type();
static void class_init(gpointer g_class, gpointer class_data);
@@ -155,11 +148,7 @@ private:
static gboolean start(GstBaseSink *sink);
static gboolean stop(GstBaseSink *sink);
- static gboolean unlock(GstBaseSink *sink);
-
- static gboolean event(GstBaseSink *sink, GstEvent *event);
- static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer);
- static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
+ static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
private:
QVideoSurfaceGstDelegate *delegate;
diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/playlistfileparser.cpp
index ac556c25c..a3aba1cab 100644
--- a/src/multimedia/playback/playlistfileparser.cpp
+++ b/src/multimedia/playback/playlistfileparser.cpp
@@ -51,6 +51,30 @@ public:
virtual void parseLine(int lineIndex, const QString& line, const QUrl& root) = 0;
+protected:
+ QUrl expandToFullPath(const QUrl &root, const QString &line)
+ {
+ // On Linux, backslashes are not converted to forward slashes :/
+ if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
+ // Network share paths are not resolved
+ return QUrl::fromLocalFile(line);
+ }
+
+ QUrl url(line);
+ if (url.scheme().isEmpty()) {
+ // Resolve it relative to root
+ if (root.isLocalFile())
+ return root.resolved(QUrl::fromLocalFile(line));
+ else
+ return root.resolved(url);
+ } else if (url.scheme().length() == 1) {
+ // Assume it's a drive letter for a Windows path
+ url = QUrl::fromLocalFile(line);
+ }
+
+ return url;
+ }
+
Q_SIGNALS:
void newItem(const QVariant& content);
void finished();
@@ -138,29 +162,6 @@ public:
return -1;
}
- QUrl expandToFullPath(const QUrl& root, const QString& line)
- {
- // On Linux, backslashes are not converted to forward slashes :/
- if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
- // Network share paths are not resolved
- return QUrl::fromLocalFile(line);
- }
-
- QUrl url(line);
- if (url.scheme().isEmpty()) {
- // Resolve it relative to root
- if (root.isLocalFile())
- return root.resolved(QUrl::fromLocalFile(line));
- else
- return root.resolved(url);
- } else if (url.scheme().length() == 1) {
- // Assume it's a drive letter for a Windows path
- url = QUrl::fromLocalFile(line);
- }
-
- return url;
- }
-
private:
bool m_extendedFormat;
QVariantMap m_extraInfo;
@@ -172,27 +173,9 @@ class PLSParser : public ParserBase
public:
PLSParser(QObject *parent)
: ParserBase(parent)
- , m_state(Header)
- , m_count(0)
- , m_readFlags(0)
{
}
- enum ReadFlags
- {
- FileRead = 0x1,
- TitleRead = 0x2,
- LengthRead = 0x4,
- All = FileRead | TitleRead | LengthRead
- };
-
- enum State
- {
- Header,
- Track,
- Footer
- };
-
/*
*
The format is essentially that of an INI file structured as follows:
@@ -231,89 +214,25 @@ NumberOfEntries=2
Version=2
*/
- inline bool containsFlag(const ReadFlags& flag)
+ void parseLine(int, const QString &line, const QUrl &root)
{
- return (m_readFlags & int(flag)) == flag;
- }
+ // We ignore everything but 'File' entries, since that's the only thing we care about.
+ if (!line.startsWith(QLatin1String("File")))
+ return;
- inline void setFlag(const ReadFlags& flag)
- {
- m_readFlags |= int(flag);
- }
+ QString value = getValue(line);
+ if (value.isEmpty())
+ return;
- void parseLine(int lineIndex, const QString& line, const QUrl&)
- {
- switch (m_state) {
- case Header:
- if (line == QLatin1String("[playlist]")) {
- m_state = Track;
- setCount(1);
- }
- break;
- case Track:
- if (!containsFlag(FileRead) && line.startsWith(m_fileName)) {
- m_item[QLatin1String("url")] = getValue(lineIndex, line);
- setFlag(FileRead);
- } else if (!containsFlag(TitleRead) && line.startsWith(m_titleName)) {
- m_item[QMediaMetaData::Title] = getValue(lineIndex, line);
- setFlag(TitleRead);
- } else if (!containsFlag(LengthRead) && line.startsWith(m_lengthName)) {
- //convert from seconds to miliseconds
- int length = getValue(lineIndex, line).toInt();
- if (length > 0)
- m_item[QMediaMetaData::Duration] = length * 1000;
- setFlag(LengthRead);
- } else if (line.startsWith(QLatin1String("NumberOfEntries"))) {
- m_state = Footer;
- int entries = getValue(lineIndex, line).toInt();
- int count = m_readFlags == 0 ? (m_count - 1) : m_count;
- if (entries != count) {
- emit error(QPlaylistFileParser::FormatError, tr("Error parsing playlist: %1, expected count = %2").
- arg(line, QString::number(count)));
- }
- break;
- }
- if (m_readFlags == int(All)) {
- emit newItem(m_item);
- setCount(m_count + 1);
- }
- break;
- case Footer:
- if (line.startsWith(QLatin1String("Version"))) {
- int version = getValue(lineIndex, line).toInt();
- if (version != 2)
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1], expected version = 2")).arg(line));
- }
- break;
- }
+ emit newItem(expandToFullPath(root, value));
}
- QString getValue(int lineIndex, const QString& line) {
+ QString getValue(const QString& line) {
int start = line.indexOf('=');
- if (start < 0) {
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1]:%2")).arg(QString::number(lineIndex), line));
+ if (start < 0)
return QString();
- }
return line.midRef(start + 1).trimmed().toString();
}
-
- void setCount(int count) {
- m_count = count;
- m_fileName = QStringLiteral("File%1").arg(count);
- m_titleName = QStringLiteral("Title%1").arg(count);
- m_lengthName = QStringLiteral("Length%1").arg(count);
- m_item.clear();
- m_readFlags = 0;
- }
-
-private:
- State m_state;
- int m_count;
- QString m_titleName;
- QString m_fileName;
- QString m_lengthName;
- QVariantMap m_item;
- int m_readFlags;
};
}
diff --git a/src/multimedia/qmediaopenglhelper_p.h b/src/multimedia/qmediaopenglhelper_p.h
index d42dfba42..0dbd79d47 100644
--- a/src/multimedia/qmediaopenglhelper_p.h
+++ b/src/multimedia/qmediaopenglhelper_p.h
@@ -66,7 +66,7 @@ inline bool QMediaOpenGLHelper::isANGLE()
#else
bool isANGLE = false;
-# if defined(Q_OS_WIN) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC))
+# if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC))
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
// Although unlikely, technically LibGLES could mean a non-ANGLE EGL/GLES2 implementation too.
// Verify that it is indeed ANGLE.
@@ -98,7 +98,7 @@ inline bool QMediaOpenGLHelper::isANGLE()
# endif // QT_OPENGL_ES_2_ANGLE_STATIC
}
-# endif // Q_OS_WIN && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC)
+# endif // Q_OS_WIN && !Q_OS_WINCE && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC)
return isANGLE;
#endif // Q_OS_WINRT
diff --git a/src/plugins/alsa/qalsaaudioinput.cpp b/src/plugins/alsa/qalsaaudioinput.cpp
index bb0182a3e..adaa41c6e 100644
--- a/src/plugins/alsa/qalsaaudioinput.cpp
+++ b/src/plugins/alsa/qalsaaudioinput.cpp
@@ -760,7 +760,7 @@ qint64 QAlsaAudioInput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return clockStamp.elapsed()*1000;
+ return clockStamp.elapsed() * qint64(1000);
}
void QAlsaAudioInput::reset()
diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp
index 07dd17362..fde2bc9bf 100644
--- a/src/plugins/alsa/qalsaaudiooutput.cpp
+++ b/src/plugins/alsa/qalsaaudiooutput.cpp
@@ -774,7 +774,7 @@ qint64 QAlsaAudioOutput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return clockStamp.elapsed()*1000;
+ return clockStamp.elapsed() * qint64(1000);
}
void QAlsaAudioOutput::reset()
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
index ade2517d2..5e6630de8 100644
--- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
+++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
@@ -83,23 +83,6 @@ public class QtAndroidMediaPlayer
private volatile int mState = State.Uninitialized;
- private class ProgressWatcher
- implements Runnable
- {
- @Override
- public void run()
- {
- try {
- while ((mState & (State.Started)) != 0) {
- onProgressUpdateNative(getCurrentPosition(), mID);
- Thread.sleep(1000);
- }
- } catch (final InterruptedException e) {
- // Ignore
- }
- }
- }
-
/**
* MediaPlayer OnErrorListener
*/
@@ -257,8 +240,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.start();
setState(State.Started);
- Thread progressThread = new Thread(new ProgressWatcher());
- progressThread.start();
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
@@ -309,7 +290,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.seekTo(msec);
- onProgressUpdateNative(msec, mID);
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
index 47dd94ccd..eae09c64f 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
@@ -37,6 +37,36 @@
QT_BEGIN_NAMESPACE
+class StateChangeNotifier
+{
+public:
+ StateChangeNotifier(QAndroidMediaPlayerControl *mp)
+ : mControl(mp)
+ , mPreviousState(mp->state())
+ , mPreviousMediaStatus(mp->mediaStatus())
+ {
+ ++mControl->mActiveStateChangeNotifiers;
+ }
+
+ ~StateChangeNotifier()
+ {
+ if (--mControl->mActiveStateChangeNotifiers)
+ return;
+
+ if (mPreviousState != mControl->state())
+ Q_EMIT mControl->stateChanged(mControl->state());
+
+ if (mPreviousMediaStatus != mControl->mediaStatus())
+ Q_EMIT mControl->mediaStatusChanged(mControl->mediaStatus());
+ }
+
+private:
+ QAndroidMediaPlayerControl *mControl;
+ QMediaPlayer::State mPreviousState;
+ QMediaPlayer::MediaStatus mPreviousMediaStatus;
+};
+
+
QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
: QMediaPlayerControl(parent),
mMediaPlayer(new AndroidMediaPlayer),
@@ -55,7 +85,9 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
mPendingPosition(-1),
mPendingSetMedia(false),
mPendingVolume(-1),
- mPendingMute(-1)
+ mPendingMute(-1),
+ mReloadingMedia(false),
+ mActiveStateChangeNotifiers(0)
{
connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)),
this,SLOT(onBufferingChanged(qint32)));
@@ -107,17 +139,14 @@ qint64 QAndroidMediaPlayerControl::position() const
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
return duration();
- if ((mState & (AndroidMediaPlayer::Idle
- | AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
+ if ((mState & (AndroidMediaPlayer::Prepared
| AndroidMediaPlayer::Started
| AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- return (mPendingPosition == -1) ? 0 : mPendingPosition;
+ | AndroidMediaPlayer::PlaybackCompleted))) {
+ return mMediaPlayer->getCurrentPosition();
}
- return (mCurrentState == QMediaPlayer::StoppedState) ? 0 : mMediaPlayer->getCurrentPosition();
+ return (mPendingPosition == -1) ? 0 : mPendingPosition;
}
void QAndroidMediaPlayerControl::setPosition(qint64 position)
@@ -127,24 +156,25 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position)
const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- if (mPendingPosition != seekPosition) {
- mPendingPosition = seekPosition;
- Q_EMIT positionChanged(seekPosition);
- }
+ if (seekPosition == this->position())
return;
- }
+
+ StateChangeNotifier notifier(this);
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
setMediaStatus(QMediaPlayer::LoadedMedia);
- mMediaPlayer->seekTo(seekPosition);
+ if ((mState & (AndroidMediaPlayer::Prepared
+ | AndroidMediaPlayer::Started
+ | AndroidMediaPlayer::Paused
+ | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
+ mPendingPosition = seekPosition;
+ } else {
+ mMediaPlayer->seekTo(seekPosition);
- if (mPendingPosition != -1) {
- mPendingPosition = -1;
+ if (mPendingPosition != -1) {
+ mPendingPosition = -1;
+ }
}
Q_EMIT positionChanged(seekPosition);
@@ -275,9 +305,11 @@ const QIODevice *QAndroidMediaPlayerControl::mediaStream() const
void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
QIODevice *stream)
{
- const bool reloading = (mMediaContent == mediaContent);
+ StateChangeNotifier notifier(this);
+
+ mReloadingMedia = (mMediaContent == mediaContent);
- if (!reloading) {
+ if (!mReloadingMedia) {
mMediaContent = mediaContent;
mMediaStream = stream;
}
@@ -286,41 +318,45 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0)
mMediaPlayer->release();
+ QString mediaPath;
+
if (mediaContent.isNull()) {
setMediaStatus(QMediaPlayer::NoMedia);
- return;
- }
-
- if (mVideoOutput && !mVideoOutput->isReady()) {
- // if a video output is set but the video texture is not ready, delay loading the media
- // since it can cause problems on some hardware
- mPendingSetMedia = true;
- return;
- }
-
- const QUrl url = mediaContent.canonicalUrl();
- QString mediaPath;
- if (url.scheme() == QLatin1String("qrc")) {
- const QString path = url.toString().mid(3);
- mTempFile.reset(QTemporaryFile::createNativeFile(path));
- if (!mTempFile.isNull())
- mediaPath = QStringLiteral("file://") + mTempFile->fileName();
} else {
- mediaPath = url.toString();
- }
+ if (mVideoOutput && !mVideoOutput->isReady()) {
+ // if a video output is set but the video texture is not ready, delay loading the media
+ // since it can cause problems on some hardware
+ mPendingSetMedia = true;
+ return;
+ }
- if (mVideoSize.isValid() && mVideoOutput)
- mVideoOutput->setVideoSize(mVideoSize);
+ const QUrl url = mediaContent.canonicalUrl();
+ if (url.scheme() == QLatin1String("qrc")) {
+ const QString path = url.toString().mid(3);
+ mTempFile.reset(QTemporaryFile::createNativeFile(path));
+ if (!mTempFile.isNull())
+ mediaPath = QStringLiteral("file://") + mTempFile->fileName();
+ } else {
+ mediaPath = url.toString();
+ }
- if ((mMediaPlayer->display() == 0) && mVideoOutput)
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
- mMediaPlayer->setDataSource(mediaPath);
- mMediaPlayer->prepareAsync();
+ if (mVideoSize.isValid() && mVideoOutput)
+ mVideoOutput->setVideoSize(mVideoSize);
- if (!reloading)
+ if ((mMediaPlayer->display() == 0) && mVideoOutput)
+ mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
+ mMediaPlayer->setDataSource(mediaPath);
+ mMediaPlayer->prepareAsync();
+ }
+
+ if (!mReloadingMedia) {
Q_EMIT mediaChanged(mMediaContent);
+ Q_EMIT actualMediaLocationChanged(mediaPath);
+ }
resetBufferingProgress();
+
+ mReloadingMedia = false;
}
void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
@@ -344,6 +380,8 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
void QAndroidMediaPlayerControl::play()
{
+ StateChangeNotifier notifier(this);
+
// We need to prepare the mediaplayer again.
if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) {
setMedia(mMediaContent, mMediaStream);
@@ -364,6 +402,8 @@ void QAndroidMediaPlayerControl::play()
void QAndroidMediaPlayerControl::pause()
{
+ StateChangeNotifier notifier(this);
+
setState(QMediaPlayer::PausedState);
if ((mState & (AndroidMediaPlayer::Started
@@ -378,6 +418,8 @@ void QAndroidMediaPlayerControl::pause()
void QAndroidMediaPlayerControl::stop()
{
+ StateChangeNotifier notifier(this);
+
setState(QMediaPlayer::StoppedState);
if ((mState & (AndroidMediaPlayer::Prepared
@@ -395,6 +437,8 @@ void QAndroidMediaPlayerControl::stop()
void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
{
+ StateChangeNotifier notifier(this);
+
Q_UNUSED(extra);
switch (what) {
case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN:
@@ -426,6 +470,8 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
{
+ StateChangeNotifier notifier(this);
+
QString errorString;
QMediaPlayer::Error error = QMediaPlayer::ResourceError;
@@ -478,6 +524,8 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent)
{
+ StateChangeNotifier notifier(this);
+
mBuffering = percent != 100;
mBufferPercent = percent;
@@ -509,6 +557,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
return;
}
+ StateChangeNotifier notifier(this);
+
mState = state;
switch (mState) {
case AndroidMediaPlayer::Idle:
@@ -516,7 +566,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
case AndroidMediaPlayer::Initialized:
break;
case AndroidMediaPlayer::Preparing:
- setMediaStatus(QMediaPlayer::LoadingMedia);
+ if (!mReloadingMedia)
+ setMediaStatus(QMediaPlayer::LoadingMedia);
break;
case AndroidMediaPlayer::Prepared:
setMediaStatus(QMediaPlayer::LoadedMedia);
@@ -537,6 +588,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
} else {
setMediaStatus(QMediaPlayer::BufferedMedia);
}
+ Q_EMIT positionChanged(position());
break;
case AndroidMediaPlayer::Paused:
setState(QMediaPlayer::PausedState);
@@ -545,27 +597,32 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::UnknownMediaStatus);
mMediaPlayer->release();
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::Stopped:
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::LoadedMedia);
- setPosition(0);
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::PlaybackCompleted:
setState(QMediaPlayer::StoppedState);
- setPosition(0);
setMediaStatus(QMediaPlayer::EndOfMedia);
break;
case AndroidMediaPlayer::Uninitialized:
- // reset some properties
- resetBufferingProgress();
- mPendingPosition = -1;
- mPendingSetMedia = false;
- mPendingState = -1;
-
- setAudioAvailable(false);
- setVideoAvailable(false);
- setSeekable(true);
+ // reset some properties (unless we reload the same media)
+ if (!mReloadingMedia) {
+ resetBufferingProgress();
+ mPendingPosition = -1;
+ mPendingSetMedia = false;
+ mPendingState = -1;
+
+ Q_EMIT durationChanged(0);
+ Q_EMIT positionChanged(0);
+
+ setAudioAvailable(false);
+ setVideoAvailable(false);
+ setSeekable(true);
+ }
break;
default:
break;
@@ -597,7 +654,6 @@ void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state)
return;
mCurrentState = state;
- Q_EMIT stateChanged(mCurrentState);
}
void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
@@ -605,14 +661,13 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status
if (mCurrentMediaStatus == status)
return;
+ mCurrentMediaStatus = status;
+
if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia)
Q_EMIT durationChanged(0);
if (status == QMediaPlayer::EndOfMedia)
- Q_EMIT durationChanged(duration());
-
- mCurrentMediaStatus = status;
- Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
+ Q_EMIT positionChanged(position());
updateBufferStatus();
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
index 86d99e822..64b88f49e 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
@@ -72,6 +72,7 @@ public:
Q_SIGNALS:
void metaDataUpdated();
+ void actualMediaLocationChanged(const QString &url);
public Q_SLOTS:
void setPosition(qint64 position) Q_DECL_OVERRIDE;
@@ -110,7 +111,9 @@ private:
bool mPendingSetMedia;
int mPendingVolume;
int mPendingMute;
+ bool mReloadingMedia;
QScopedPointer<QTemporaryFile> mTempFile;
+ int mActiveStateChangeNotifiers;
void setState(QMediaPlayer::State state);
void setMediaStatus(QMediaPlayer::MediaStatus status);
@@ -121,6 +124,8 @@ private:
void resetBufferingProgress();
void flushPendingStates();
void updateBufferStatus();
+
+ friend class StateChangeNotifier;
};
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
index 00e8b6184..05cee3b9d 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
@@ -45,8 +45,8 @@ QAndroidMediaService::QAndroidMediaService(QObject *parent)
{
mMediaControl = new QAndroidMediaPlayerControl;
mMetadataControl = new QAndroidMetaDataReaderControl;
- connect(mMediaControl, SIGNAL(mediaChanged(QMediaContent)),
- mMetadataControl, SLOT(onMediaChanged(QMediaContent)));
+ connect(mMediaControl, SIGNAL(actualMediaLocationChanged(QString)),
+ mMetadataControl, SLOT(onMediaChanged(QString)));
connect(mMediaControl, SIGNAL(metaDataUpdated()),
mMetadataControl, SLOT(onUpdateMetaData()));
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
index a3598228c..a9c87488a 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
@@ -93,18 +93,18 @@ QStringList QAndroidMetaDataReaderControl::availableMetaData() const
return m_metadata.keys();
}
-void QAndroidMetaDataReaderControl::onMediaChanged(const QMediaContent &media)
+void QAndroidMetaDataReaderControl::onMediaChanged(const QString &url)
{
if (!m_retriever)
return;
- m_mediaContent = media;
+ m_mediaLocation = url;
updateData();
}
void QAndroidMetaDataReaderControl::onUpdateMetaData()
{
- if (!m_retriever || m_mediaContent.isNull())
+ if (!m_retriever || m_mediaLocation.isEmpty())
return;
updateData();
@@ -114,8 +114,8 @@ void QAndroidMetaDataReaderControl::updateData()
{
m_metadata.clear();
- if (!m_mediaContent.isNull()) {
- if (m_retriever->setDataSource(m_mediaContent.canonicalUrl())) {
+ if (!m_mediaLocation.isEmpty()) {
+ if (m_retriever->setDataSource(m_mediaLocation)) {
QString mimeType = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::MimeType);
if (!mimeType.isNull())
m_metadata.insert(QMediaMetaData::MediaType, mimeType);
diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
index 72df6eecc..f8720b77a 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
+++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
@@ -54,13 +54,13 @@ public:
QStringList availableMetaData() const Q_DECL_OVERRIDE;
public Q_SLOTS:
- void onMediaChanged(const QMediaContent &media);
+ void onMediaChanged(const QString &url);
void onUpdateMetaData();
private:
void updateData();
- QMediaContent m_mediaContent;
+ QString m_mediaLocation;
bool m_available;
QVariantMap m_metadata;
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index dbe9393ca..b9ea1a6a3 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
-static jclass g_qtCameraListenerClass = 0;
+static const char QtCameraListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtCameraListener";
static QMutex g_cameraMapMutex;
typedef QMap<int, AndroidCamera *> CameraMap;
Q_GLOBAL_STATIC(CameraMap, g_cameraMap)
@@ -720,7 +720,7 @@ bool AndroidCameraPrivate::init(int cameraId)
if (exceptionCheckAndClear(env) || !m_camera.isValid())
return false;
- m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId);
+ m_cameraListener = QJNIObjectPrivate(QtCameraListenerClassName, "(I)V", m_cameraId);
m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo");
m_camera.callStaticMethod<void>("android/hardware/Camera",
"getCameraInfo",
@@ -1392,24 +1392,22 @@ QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArra
return stringList;
}
-static JNINativeMethod methods[] = {
- {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
- {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
- {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured},
- {"notifyFrameFetched", "(I[B)V", (void *)notifyFrameFetched}
-};
-
bool AndroidCamera::initJNI(JNIEnv *env)
{
- jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener");
+ jclass clazz = QJNIEnvironmentPrivate::findClass(QtCameraListenerClassName,
+ env);
- if (!exceptionCheckAndClear(env) && clazz) {
- g_qtCameraListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- if (env->RegisterNatives(g_qtCameraListenerClass,
- methods,
- sizeof(methods) / sizeof(methods[0])) < 0) {
- return false;
- }
+ static const JNINativeMethod methods[] = {
+ {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
+ {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
+ {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured},
+ {"notifyFrameFetched", "(I[B)V", (void *)notifyFrameFetched}
+ };
+
+ if (clazz && env->RegisterNatives(clazz,
+ methods,
+ sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
+ return false;
}
return true;
diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
index a01aacf5e..df5345053 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
@@ -35,9 +35,24 @@
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
+#include <QtCore/QUrl>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
+static bool exceptionCheckAndClear(JNIEnv *env)
+{
+ if (Q_UNLIKELY(env->ExceptionCheck())) {
+#ifdef QT_DEBUG
+ env->ExceptionDescribe();
+#endif // QT_DEBUG
+ env->ExceptionClear();
+ return true;
+ }
+
+ return false;
+}
+
AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever()
{
m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever");
@@ -68,55 +83,105 @@ void AndroidMediaMetadataRetriever::release()
m_metadataRetriever.callMethod<void>("release");
}
-bool AndroidMediaMetadataRetriever::setDataSource(const QUrl &url)
+bool AndroidMediaMetadataRetriever::setDataSource(const QString &urlString)
{
if (!m_metadataRetriever.isValid())
return false;
QJNIEnvironmentPrivate env;
+ QUrl url(urlString);
- bool loaded = false;
+ if (url.isLocalFile()) { // also includes qrc files (copied to a temp file)
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path());
+ QJNIObjectPrivate fileInputStream("java/io/FileInputStream",
+ "(Ljava/lang/String;)V",
+ string.object());
- QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ QJNIObjectPrivate fd = fileInputStream.callObjectMethod("getFD",
+ "()Ljava/io/FileDescriptor;");
+ if (exceptionCheckAndClear(env)) {
+ fileInputStream.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+ return false;
+ }
- QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri",
- "parse",
- "(Ljava/lang/String;)Landroid/net/Uri;",
- string.object());
- if (env->ExceptionCheck()) {
- env->ExceptionClear();
- } else {
m_metadataRetriever.callMethod<void>("setDataSource",
- "(Landroid/content/Context;Landroid/net/Uri;)V",
- QtAndroidPrivate::activity(),
- uri.object());
- if (env->ExceptionCheck())
- env->ExceptionClear();
- else
- loaded = true;
- }
+ "(Ljava/io/FileDescriptor;)V",
+ fd.object());
+
+ bool ok = !exceptionCheckAndClear(env);
+
+ fileInputStream.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+
+ if (!ok)
+ return false;
+ } else if (url.scheme() == QLatin1String("assets")) {
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path().mid(1)); // remove first '/'
+ QJNIObjectPrivate activity(QtAndroidPrivate::activity());
+ QJNIObjectPrivate assetManager = activity.callObjectMethod("getAssets",
+ "()Landroid/content/res/AssetManager;");
+ QJNIObjectPrivate assetFd = assetManager.callObjectMethod("openFd",
+ "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;",
+ string.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ QJNIObjectPrivate fd = assetFd.callObjectMethod("getFileDescriptor",
+ "()Ljava/io/FileDescriptor;");
+ if (exceptionCheckAndClear(env)) {
+ assetFd.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+ return false;
+ }
- return loaded;
-}
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Ljava/io/FileDescriptor;JJ)V",
+ fd.object(),
+ assetFd.callMethod<jlong>("getStartOffset"),
+ assetFd.callMethod<jlong>("getLength"));
-bool AndroidMediaMetadataRetriever::setDataSource(const QString &path)
-{
- if (!m_metadataRetriever.isValid())
- return false;
+ bool ok = !exceptionCheckAndClear(env);
- QJNIEnvironmentPrivate env;
+ assetFd.callMethod<void>("close");
+ exceptionCheckAndClear(env);
- bool loaded = false;
+ if (!ok)
+ return false;
+ } else if (QtAndroidPrivate::androidSdkVersion() >= 14) {
+ // On API levels >= 14, only setDataSource(String, Map<String, String>) accepts remote media
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(urlString);
+ QJNIObjectPrivate hash("java/util/HashMap");
- m_metadataRetriever.callMethod<void>("setDataSource",
- "(Ljava/lang/String;)V",
- QJNIObjectPrivate::fromString(path).object());
- if (env->ExceptionCheck())
- env->ExceptionClear();
- else
- loaded = true;
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Ljava/lang/String;Ljava/util/Map;)V",
+ string.object(),
+ hash.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+ } else {
+ // While on API levels < 14, only setDataSource(Context, Uri) is available and works for
+ // remote media...
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(urlString);
+ QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri",
+ "parse",
+ "(Ljava/lang/String;)Landroid/net/Uri;",
+ string.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Landroid/content/Context;Landroid/net/Uri;)V",
+ QtAndroidPrivate::activity(),
+ uri.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+ }
- return loaded;
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
index 1cf0bcc91..c1633580f 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
+++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
@@ -35,7 +35,6 @@
#define ANDROIDMEDIAMETADATARETRIEVER_H
#include <QtCore/private/qjni_p.h>
-#include <qurl.h>
QT_BEGIN_NAMESPACE
@@ -73,8 +72,7 @@ public:
QString extractMetadata(MetadataKey key);
void release();
- bool setDataSource(const QUrl &url);
- bool setDataSource(const QString &path);
+ bool setDataSource(const QString &url);
private:
QJNIObjectPrivate m_metadataRetriever;
diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
index a285f0180..9f8264565 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
@@ -39,7 +39,7 @@
#include "androidsurfacetexture.h"
#include <QMap>
-static jclass mediaPlayerClass = Q_NULLPTR;
+static const char QtAndroidMediaPlayerClassName[] = "org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer";
typedef QMap<jlong, AndroidMediaPlayer *> MediaPlayerMap;
Q_GLOBAL_STATIC(MediaPlayerMap, mediaPlayers)
@@ -50,10 +50,10 @@ AndroidMediaPlayer::AndroidMediaPlayer()
{
const jlong id = reinterpret_cast<jlong>(this);
- mMediaPlayer = QJNIObjectPrivate(mediaPlayerClass,
- "(Landroid/app/Activity;J)V",
- QtAndroidPrivate::activity(),
- id);
+ mMediaPlayer = QJNIObjectPrivate(QtAndroidMediaPlayerClassName,
+ "(Landroid/app/Activity;J)V",
+ QtAndroidPrivate::activity(),
+ id);
(*mediaPlayers)[id] = this;
}
@@ -233,26 +233,23 @@ static void onVideoSizeChangedNative(JNIEnv *env,
bool AndroidMediaPlayer::initJNI(JNIEnv *env)
{
- jclass jClass = env->FindClass("org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer");
-
- if (jClass) {
- mediaPlayerClass = static_cast<jclass>(env->NewGlobalRef(jClass));
-
- JNINativeMethod methods[] = {
- {"onErrorNative", "(IIJ)V", reinterpret_cast<void *>(onErrorNative)},
- {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast<void *>(onBufferingUpdateNative)},
- {"onProgressUpdateNative", "(IJ)V", reinterpret_cast<void *>(onProgressUpdateNative)},
- {"onDurationChangedNative", "(IJ)V", reinterpret_cast<void *>(onDurationChangedNative)},
- {"onInfoNative", "(IIJ)V", reinterpret_cast<void *>(onInfoNative)},
- {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast<void *>(onVideoSizeChangedNative)},
- {"onStateChangedNative", "(IJ)V", reinterpret_cast<void *>(onStateChangedNative)}
- };
-
- if (env->RegisterNatives(mediaPlayerClass,
- methods,
- sizeof(methods) / sizeof(methods[0])) < 0) {
+ jclass clazz = QJNIEnvironmentPrivate::findClass(QtAndroidMediaPlayerClassName,
+ env);
+
+ static const JNINativeMethod methods[] = {
+ {"onErrorNative", "(IIJ)V", reinterpret_cast<void *>(onErrorNative)},
+ {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast<void *>(onBufferingUpdateNative)},
+ {"onProgressUpdateNative", "(IJ)V", reinterpret_cast<void *>(onProgressUpdateNative)},
+ {"onDurationChangedNative", "(IJ)V", reinterpret_cast<void *>(onDurationChangedNative)},
+ {"onInfoNative", "(IIJ)V", reinterpret_cast<void *>(onInfoNative)},
+ {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast<void *>(onVideoSizeChangedNative)},
+ {"onStateChangedNative", "(IJ)V", reinterpret_cast<void *>(onStateChangedNative)}
+ };
+
+ if (clazz && env->RegisterNatives(clazz,
+ methods,
+ sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
return false;
- }
}
return true;
diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
index 074f1c92b..2d2b6e2f3 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
@@ -113,7 +113,7 @@ AndroidCamcorderProfile::AndroidCamcorderProfile(const QJNIObjectPrivate &camcor
m_camcorderProfile = camcorderProfile;
}
-static jclass g_qtMediaRecorderListenerClass = 0;
+static const char QtMediaRecorderListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtMediaRecorderListener";
typedef QMap<jlong, AndroidMediaRecorder*> MediaRecorderMap;
Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders)
@@ -137,7 +137,7 @@ AndroidMediaRecorder::AndroidMediaRecorder()
{
m_mediaRecorder = QJNIObjectPrivate("android/media/MediaRecorder");
if (m_mediaRecorder.isValid()) {
- QJNIObjectPrivate listener(g_qtMediaRecorderListenerClass, "(J)V", m_id);
+ QJNIObjectPrivate listener(QtMediaRecorderListenerClassName, "(J)V", m_id);
m_mediaRecorder.callMethod<void>("setOnErrorListener",
"(Landroid/media/MediaRecorder$OnErrorListener;)V",
listener.object());
@@ -339,24 +339,20 @@ void AndroidMediaRecorder::setOutputFile(const QString &path)
}
}
-static JNINativeMethod methods[] = {
- {"notifyError", "(JII)V", (void *)notifyError},
- {"notifyInfo", "(JII)V", (void *)notifyInfo}
-};
-
bool AndroidMediaRecorder::initJNI(JNIEnv *env)
{
- jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtMediaRecorderListener");
- if (env->ExceptionCheck())
- env->ExceptionClear();
+ jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName,
+ env);
+
+ static const JNINativeMethod methods[] = {
+ {"notifyError", "(JII)V", (void *)notifyError},
+ {"notifyInfo", "(JII)V", (void *)notifyInfo}
+ };
- if (clazz) {
- g_qtMediaRecorderListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- if (env->RegisterNatives(g_qtMediaRecorderListenerClass,
- methods,
- sizeof(methods) / sizeof(methods[0])) < 0) {
+ if (clazz && env->RegisterNatives(clazz,
+ methods,
+ sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
return false;
- }
}
return true;
diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
index 261a644d5..7cdab0097 100644
--- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp
@@ -37,7 +37,7 @@
QT_BEGIN_NAMESPACE
-static jclass g_qtSurfaceTextureListenerClass = 0;
+static const char QtSurfaceTextureListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener";
static QMap<int, AndroidSurfaceTexture*> g_objectMap;
// native method for QtSurfaceTexture.java
@@ -70,7 +70,7 @@ AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName)
if (m_surfaceTexture.isValid())
g_objectMap.insert(int(texName), this);
- QJNIObjectPrivate listener(g_qtSurfaceTextureListenerClass, "(I)V", jint(texName));
+ QJNIObjectPrivate listener(QtSurfaceTextureListenerClassName, "(I)V", jint(texName));
m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener",
"(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V",
listener.object());
@@ -144,27 +144,23 @@ jobject AndroidSurfaceTexture::surfaceHolder()
return m_surfaceHolder.object();
}
-static JNINativeMethod methods[] = {
- {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable}
-};
-
bool AndroidSurfaceTexture::initJNI(JNIEnv *env)
{
// SurfaceTexture is available since API 11.
if (QtAndroidPrivate::androidSdkVersion() < 11)
return false;
- jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener");
- if (env->ExceptionCheck())
- env->ExceptionClear();
+ jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceTextureListenerClassName,
+ env);
- if (clazz) {
- g_qtSurfaceTextureListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- if (env->RegisterNatives(g_qtSurfaceTextureListenerClass,
- methods,
- sizeof(methods) / sizeof(methods[0])) < 0) {
- return false;
- }
+ static const JNINativeMethod methods[] = {
+ {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable}
+ };
+
+ if (clazz && env->RegisterNatives(clazz,
+ methods,
+ sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
+ return false;
}
return true;
diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm
index 20792000a..77a145ba3 100644
--- a/src/plugins/avfoundation/camera/avfcameraservice.mm
+++ b/src/plugins/avfoundation/camera/avfcameraservice.mm
@@ -142,9 +142,9 @@ QMediaControl *AVFCameraService::requestControl(const char *name)
void AVFCameraService::releaseControl(QMediaControl *control)
{
if (m_videoOutput == control) {
- m_videoOutput = 0;
m_session->setVideoOutput(0);
- delete control;
+ delete m_videoOutput;
+ m_videoOutput = 0;
}
AVFMediaVideoProbeControl *videoProbe = qobject_cast<AVFMediaVideoProbeControl *>(control);
if (videoProbe) {
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
index e5549803f..bb75adb8b 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
@@ -118,14 +118,15 @@ void AVFMediaPlayerService::releaseControl(QMediaControl *control)
#ifdef QT_DEBUG_AVF
qDebug() << Q_FUNC_INFO << control;
#endif
-#if defined(Q_OS_OSX)
if (m_videoOutput == control) {
+#if defined(Q_OS_OSX)
AVFVideoRendererControl *renderControl = qobject_cast<AVFVideoRendererControl*>(m_videoOutput);
if (renderControl)
renderControl->setSurface(0);
+#endif
m_videoOutput = 0;
m_session->setVideoOutput(0);
+
delete control;
}
-#endif
}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
index 09ac4b5b3..5157a8571 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
@@ -97,8 +97,6 @@ public Q_SLOTS:
void processPositionChange();
void processMediaLoadError();
- void processCurrentItemChanged();
-
Q_SIGNALS:
void positionChanged(qint64 position);
void durationChanged(qint64 duration);
@@ -148,6 +146,9 @@ private:
QByteArray rawData;
};
+ void setAudioAvailable(bool available);
+ void setVideoAvailable(bool available);
+
AVFMediaPlayerService *m_service;
AVFVideoOutput *m_videoOutput;
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
index a73974ccd..73e9d764e 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
@@ -70,15 +70,11 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
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;
@@ -96,7 +92,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
@implementation AVFMediaPlayerSessionObserver
-@synthesize m_player, m_playerItem, m_playerLayer, m_audioAvailable, m_videoAvailable, m_session;
+@synthesize m_player, m_playerItem, m_playerLayer, m_session;
- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session
{
@@ -186,18 +182,6 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
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)
@@ -258,18 +242,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
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 = CGPointMake(0.0f, 0.0f);
- m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
- }
- }
-
+ m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f);
}
//Observe the AVPlayer "currentItem" property to find out when any
@@ -322,7 +295,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
//AVPlayerItem "status" property value observer.
if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
{
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
//Indicates that the status of the player is not yet known because
@@ -366,24 +339,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
{
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 = CGPointMake(0.0f, 0.0f);
- m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
- }
- }
-
- }
- if (self.session)
- QMetaObject::invokeMethod(m_session, "processCurrentItemChanged", Qt::AutoConnection);
}
else
{
@@ -513,6 +469,9 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
m_resources = content;
m_mediaStream = stream;
+ setAudioAvailable(false);
+ setVideoAvailable(false);
+
QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
if (content.isNull() || content.canonicalUrl().isEmpty()) {
@@ -582,14 +541,32 @@ bool AVFMediaPlayerSession::isMuted() const
return m_muted;
}
+void AVFMediaPlayerSession::setAudioAvailable(bool available)
+{
+ if (m_audioAvailable == available)
+ return;
+
+ m_audioAvailable = available;
+ Q_EMIT audioAvailableChanged(available);
+}
+
bool AVFMediaPlayerSession::isAudioAvailable() const
{
- return [(AVFMediaPlayerSessionObserver*)m_observer audioAvailable];
+ return m_audioAvailable;
+}
+
+void AVFMediaPlayerSession::setVideoAvailable(bool available)
+{
+ if (m_videoAvailable == available)
+ return;
+
+ m_videoAvailable = available;
+ Q_EMIT videoAvailableChanged(available);
}
bool AVFMediaPlayerSession::isVideoAvailable() const
{
- return [(AVFMediaPlayerSessionObserver*)m_observer videoAvailable];
+ return m_videoAvailable;
}
bool AVFMediaPlayerSession::isSeekable() const
@@ -802,16 +779,41 @@ void AVFMediaPlayerSession::processLoadStateChange()
bool isPlaying = (m_state != QMediaPlayer::StoppedState);
if (currentStatus == AVPlayerStatusReadyToPlay) {
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+ if (playerItem) {
+ // Check each track for audio and video content
+ AVAssetTrack *videoTrack = nil;
+ NSArray *tracks = playerItem.tracks;
+ for (AVPlayerItemTrack *track in tracks) {
+ AVAssetTrack *assetTrack = track.assetTrack;
+ if (assetTrack) {
+ if ([assetTrack.mediaType isEqualToString:AVMediaTypeAudio])
+ setAudioAvailable(true);
+ if ([assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) {
+ setVideoAvailable(true);
+ if (!videoTrack)
+ videoTrack = assetTrack;
+ }
+ }
+ }
+
+ // Get the native size of the video, and reset the bounds of the player layer
+ AVPlayerLayer *playerLayer = [(AVFMediaPlayerSessionObserver*)m_observer playerLayer];
+ if (videoTrack && playerLayer) {
+ playerLayer.bounds = CGRectMake(0.0f, 0.0f,
+ videoTrack.naturalSize.width,
+ videoTrack.naturalSize.height);
+
+ if (m_videoOutput && m_state != QMediaPlayer::StoppedState) {
+ m_videoOutput->setLayer(playerLayer);
+ }
+ }
+ }
+
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]) {
@@ -835,17 +837,3 @@ void AVFMediaPlayerSession::processMediaLoadError()
Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
}
-
-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/avfvideowidget.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
index d4fa7c4c6..2893921f3 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
@@ -64,8 +64,10 @@ AVFVideoWidget::~AVFVideoWidget()
qDebug() << Q_FUNC_INFO;
#endif
- if (m_playerLayer)
+ if (m_playerLayer) {
+ [m_playerLayer removeFromSuperlayer];
[m_playerLayer release];
+ }
}
QSize AVFVideoWidget::sizeHint() const
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
index 17fc94de7..8e96d732f 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
@@ -61,8 +61,10 @@ AVFVideoWindowControl::AVFVideoWindowControl(QObject *parent)
AVFVideoWindowControl::~AVFVideoWindowControl()
{
- if (m_playerLayer)
+ if (m_playerLayer) {
+ [m_playerLayer removeFromSuperlayer];
[m_playerLayer release];
+ }
}
WId AVFVideoWindowControl::winId() const
diff --git a/src/plugins/coreaudio/coreaudiodeviceinfo.mm b/src/plugins/coreaudio/coreaudiodeviceinfo.mm
index ac41a310c..2faeac8c9 100644
--- a/src/plugins/coreaudio/coreaudiodeviceinfo.mm
+++ b/src/plugins/coreaudio/coreaudiodeviceinfo.mm
@@ -45,6 +45,7 @@
# include "coreaudiosessionmanager.h"
#endif
+#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QSet>
diff --git a/src/plugins/coreaudio/coreaudioinput.h b/src/plugins/coreaudio/coreaudioinput.h
index 64691eb36..533b7fef4 100644
--- a/src/plugins/coreaudio/coreaudioinput.h
+++ b/src/plugins/coreaudio/coreaudioinput.h
@@ -38,6 +38,7 @@
#include <CoreAudio/CoreAudioTypes.h>
#include <AudioToolbox/AudioToolbox.h>
+#include <QtCore/QIODevice>
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
#include <QtCore/QTimer>
diff --git a/src/plugins/coreaudio/coreaudioinput.mm b/src/plugins/coreaudio/coreaudioinput.mm
index a0b9e9d25..972f959f5 100644
--- a/src/plugins/coreaudio/coreaudioinput.mm
+++ b/src/plugins/coreaudio/coreaudioinput.mm
@@ -52,6 +52,7 @@
#endif
#include <QtMultimedia/private/qaudiohelpers_p.h>
+#include <QtCore/QDataStream>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/coreaudio/coreaudiooutput.h b/src/plugins/coreaudio/coreaudiooutput.h
index 84083acea..23b229379 100644
--- a/src/plugins/coreaudio/coreaudiooutput.h
+++ b/src/plugins/coreaudio/coreaudiooutput.h
@@ -41,6 +41,7 @@
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/CoreAudioTypes.h>
+#include <QtCore/QIODevice>
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
diff --git a/src/plugins/coreaudio/coreaudiooutput.mm b/src/plugins/coreaudio/coreaudiooutput.mm
index e5e1c65e5..7bb5c0e15 100644
--- a/src/plugins/coreaudio/coreaudiooutput.mm
+++ b/src/plugins/coreaudio/coreaudiooutput.mm
@@ -43,6 +43,7 @@
#include "coreaudiodeviceinfo.h"
#include "coreaudioutils.h"
+#include <QtCore/QDataStream>
#include <QtCore/QTimer>
#include <QtCore/QDebug>
@@ -698,14 +699,14 @@ void CoreAudioOutput::audioThreadStop()
{
stopTimers();
if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
- m_threadFinished.wait(&m_mutex);
+ m_threadFinished.wait(&m_mutex, 500);
}
void CoreAudioOutput::audioThreadDrain()
{
stopTimers();
if (m_audioThreadState.testAndSetAcquire(Running, Draining))
- m_threadFinished.wait(&m_mutex);
+ m_threadFinished.wait(&m_mutex, 500);
}
void CoreAudioOutput::audioDeviceStop()
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
index fe8098a02..865a764a8 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
@@ -117,4 +117,28 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile()
return profile;
}
+void CameraBinAudioEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const bool isVorbis = qstrcmp(name, "vorbisenc") == 0;
+
+ const int bitRate = m_actualAudioSettings.bitRate();
+ if (!isVorbis && bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions unless the encoder is
+ // vorbisenc which is known to accept -1 as an unspecified bitrate.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (isVorbis) {
+ static const double qualities[] = { 0.1, 0.3, 0.5, 0.7, 1.0 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualAudioSettings.quality()], NULL);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
index 46f812a67..f71436552 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
@@ -78,6 +78,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *element);
+
Q_SIGNALS:
void settingsChanged();
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
index 4e7630b72..51024b7d9 100644
--- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
@@ -38,13 +38,9 @@
#include "camerabinserviceplugin.h"
-
#include "camerabinservice.h"
#include <private/qgstutils_p.h>
-#include <private/qcore_unix_p.h>
-#include <linux/videodev2.h>
-
QT_BEGIN_NAMESPACE
template <typename T, int N> static int lengthOf(const T(&)[N]) { return N; }
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index c7804b9cd..91affff46 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -98,6 +98,8 @@
#define CAPTURE_START "start-capture"
#define CAPTURE_STOP "stop-capture"
+#define FILESINK_BIN_NAME "videobin-filesink"
+
#define CAMERABIN_IMAGE_MODE 1
#define CAMERABIN_VIDEO_MODE 2
@@ -133,6 +135,7 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_capsFilter(0),
m_fileSink(0),
m_audioEncoder(0),
+ m_videoEncoder(0),
m_muxer(0)
{
if (m_sourceFactory)
@@ -140,6 +143,8 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_camerabin = gst_element_factory_make(QT_GSTREAMER_CAMERABIN_ELEMENT_NAME, "camerabin");
g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-added", G_CALLBACK(elementAdded), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-removed", G_CALLBACK(elementRemoved), this);
qt_gst_object_ref_sink(m_camerabin);
m_bus = gst_element_get_bus(m_camerabin);
@@ -319,6 +324,9 @@ void CameraBinSession::setupCaptureResolution()
if (caps)
gst_caps_unref(caps);
}
+
+ if (m_videoEncoder)
+ m_videoEncodeControl->applySettings(m_videoEncoder);
}
void CameraBinSession::setAudioCaptureCaps()
@@ -349,6 +357,9 @@ void CameraBinSession::setAudioCaptureCaps()
GstCaps *caps = gst_caps_new_full(structure, NULL);
g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
gst_caps_unref(caps);
+
+ if (m_audioEncoder)
+ m_audioEncodeControl->applySettings(m_audioEncoder);
}
GstElement *CameraBinSession::buildCameraSource()
@@ -691,12 +702,19 @@ void CameraBinSession::updateBusyStatus(GObject *o, GParamSpec *p, gpointer d)
qint64 CameraBinSession::duration() const
{
- gint64 duration = 0;
+ if (m_camerabin) {
+ GstElement *fileSink = gst_bin_get_by_name(GST_BIN(m_camerabin), FILESINK_BIN_NAME);
+ if (fileSink) {
+ GstFormat format = GST_FORMAT_TIME;
+ gint64 duration = 0;
+ bool ret = qt_gst_element_query_position(fileSink, format, &duration);
+ gst_object_unref(GST_OBJECT(fileSink));
+ if (ret)
+ return duration / 1000000;
+ }
+ }
- if (m_camerabin && qt_gst_element_query_position(m_camerabin, GST_FORMAT_TIME, &duration))
- return duration / 1000000;
- else
- return 0;
+ return 0;
}
bool CameraBinSession::isMuted() const
@@ -1193,4 +1211,32 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
return res;
}
+void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ GstElementFactory *factory = gst_element_get_factory(element);
+
+ if (GST_IS_BIN(element)) {
+ g_signal_connect(G_OBJECT(element), "element-added", G_CALLBACK(elementAdded), session);
+ g_signal_connect(G_OBJECT(element), "element-removed", G_CALLBACK(elementRemoved), session);
+ } else if (!factory) {
+ // no-op
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) {
+ session->m_audioEncoder = element;
+
+ session->m_audioEncodeControl->applySettings(element);
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) {
+ session->m_videoEncoder = element;
+
+ session->m_videoEncodeControl->applySettings(element);
+ }
+}
+
+void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ if (element == session->m_audioEncoder)
+ session->m_audioEncoder = 0;
+ else if (element == session->m_videoEncoder)
+ session->m_videoEncoder = 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 42ed0e988..7e8a46dee 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -190,6 +190,9 @@ private:
void setAudioCaptureCaps();
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
+ static void elementAdded(GstBin *bin, GstElement *element, CameraBinSession *session);
+ static void elementRemoved(GstBin *bin, GstElement *element, CameraBinSession *session);
+
QUrl m_sink;
QUrl m_actualSink;
bool m_recordingActive;
@@ -241,6 +244,7 @@ private:
GstElement *m_capsFilter;
GstElement *m_fileSink;
GstElement *m_audioEncoder;
+ GstElement *m_videoEncoder;
GstElement *m_muxer;
public:
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
index 228054318..554437047 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
@@ -175,4 +175,46 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile()
return (GstEncodingProfile *)profile;
}
+void CameraBinVideoEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const int bitRate = m_actualVideoSettings.bitRate();
+ if (bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (qstrcmp(name, "theoraenc") == 0) {
+ static const int qualities[] = { 8, 16, 32, 45, 60 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualVideoSettings.quality()], NULL);
+ } else if (qstrncmp(name, "avenc_", 6) == 0) {
+ if (g_object_class_find_property(objectClass, "pass")) {
+ static const int modes[] = { 0, 2, 512, 1024 };
+ g_object_set(G_OBJECT(encoder), "pass", modes[m_actualVideoSettings.encodingMode()], NULL);
+ }
+ if (g_object_class_find_property(objectClass, "quantizer")) {
+ static const double qualities[] = { 20, 8.0, 3.0, 2.5, 2.0 };
+ g_object_set(G_OBJECT(encoder), "quantizer", qualities[m_actualVideoSettings.quality()], NULL);
+ }
+ } else if (qstrncmp(name, "omx", 3) == 0) {
+ if (!g_object_class_find_property(objectClass, "control-rate")) {
+ } else switch (m_actualVideoSettings.encodingMode()) {
+ case QMultimedia::ConstantBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 2, NULL);
+ break;
+ case QMultimedia::AverageBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 1, NULL);
+ break;
+ default:
+ g_object_set(G_OBJECT(encoder), "control-rate", 0, NULL);
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
index 0838ba651..dabe098ab 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
@@ -76,6 +76,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *encoder);
+
Q_SIGNALS:
void settingsChanged();
diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.pro b/src/plugins/gstreamer/mediacapture/mediacapture.pro
index e8d039f8d..5baa0fd8f 100644
--- a/src/plugins/gstreamer/mediacapture/mediacapture.pro
+++ b/src/plugins/gstreamer/mediacapture/mediacapture.pro
@@ -15,7 +15,6 @@ HEADERS += $$PWD/qgstreamercaptureservice.h \
$$PWD/qgstreamerrecordercontrol.h \
$$PWD/qgstreamermediacontainercontrol.h \
$$PWD/qgstreamercameracontrol.h \
- $$PWD/qgstreamerv4l2input.h \
$$PWD/qgstreamercapturemetadatacontrol.h \
$$PWD/qgstreamerimagecapturecontrol.h \
$$PWD/qgstreamerimageencode.h \
@@ -28,7 +27,6 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \
$$PWD/qgstreamerrecordercontrol.cpp \
$$PWD/qgstreamermediacontainercontrol.cpp \
$$PWD/qgstreamercameracontrol.cpp \
- $$PWD/qgstreamerv4l2input.cpp \
$$PWD/qgstreamercapturemetadatacontrol.cpp \
$$PWD/qgstreamerimagecapturecontrol.cpp \
$$PWD/qgstreamerimageencode.cpp \
@@ -37,13 +35,18 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \
# Camera usage with gstreamer needs to have
#CONFIG += use_gstreamer_camera
-use_gstreamer_camera {
-DEFINES += USE_GSTREAMER_CAMERA
+use_gstreamer_camera:config_linux_v4l {
+ DEFINES += USE_GSTREAMER_CAMERA
+
+ OTHER_FILES += \
+ mediacapturecamera.json
+
+ HEADERS += \
+ $$PWD/qgstreamerv4l2input.h
+ SOURCES += \
+ $$PWD/qgstreamerv4l2input.cpp
-OTHER_FILES += \
- mediacapturecamera.json
} else {
-OTHER_FILES += \
- mediacapture.json
+ OTHER_FILES += \
+ mediacapture.json
}
-
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
index 771e32c91..1ab98cd4a 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -40,9 +40,12 @@
#include "qgstreamerimageencode.h"
#include "qgstreamercameracontrol.h"
#include <private/qgstreamerbushelper_p.h>
-#include "qgstreamerv4l2input.h"
#include "qgstreamercapturemetadatacontrol.h"
+#if defined(USE_GSTREAMER_CAMERA)
+#include "qgstreamerv4l2input.h"
+#endif
+
#include "qgstreamerimagecapturecontrol.h"
#include <private/qgstreameraudioinputselector_p.h>
#include <private/qgstreamervideoinputdevicecontrol_p.h>
@@ -63,7 +66,9 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
: QMediaService(parent)
, m_captureSession(0)
, m_cameraControl(0)
+#if defined(USE_GSTREAMER_CAMERA)
, m_videoInput(0)
+#endif
, m_metaDataControl(0)
, m_audioInputSelector(0)
, m_videoInputDevice(0)
@@ -80,6 +85,7 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this);
}
+#if defined(USE_GSTREAMER_CAMERA)
if (service == Q_MEDIASERVICE_CAMERA) {
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::AudioAndVideo, this);
m_cameraControl = new QGstreamerCameraControl(m_captureSession);
@@ -101,6 +107,7 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
#endif
m_imageCaptureControl = new QGstreamerImageCaptureControl(m_captureSession);
}
+#endif
m_audioInputSelector = new QGstreamerAudioInputSelector(this);
connect(m_audioInputSelector, SIGNAL(activeInputChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString)));
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
index a13e18477..e0cf4ee42 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
@@ -71,7 +71,9 @@ private:
QGstreamerCaptureSession *m_captureSession;
QGstreamerCameraControl *m_cameraControl;
+#if defined(USE_GSTREAMER_CAMERA)
QGstreamerV4L2Input *m_videoInput;
+#endif
QGstreamerCaptureMetaDataControl *m_metaDataControl;
QAudioInputSelectorControl *m_audioInputSelector;
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
index e9c922e28..8ae3a78de 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
@@ -76,8 +76,10 @@ static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys()
// Music
metadataKeys->insert(GST_TAG_ALBUM, QMediaMetaData::AlbumTitle);
- metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::AlbumArtist);
- metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::ContributingArtist);
+#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 25)
+ metadataKeys->insert(GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist);
+#endif
+ metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::ContributingArtist);
#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19)
metadataKeys->insert(GST_TAG_COMPOSER, QMediaMetaData::Composer);
#endif
@@ -164,6 +166,11 @@ void QGstreamerMetaDataProvider::updateTags()
}
}
+ if (oldTags.isEmpty() != m_tags.isEmpty()) {
+ emit metaDataAvailableChanged(isMetaDataAvailable());
+ changed = true;
+ }
+
if (changed)
emit metaDataChanged();
}
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
index e24973b06..49156bc07 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
@@ -60,7 +60,6 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
, m_currentState(QMediaPlayer::StoppedState)
, m_mediaStatus(QMediaPlayer::NoMedia)
, m_bufferProgress(-1)
- , m_seekToStartPending(false)
, m_pendingSeekPosition(-1)
, m_setMediaPending(false)
, m_stream(0)
@@ -69,7 +68,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
Q_ASSERT(m_resources);
connect(m_session, SIGNAL(positionChanged(qint64)),
- this, SLOT(updatePosition(qint64)));
+ this, SIGNAL(positionChanged(qint64)));
connect(m_session, SIGNAL(durationChanged(qint64)),
this, SIGNAL(durationChanged(qint64)));
connect(m_session, SIGNAL(mutedStateChanged(bool)),
@@ -94,8 +93,6 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
this, SLOT(handleInvalidMedia()));
connect(m_session, SIGNAL(playbackRateChanged(qreal)),
this, SIGNAL(playbackRateChanged(qreal)));
- connect(m_session, SIGNAL(seekableChanged(bool)),
- this, SLOT(applyPendingSeek(bool)));
connect(m_resources, SIGNAL(resourcesGranted()), SLOT(handleResourcesGranted()));
//denied signal should be queued to have correct state update process,
@@ -117,7 +114,7 @@ QMediaPlayerResourceSetInterface* QGstreamerPlayerControl::resources() const
qint64 QGstreamerPlayerControl::position() const
{
- return m_seekToStartPending ? 0 : m_session->position();
+ return m_pendingSeekPosition != -1 ? m_pendingSeekPosition : m_session->position();
}
qint64 QGstreamerPlayerControl::duration() const
@@ -183,15 +180,21 @@ void QGstreamerPlayerControl::setPosition(qint64 pos)
if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
m_mediaStatus = QMediaPlayer::LoadedMedia;
- m_seekToStartPending = true;
}
- if (m_session->isSeekable() && m_session->seek(pos)) {
- m_seekToStartPending = false;
- } else {
+ if (m_currentState == QMediaPlayer::StoppedState) {
m_pendingSeekPosition = pos;
- //don't display the first video frame since it's not what user requested.
- m_session->showPrerollFrames(false);
+ emit positionChanged(m_pendingSeekPosition);
+ } else if (m_session->isSeekable()) {
+ m_session->showPrerollFrames(true);
+ m_session->seek(pos);
+ m_pendingSeekPosition = -1;
+ } else if (m_session->state() == QMediaPlayer::StoppedState) {
+ m_pendingSeekPosition = pos;
+ emit positionChanged(m_pendingSeekPosition);
+ } else if (m_pendingSeekPosition != -1) {
+ m_pendingSeekPosition = -1;
+ emit positionChanged(m_pendingSeekPosition);
}
popAndNotifyState();
@@ -239,26 +242,30 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
}
#endif
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia && m_pendingSeekPosition == -1) {
+ m_pendingSeekPosition = 0;
+ }
+
if (!m_resources->isGranted())
m_resources->acquire();
if (m_resources->isGranted()) {
- if (m_seekToStartPending) {
+ // show prerolled frame if switching from stopped state
+ if (m_pendingSeekPosition == -1) {
+ m_session->showPrerollFrames(true);
+ } else if (m_session->state() == QMediaPlayer::StoppedState) {
+ // Don't evaluate the next two conditions.
+ } else if (m_session->isSeekable()) {
m_session->pause();
- if (!m_session->seek(0)) {
- m_bufferProgress = -1;
- m_session->stop();
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- }
- m_seekToStartPending = false;
+ m_session->showPrerollFrames(true);
+ m_session->seek(m_pendingSeekPosition);
+ m_pendingSeekPosition = -1;
+ } else {
+ m_pendingSeekPosition = -1;
}
bool ok = false;
- // show prerolled frame if switching from stopped state
- if (newState != QMediaPlayer::StoppedState && m_currentState == QMediaPlayer::StoppedState && m_pendingSeekPosition == -1)
- m_session->showPrerollFrames(true);
-
//To prevent displaying the first video frame when playback is resumed
//the pipeline is paused instead of playing, seeked to requested position,
//and after seeking is finished (position updated) playback is restarted
@@ -305,7 +312,7 @@ void QGstreamerPlayerControl::stop()
m_session->pause();
if (m_mediaStatus != QMediaPlayer::EndOfMedia) {
- m_seekToStartPending = true;
+ m_pendingSeekPosition = 0;
emit positionChanged(position());
}
}
@@ -343,7 +350,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
m_currentState = QMediaPlayer::StoppedState;
QMediaContent oldMedia = m_currentResource;
- m_pendingSeekPosition = -1;
+ m_pendingSeekPosition = 0;
m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called
m_setMediaPending = false;
@@ -390,7 +397,6 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
m_currentResource = content;
m_stream = stream;
- m_seekToStartPending = false;
QNetworkRequest request;
@@ -461,8 +467,21 @@ void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state)
{
pushState();
- if (state == QMediaPlayer::StoppedState)
+ if (state == QMediaPlayer::StoppedState) {
+ m_session->showPrerollFrames(false);
m_currentState = QMediaPlayer::StoppedState;
+ }
+
+ if (state == QMediaPlayer::PausedState && m_currentState != QMediaPlayer::StoppedState) {
+ if (m_pendingSeekPosition != -1 && m_session->isSeekable()) {
+ m_session->showPrerollFrames(true);
+ m_session->seek(m_pendingSeekPosition);
+ }
+ m_pendingSeekPosition = -1;
+
+ if (m_currentState == QMediaPlayer::PlayingState)
+ m_session->play();
+ }
updateMediaStatus();
@@ -511,7 +530,6 @@ void QGstreamerPlayerControl::processEOS()
m_mediaStatus = QMediaPlayer::EndOfMedia;
emit positionChanged(position());
m_session->endOfMediaReset();
- m_setMediaPending = true;
if (m_currentState != QMediaPlayer::StoppedState) {
m_currentState = QMediaPlayer::StoppedState;
@@ -550,17 +568,12 @@ void QGstreamerPlayerControl::setBufferProgress(int progress)
emit bufferStatusChanged(m_bufferProgress);
}
-void QGstreamerPlayerControl::applyPendingSeek(bool isSeekable)
-{
- if (isSeekable && m_pendingSeekPosition != -1)
- setPosition(m_pendingSeekPosition);
-}
-
void QGstreamerPlayerControl::handleInvalidMedia()
{
pushState();
m_mediaStatus = QMediaPlayer::InvalidMedia;
m_currentState = QMediaPlayer::StoppedState;
+ m_setMediaPending = true;
popAndNotifyState();
}
@@ -637,24 +650,4 @@ void QGstreamerPlayerControl::popAndNotifyState()
}
}
-void QGstreamerPlayerControl::updatePosition(qint64 pos)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << pos/1000.0 << "pending:" << m_pendingSeekPosition/1000.0;
-#endif
-
- if (m_pendingSeekPosition != -1) {
- //seek request is complete, it's safe to resume playback
- //with prerolled frame displayed
- m_pendingSeekPosition = -1;
- if (m_currentState != QMediaPlayer::StoppedState)
- m_session->showPrerollFrames(true);
- if (m_currentState == QMediaPlayer::PlayingState) {
- m_session->play();
- }
- }
-
- emit positionChanged(pos);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
index 94f7b7019..0a5f8af83 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
@@ -103,8 +103,6 @@ private Q_SLOTS:
void updateMediaStatus();
void processEOS();
void setBufferProgress(int progress);
- void applyPendingSeek(bool isSeekable);
- void updatePosition(qint64 pos);
void handleInvalidMedia();
@@ -127,7 +125,6 @@ private:
QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack;
int m_bufferProgress;
- bool m_seekToStartPending;
qint64 m_pendingSeekPosition;
bool m_setMediaPending;
QMediaContent m_currentResource;
diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp
index 9e344b463..cd592a7d6 100644
--- a/src/plugins/opensles/qopenslesaudioinput.cpp
+++ b/src/plugins/opensles/qopenslesaudioinput.cpp
@@ -474,7 +474,7 @@ qint64 QOpenSLESAudioInput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QOpenSLESAudioInput::setVolume(qreal vol)
diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp
index f055796b5..c45fbd3c5 100644
--- a/src/plugins/opensles/qopenslesaudiooutput.cpp
+++ b/src/plugins/opensles/qopenslesaudiooutput.cpp
@@ -70,7 +70,9 @@ QOpenSLESAudioOutput::QOpenSLESAudioOutput(const QByteArray &device)
m_periodSize(0),
m_elapsedTime(0),
m_processedBytes(0),
- m_availableBuffers(BUFFER_COUNT)
+ m_availableBuffers(BUFFER_COUNT),
+ m_eventMask(SL_PLAYEVENT_HEADATEND),
+ m_startRequiresInit(true)
{
#ifndef ANDROID
m_streamType = -1;
@@ -98,13 +100,10 @@ QAudio::State QOpenSLESAudioOutput::state() const
void QOpenSLESAudioOutput::start(QIODevice *device)
{
Q_ASSERT(device);
- destroyPlayer();
-
- m_pullMode = true;
-
if (!preparePlayer())
return;
+ m_pullMode = true;
m_audioSource = device;
setState(QAudio::ActiveState);
setError(QAudio::NoError);
@@ -125,29 +124,20 @@ void QOpenSLESAudioOutput::start(QIODevice *device)
// Change the state to playing.
// We need to do this after filling the buffers or processedBytes might get corrupted.
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- }
+ startPlayer();
}
QIODevice *QOpenSLESAudioOutput::start()
{
- destroyPlayer();
-
- m_pullMode = false;
-
if (!preparePlayer())
return Q_NULLPTR;
+ m_pullMode = false;
m_audioSource = new SLIODevicePrivate(this);
m_audioSource->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
// Change the state to playing
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- }
+ startPlayer();
setState(QAudio::IdleState);
return m_audioSource;
@@ -158,7 +148,7 @@ void QOpenSLESAudioOutput::stop()
if (m_state == QAudio::StoppedState)
return;
- destroyPlayer();
+ stopPlayer();
setError(QAudio::NoError);
}
@@ -180,6 +170,7 @@ void QOpenSLESAudioOutput::setBufferSize(int value)
if (m_state != QAudio::StoppedState)
return;
+ m_startRequiresInit = true;
m_bufferSize = value;
}
@@ -190,7 +181,33 @@ int QOpenSLESAudioOutput::bufferSize() const
void QOpenSLESAudioOutput::setNotifyInterval(int ms)
{
- m_notifyInterval = ms > 0 ? ms : 0;
+ const int newInterval = ms > 0 ? ms : 0;
+
+ if (newInterval == m_notifyInterval)
+ return;
+
+ const SLuint32 newEvenMask = newInterval == 0 ? m_eventMask & ~SL_PLAYEVENT_HEADATNEWPOS
+ : m_eventMask & SL_PLAYEVENT_HEADATNEWPOS;
+
+ if (m_state == QAudio::StoppedState) {
+ m_eventMask = newEvenMask;
+ m_notifyInterval = newInterval;
+ return;
+ }
+
+ if (newEvenMask != m_eventMask
+ && SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, newEvenMask)) {
+ return;
+ }
+
+ m_eventMask = newEvenMask;
+
+ if (newInterval && SL_RESULT_SUCCESS != (*m_playItf)->SetPositionUpdatePeriod(m_playItf,
+ newInterval)) {
+ return;
+ }
+
+ m_notifyInterval = newInterval;
}
int QOpenSLESAudioOutput::notifyInterval() const
@@ -227,6 +244,7 @@ void QOpenSLESAudioOutput::resume()
void QOpenSLESAudioOutput::setFormat(const QAudioFormat &format)
{
+ m_startRequiresInit = true;
m_format = format;
}
@@ -255,7 +273,7 @@ qint64 QOpenSLESAudioOutput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QOpenSLESAudioOutput::reset()
@@ -298,6 +316,7 @@ void QOpenSLESAudioOutput::setCategory(const QString &category)
return;
}
+ m_startRequiresInit = true;
m_streamType = streamType;
m_category = category;
#endif // ANDROID
@@ -376,6 +395,11 @@ void QOpenSLESAudioOutput::bufferQueueCallback(SLBufferQueueItf bufferQueue, voi
bool QOpenSLESAudioOutput::preparePlayer()
{
+ if (m_startRequiresInit)
+ destroyPlayer();
+ else
+ return true;
+
SLEngineItf engine = QOpenSLESEngine::instance()->slEngine();
if (!engine) {
qWarning() << "No engine";
@@ -480,13 +504,12 @@ bool QOpenSLESAudioOutput::preparePlayer()
return false;
}
- SLuint32 mask = SL_PLAYEVENT_HEADATEND;
if (m_notifyInterval && SL_RESULT_SUCCESS == (*m_playItf)->SetPositionUpdatePeriod(m_playItf,
m_notifyInterval)) {
- mask |= SL_PLAYEVENT_HEADATNEWPOS;
+ m_eventMask |= SL_PLAYEVENT_HEADATNEWPOS;
}
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, mask)) {
+ if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, m_eventMask)) {
setError(QAudio::FatalError);
return false;
}
@@ -517,20 +540,15 @@ bool QOpenSLESAudioOutput::preparePlayer()
m_clockStamp.restart();
setError(QAudio::NoError);
+ m_startRequiresInit = false;
return true;
}
void QOpenSLESAudioOutput::destroyPlayer()
{
- setState(QAudio::StoppedState);
-
- // We need to change the state manually...
- if (m_playItf)
- (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
-
- if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf))
- qWarning() << "Unable to clear buffer";
+ if (m_state != QAudio::StoppedState)
+ stopPlayer();
if (m_playerObject) {
(*m_playerObject)->Destroy(m_playerObject);
@@ -556,6 +574,27 @@ void QOpenSLESAudioOutput::destroyPlayer()
m_playItf = Q_NULLPTR;
m_volumeItf = Q_NULLPTR;
m_bufferQueueItf = Q_NULLPTR;
+ m_startRequiresInit = true;
+}
+
+void QOpenSLESAudioOutput::stopPlayer()
+{
+ setState(QAudio::StoppedState);
+
+ // We need to change the state manually...
+ if (m_playItf)
+ (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
+
+ if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf))
+ qWarning() << "Unable to clear buffer";
+}
+
+void QOpenSLESAudioOutput::startPlayer()
+{
+ if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
+ setError(QAudio::FatalError);
+ destroyPlayer();
+ }
}
qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len)
diff --git a/src/plugins/opensles/qopenslesaudiooutput.h b/src/plugins/opensles/qopenslesaudiooutput.h
index 60c8cfa86..200b4a3cc 100644
--- a/src/plugins/opensles/qopenslesaudiooutput.h
+++ b/src/plugins/opensles/qopenslesaudiooutput.h
@@ -86,6 +86,8 @@ private:
bool preparePlayer();
void destroyPlayer();
+ void stopPlayer();
+ void startPlayer();
qint64 writeData(const char *data, qint64 len);
void setState(QAudio::State state);
@@ -112,6 +114,8 @@ private:
qint64 m_elapsedTime;
qint64 m_processedBytes;
QAtomicInt m_availableBuffers;
+ SLuint32 m_eventMask;
+ bool m_startRequiresInit;
qint32 m_streamType;
QTime m_clockStamp;
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 0020203c3..aa28bdd1b 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -44,15 +44,15 @@ unix:!mac:!android {
config_alsa: SUBDIRS += alsa
# v4l is turned off because it is not supported in Qt 5
- # !maemo*:SUBDIRS += v4l
+ # config_linux_v4l {
+ # !maemo*:SUBDIRS += v4l
+ # }
}
mac:!simulator {
SUBDIRS += audiocapture coreaudio
config_avfoundation: SUBDIRS += avfoundation
-
- contains(QT_CONFIG, opengl.*):!ios: SUBDIRS += qt7
}
config_resourcepolicy {
diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
index b97cd6c4f..ea053578f 100644
--- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
@@ -684,7 +684,7 @@ qint64 QPulseAudioInput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QPulseAudioInput::reset()
diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
index c55cfe44c..b979450b6 100644
--- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
@@ -596,7 +596,7 @@ qint64 QPulseAudioOutput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QPulseAudioOutput::reset()
diff --git a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
index ea9ea5abf..3f60dfc29 100644
--- a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
@@ -186,7 +186,7 @@ qint64 QnxAudioInput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
QAudio::Error QnxAudioInput::error() const
diff --git a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
index 4604ed542..e7733276e 100644
--- a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
@@ -172,7 +172,7 @@ qint64 QnxAudioOutput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
else
- return m_startTimeStamp.elapsed() * 1000;
+ return m_startTimeStamp.elapsed() * qint64(1000);
}
QAudio::Error QnxAudioOutput::error() const
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
index 217f8b3bb..503c5beb8 100644
--- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
@@ -538,6 +538,7 @@ void MmRendererMediaPlayerControl::play()
return;
}
+ m_stopEventsToIgnore = 0; // once playing, stop events must be proccessed
setState( QMediaPlayer::PlayingState);
}
diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
index e48cba794..f95cd8a99 100644
--- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
@@ -70,7 +70,7 @@ void MmRendererPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *sur
m_surface = QPointer<QAbstractVideoSurface>(surface);
if (QOpenGLContext::currentContext())
m_windowGrabber->checkForEglImageExtension();
- else
+ else if (m_surface)
m_surface->setProperty("_q_GLThreadCallback", QVariant::fromValue<QObject*>(this));
}
diff --git a/src/plugins/qt7/mediaplayer/mediaplayer.pri b/src/plugins/qt7/mediaplayer/mediaplayer.pri
deleted file mode 100644
index 2edb1d2c7..000000000
--- a/src/plugins/qt7/mediaplayer/mediaplayer.pri
+++ /dev/null
@@ -1,16 +0,0 @@
-INCLUDEPATH += $$PWD
-
-DEFINES += QMEDIA_QT7_PLAYER
-
-HEADERS += \
- $$PWD/qt7playercontrol.h \
- $$PWD/qt7playermetadata.h \
- $$PWD/qt7playerservice.h \
- $$PWD/qt7playersession.h
-
-OBJECTIVE_SOURCES += \
- $$PWD/qt7playercontrol.mm \
- $$PWD/qt7playermetadata.mm \
- $$PWD/qt7playerservice.mm \
- $$PWD/qt7playersession.mm
-
diff --git a/src/plugins/qt7/mediaplayer/qt7playercontrol.h b/src/plugins/qt7/mediaplayer/qt7playercontrol.h
deleted file mode 100644
index 61fd0a456..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playercontrol.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERCONTROL_H
-#define QT7PLAYERCONTROL_H
-
-#include <QtCore/qobject.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-class QT7PlayerService;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-
-class QT7PlayerControl : public QMediaPlayerControl
-{
-Q_OBJECT
-public:
- QT7PlayerControl(QObject *parent = 0);
- ~QT7PlayerControl();
-
- void setSession(QT7PlayerSession *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:
- QT7PlayerSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playercontrol.mm b/src/plugins/qt7/mediaplayer/qt7playercontrol.mm
deleted file mode 100644
index c48660778..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playercontrol.mm
+++ /dev/null
@@ -1,191 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 "qt7playercontrol.h"
-#include "qt7playersession.h"
-
-#include <private/qmediaplaylistnavigator_p.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerControl::QT7PlayerControl(QObject *parent)
- : QMediaPlayerControl(parent)
-{
-}
-
-QT7PlayerControl::~QT7PlayerControl()
-{
-}
-
-void QT7PlayerControl::setSession(QT7PlayerSession *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)));
-}
-
-qint64 QT7PlayerControl::position() const
-{
- return m_session->position();
-}
-
-qint64 QT7PlayerControl::duration() const
-{
- return m_session->duration();
-}
-
-QMediaPlayer::State QT7PlayerControl::state() const
-{
- return m_session->state();
-}
-
-QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const
-{
- return m_session->mediaStatus();
-}
-
-int QT7PlayerControl::bufferStatus() const
-{
- return m_session->bufferStatus();
-}
-
-int QT7PlayerControl::volume() const
-{
- return m_session->volume();
-}
-
-bool QT7PlayerControl::isMuted() const
-{
- return m_session->isMuted();
-}
-
-bool QT7PlayerControl::isSeekable() const
-{
- return m_session->isSeekable();
-}
-
-QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const
-{
- return m_session->availablePlaybackRanges();
-}
-
-qreal QT7PlayerControl::playbackRate() const
-{
- return m_session->playbackRate();
-}
-
-void QT7PlayerControl::setPlaybackRate(qreal rate)
-{
- m_session->setPlaybackRate(rate);
-}
-
-void QT7PlayerControl::setPosition(qint64 pos)
-{
- m_session->setPosition(pos);
-}
-
-void QT7PlayerControl::play()
-{
- m_session->play();
-}
-
-void QT7PlayerControl::pause()
-{
- m_session->pause();
-}
-
-void QT7PlayerControl::stop()
-{
- m_session->stop();
-}
-
-void QT7PlayerControl::setVolume(int volume)
-{
- m_session->setVolume(volume);
-}
-
-void QT7PlayerControl::setMuted(bool muted)
-{
- m_session->setMuted(muted);
-}
-
-QMediaContent QT7PlayerControl::media() const
-{
- return m_session->media();
-}
-
-const QIODevice *QT7PlayerControl::mediaStream() const
-{
- return m_session->mediaStream();
-}
-
-void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
-{
- m_session->setMedia(content, stream);
-
- Q_EMIT mediaChanged(content);
-}
-
-bool QT7PlayerControl::isAudioAvailable() const
-{
- return m_session->isAudioAvailable();
-}
-
-bool QT7PlayerControl::isVideoAvailable() const
-{
- return m_session->isVideoAvailable();
-}
-
-
-#include "moc_qt7playercontrol.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playermetadata.h b/src/plugins/qt7/mediaplayer/qt7playermetadata.h
deleted file mode 100644
index 9f0ceae16..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playermetadata.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERMETADATACONTROL_H
-#define QT7PLAYERMETADATACONTROL_H
-
-#include <qmetadatareadercontrol.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-
-class QT7PlayerMetaDataControl : public QMetaDataReaderControl
-{
- Q_OBJECT
-public:
- QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent);
- virtual ~QT7PlayerMetaDataControl();
-
- bool isMetaDataAvailable() const;
- bool isWritable() const;
-
- QVariant metaData(const QString &key) const;
- QStringList availableMetaData() const;
-
-private Q_SLOTS:
- void updateTags();
-
-private:
- QT7PlayerSession *m_session;
- QMap<QString, QVariant> m_tags;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playermetadata.mm b/src/plugins/qt7/mediaplayer/qt7playermetadata.mm
deleted file mode 100644
index 84d434be2..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playermetadata.mm
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 "qt7backend.h"
-#include "qt7playermetadata.h"
-#include "qt7playersession.h"
-#include <QtCore/qvarlengtharray.h>
-#include <QtMultimedia/qmediametadata.h>
-
-#import <QTKit/QTMovie.h>
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- #include <QuickTime/QuickTime.h>
- #undef check // avoid name clash;
-#endif
-
-QT_USE_NAMESPACE
-
-QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent)
- :QMetaDataReaderControl(parent), m_session(session)
-{
-}
-
-QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl()
-{
-}
-
-bool QT7PlayerMetaDataControl::isMetaDataAvailable() const
-{
- return !m_tags.isEmpty();
-}
-
-bool QT7PlayerMetaDataControl::isWritable() const
-{
- return false;
-}
-
-QVariant QT7PlayerMetaDataControl::metaData(const QString &key) const
-{
- return m_tags.value(key);
-}
-
-QStringList QT7PlayerMetaDataControl::availableMetaData() const
-{
- return m_tags.keys();
-}
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-
-static QString stripCopyRightSymbol(const QString &key)
-{
- return key.right(key.length()-1);
-}
-
-static QString convertQuickTimeKeyToUserKey(const QString &key)
-{
- if (key == QLatin1String("com.apple.quicktime.displayname"))
- return QLatin1String("nam");
- else if (key == QLatin1String("com.apple.quicktime.album"))
- return QLatin1String("alb");
- else if (key == QLatin1String("com.apple.quicktime.artist"))
- return QLatin1String("ART");
- else
- return QLatin1String("???");
-}
-
-static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
- QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
-{
- QTPropertyValueType type;
- ByteCount propSize;
- UInt32 propFlags;
- OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
-
- if (err == noErr) {
- *value = malloc(propSize);
- if (*value != 0) {
- err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
-
- if (err == noErr && (type == 'code' || type == 'itsk' || type == 'itlk')) {
- // convert from native endian to big endian
- OSTypePtr pType = (OSTypePtr)*value;
- *pType = EndianU32_NtoB(*pType);
- }
- }
- else
- return -1;
- }
-
- return err;
-}
-
-static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
-{
- QTPropertyValuePtr value = 0;
- ByteCount ignore = 0;
- OSStatus err = readMetaValue(
- metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
-
- if (err == noErr) {
- UInt32 type = *((UInt32 *) value);
- if (value)
- free(value);
- return type;
- }
-
- return 0;
-}
-
-static QString cFStringToQString(CFStringRef str)
-{
- if(!str)
- return QString();
- CFIndex length = CFStringGetLength(str);
- const UniChar *chars = CFStringGetCharactersPtr(str);
- if (chars)
- return QString(reinterpret_cast<const QChar *>(chars), length);
-
- QVarLengthArray<UniChar> buffer(length);
- CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
- return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
-}
-
-
-static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
-{
- QTPropertyValuePtr value = 0;
- ByteCount size = 0;
- OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
- QString string;
-
- if (err == noErr) {
- UInt32 dataType = getMetaType(metaDataRef, item);
- switch (dataType){
- case kQTMetaDataTypeUTF8:
- case kQTMetaDataTypeMacEncodedText:
- string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
- break;
- case kQTMetaDataTypeUTF16BE:
- string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
- break;
- default:
- break;
- }
-
- if (value)
- free(value);
- }
-
- return string;
-}
-
-
-static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
-{
- QTMetaDataItem item = kQTMetaDataItemUninitialized;
- OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
- while (err == noErr){
- QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
- if (format == kQTMetaDataStorageFormatQuickTime)
- key = convertQuickTimeKeyToUserKey(key);
- else
- key = stripCopyRightSymbol(key);
-
- if (!result.contains(key)){
- QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
- result.insert(key, val);
- }
- err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
- }
-}
-#endif
-
-
-void QT7PlayerMetaDataControl::updateTags()
-{
- bool wasEmpty = m_tags.isEmpty();
- m_tags.clear();
-
- QTMovie *movie = (QTMovie*)m_session->movie();
-
- if (movie) {
- QMultiMap<QString, QString> metaMap;
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTMetaDataRef metaDataRef;
- OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef);
- if (err == noErr) {
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
- }
-#else
- AutoReleasePool pool;
- NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"];
- metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
-#endif // QUICKTIME_C_API_AVAILABLE
-
- m_tags.insert(QMediaMetaData::AlbumArtist, metaMap.value(QLatin1String("ART")));
- m_tags.insert(QMediaMetaData::AlbumTitle, metaMap.value(QLatin1String("alb")));
- m_tags.insert(QMediaMetaData::Title, metaMap.value(QLatin1String("nam")));
- m_tags.insert(QMediaMetaData::Date, metaMap.value(QLatin1String("day")));
- m_tags.insert(QMediaMetaData::Genre, metaMap.value(QLatin1String("gnre")));
- m_tags.insert(QMediaMetaData::TrackNumber, metaMap.value(QLatin1String("trk")));
- m_tags.insert(QMediaMetaData::Description, metaMap.value(QLatin1String("des")));
- }
-
- if (!wasEmpty || !m_tags.isEmpty())
- Q_EMIT metaDataChanged();
-}
-
-#include "moc_qt7playermetadata.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playerservice.h b/src/plugins/qt7/mediaplayer/qt7playerservice.h
deleted file mode 100644
index 15c1d2cb7..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playerservice.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSERVICE_H
-#define QT7PLAYERSERVICE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qset.h>
-#include <qmediaservice.h>
-
-
-QT_BEGIN_NAMESPACE
-class QMediaPlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7PlayerControl;
-class QT7PlayerMetaDataControl;
-class QT7VideoWindowControl;
-class QT7VideoWidgetControl;
-class QT7VideoRendererControl;
-class QT7VideoOutput;
-class QT7PlayerSession;
-
-class QT7PlayerService : public QMediaService
-{
-Q_OBJECT
-public:
- QT7PlayerService(QObject *parent = 0);
- ~QT7PlayerService();
-
- QMediaControl* requestControl(const char *name);
- void releaseControl(QMediaControl *control);
-
-private:
- QT7PlayerSession *m_session;
- QT7PlayerControl *m_control;
- QMediaControl * m_videoOutput;
- QT7PlayerMetaDataControl *m_playerMetaDataControl;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playerservice.mm b/src/plugins/qt7/mediaplayer/qt7playerservice.mm
deleted file mode 100644
index 46be5475f..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playerservice.mm
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 <QtCore/qvariant.h>
-#include <QtCore/qdebug.h>
-
-#include "qt7backend.h"
-#include "qt7playerservice.h"
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-#include "qt7videooutput.h"
-#include "qt7movieviewoutput.h"
-#include "qt7movieviewrenderer.h"
-#include "qt7movierenderer.h"
-#ifndef QT_NO_WIDGETS
-#include "qt7movievideowidget.h"
-#endif
-#include "qt7playermetadata.h"
-
-#include <private/qmediaplaylistnavigator_p.h>
-#include <qmediaplaylist.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerService::QT7PlayerService(QObject *parent):
- QMediaService(parent),
- m_videoOutput(0)
-{
- m_session = new QT7PlayerSession(this);
-
- m_control = new QT7PlayerControl(this);
- m_control->setSession(m_session);
-
- m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this);
- connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
-}
-
-QT7PlayerService::~QT7PlayerService()
-{
-}
-
-QMediaControl *QT7PlayerService::requestControl(const char *name)
-{
- if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
- return m_control;
-
- if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
- return m_playerMetaDataControl;
-
-#ifndef QT_NO_OPENGL
- if (!m_videoOutput) {
- if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
- m_videoOutput = new QT7MovieViewOutput(this);
- }
-
- if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
-#ifndef QT_NO_WIDGETS
- m_videoOutput = new QT7MovieViewRenderer(this);
-#endif
- }
-
-#ifndef QT_NO_WIDGETS
- if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_videoOutput = new QT7MovieVideoWidget(this);
-#endif
- }
-#endif
-
- if (m_videoOutput) {
- QT7VideoOutput *videoOutput = qobject_cast<QT7VideoOutput*>(m_videoOutput);
- m_session->setVideoOutput(videoOutput);
- return m_videoOutput;
- }
- }
-#endif // !defined(QT_NO_OPENGL)
-
- return 0;
-}
-
-void QT7PlayerService::releaseControl(QMediaControl *control)
-{
- if (m_videoOutput == control) {
- m_videoOutput = 0;
- m_session->setVideoOutput(0);
- delete control;
- }
-}
-
-#include "moc_qt7playerservice.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playersession.h b/src/plugins/qt7/mediaplayer/qt7playersession.h
deleted file mode 100644
index 58ea76a01..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playersession.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSESSION_H
-#define QT7PLAYERSESSION_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qset.h>
-#include <QtCore/qresource.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7VideoOutput;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-
-class QT7PlayerSession : public QObject
-{
- Q_OBJECT
-public:
- QT7PlayerSession(QObject *parent = 0);
- ~QT7PlayerSession();
-
- void *movie() const;
-
- void setControl(QT7PlayerControl *control);
-
- void setVideoOutput(QT7VideoOutput *output);
-
- 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 processVolumeChange();
- void processNaturalSizeChange();
- void processPositionChange();
-
-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;
- };
-
- void openMovie(bool tryAsync);
-
- void *m_QTMovie;
- void *m_movieObserver;
-
- QMediaPlayer::State m_state;
- QMediaPlayer::MediaStatus m_mediaStatus;
- QIODevice *m_mediaStream;
- QMediaContent m_resources;
- ResourceHandler m_resourceHandler;
-
- QT7VideoOutput * m_videoOutput;
-
- bool m_muted;
- bool m_tryingAsync;
- int m_volume;
- qreal m_rate;
-
- qint64 m_duration;
- bool m_videoAvailable;
- bool m_audioAvailable;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playersession.mm b/src/plugins/qt7/mediaplayer/qt7playersession.mm
deleted file mode 100644
index 4ec015cbf..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playersession.mm
+++ /dev/null
@@ -1,751 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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$
-**
-****************************************************************************/
-
-#import <QTKit/QTDataReference.h>
-#import <QTKit/QTMovie.h>
-
-#include "qt7backend.h"
-
-#include "qt7playersession.h"
-#include "qt7playercontrol.h"
-#include "qt7videooutput.h"
-
-#include <QtNetwork/qnetworkcookie.h>
-#include <private/qmediaplaylistnavigator_p.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qurl.h>
-
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-//#define QT_DEBUG_QT7
-
-@interface QTMovieObserver : NSObject
-{
-@private
- QT7PlayerSession *m_session;
- QTMovie *m_movie;
-}
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session;
-- (void) setMovie:(QTMovie *)movie;
-- (void) processEOS:(NSNotification *)notification;
-- (void) processLoadStateChange:(NSNotification *)notification;
-- (void) processVolumeChange:(NSNotification *)notification;
-- (void) processNaturalSizeChange :(NSNotification *)notification;
-- (void) processPositionChange :(NSNotification *)notification;
-@end
-
-@implementation QTMovieObserver
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session
-{
- if (!(self = [super init]))
- return nil;
-
- self->m_session = session;
- return self;
-}
-
-- (void) setMovie:(QTMovie *)movie
-{
- if (m_movie == movie)
- return;
-
- if (m_movie) {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [m_movie release];
- }
-
- m_movie = movie;
-
- if (movie) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processEOS:)
- name:QTMovieDidEndNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processLoadStateChange:)
- name:QTMovieLoadStateDidChangeNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processVolumeChange:)
- name:QTMovieVolumeDidChangeNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processPositionChange:)
- name:QTMovieTimeDidChangeNotification
- object:m_movie];
-
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processNaturalSizeChange:)
- name:@"QTMovieNaturalSizeDidChangeNotification"
- object:m_movie];
-
- }
- else {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processNaturalSizeChange:)
- name:QTMovieEditedNotification
- object:m_movie];
- }
-
- [movie retain];
- }
-}
-
-- (void) processEOS:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection);
-}
-
-- (void) processLoadStateChange:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
-}
-
-- (void) processVolumeChange:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection);
-}
-
-- (void) processNaturalSizeChange :(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection);
-}
-
-- (void) processPositionChange :(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processPositionChange", Qt::AutoConnection);
-}
-
-@end
-
-static inline NSString *qString2CFStringRef(const QString &string)
-{
- return [NSString stringWithCharacters:reinterpret_cast<const UniChar *>(string.unicode()) length:string.length()];
-}
-
-QT7PlayerSession::QT7PlayerSession(QObject *parent)
- : QObject(parent)
- , m_QTMovie(0)
- , m_state(QMediaPlayer::StoppedState)
- , m_mediaStatus(QMediaPlayer::NoMedia)
- , m_mediaStream(0)
- , m_videoOutput(0)
- , m_muted(false)
- , m_tryingAsync(false)
- , m_volume(100)
- , m_rate(1.0)
- , m_duration(0)
- , m_videoAvailable(false)
- , m_audioAvailable(false)
-{
- m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this];
-}
-
-QT7PlayerSession::~QT7PlayerSession()
-{
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- [(QTMovieObserver*)m_movieObserver setMovie:nil];
- [(QTMovieObserver*)m_movieObserver release];
- [(QTMovie*)m_QTMovie release];
-}
-
-void *QT7PlayerSession::movie() const
-{
- return m_QTMovie;
-}
-
-void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output)
-{
- if (m_videoOutput == output)
- return;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- m_videoOutput = output;
-
- if (m_videoOutput && m_state != QMediaPlayer::StoppedState)
- m_videoOutput->setMovie(m_QTMovie);
-}
-
-qint64 QT7PlayerSession::position() const
-{
- if (!m_QTMovie)
- return 0;
-
- QTTime qtTime = [(QTMovie*)m_QTMovie currentTime];
-
- return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-}
-
-qint64 QT7PlayerSession::duration() const
-{
- if (!m_QTMovie)
- return 0;
-
- QTTime qtTime = [(QTMovie*)m_QTMovie duration];
-
- return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-}
-
-QMediaPlayer::State QT7PlayerSession::state() const
-{
- return m_state;
-}
-
-QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const
-{
- return m_mediaStatus;
-}
-
-int QT7PlayerSession::bufferStatus() const
-{
- return 100;
-}
-
-int QT7PlayerSession::volume() const
-{
- return m_volume;
-}
-
-bool QT7PlayerSession::isMuted() const
-{
- return m_muted;
-}
-
-bool QT7PlayerSession::isSeekable() const
-{
- return true;
-}
-
-#ifndef QUICKTIME_C_API_AVAILABLE
-@interface QTMovie(QtExtensions)
-- (NSArray*)loadedRanges;
-- (QTTime)maxTimeLoaded;
-@end
-#endif
-
-QMediaTimeRange QT7PlayerSession::availablePlaybackRanges() const
-{
- QTMovie *movie = (QTMovie*)m_QTMovie;
-#ifndef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- if ([movie respondsToSelector:@selector(loadedRanges)]) {
- QMediaTimeRange rc;
- NSArray *r = [movie loadedRanges];
- for (NSValue *tr in r) {
- QTTimeRange timeRange = [tr QTTimeRangeValue];
- qint64 startTime = qint64(float(timeRange.time.timeValue) / timeRange.time.timeScale * 1000.0);
- rc.addInterval(startTime, startTime + qint64(float(timeRange.duration.timeValue) / timeRange.duration.timeScale * 1000.0));
- }
- return rc;
- }
- else if ([movie respondsToSelector:@selector(maxTimeLoaded)]) {
- QTTime loadedTime = [movie maxTimeLoaded];
- return QMediaTimeRange(0, qint64(float(loadedTime.timeValue) / loadedTime.timeScale * 1000.0));
- }
-#else
- TimeValue loadedTime;
- TimeScale scale;
- Movie m = [movie quickTimeMovie];
- if (GetMaxLoadedTimeInMovie(m, &loadedTime) == noErr) {
- scale = GetMovieTimeScale(m);
- return QMediaTimeRange(0, qint64(float(loadedTime) / scale * 1000.0f));
- }
-#endif
- return QMediaTimeRange(0, duration());
-}
-
-qreal QT7PlayerSession::playbackRate() const
-{
- return m_rate;
-}
-
-void QT7PlayerSession::setPlaybackRate(qreal rate)
-{
- if (qFuzzyCompare(m_rate, rate))
- return;
-
- m_rate = rate;
-
- if (m_QTMovie != 0 && m_state == QMediaPlayer::PlayingState) {
- AutoReleasePool pool;
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
- }
-}
-
-void QT7PlayerSession::setPosition(qint64 pos)
-{
- if ( !isSeekable() || pos == position())
- return;
-
- if (duration() > 0)
- pos = qMin(pos, duration());
-
- QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime];
- newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale;
- [(QTMovie*)m_QTMovie setCurrentTime:newQTTime];
-
- //reset the EndOfMedia status position is changed after playback is finished
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-}
-
-void QT7PlayerSession::play()
-{
- if (m_state == QMediaPlayer::PlayingState)
- return;
-
- m_state = QMediaPlayer::PlayingState;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- //reset the EndOfMedia status if the same file is played again
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-
- AutoReleasePool pool;
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
-}
-
-void QT7PlayerSession::pause()
-{
- if (m_state == QMediaPlayer::PausedState)
- return;
-
- m_state = QMediaPlayer::PausedState;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- //reset the EndOfMedia status if the same file is played again
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-
- [(QTMovie*)m_QTMovie setRate:0];
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
-}
-
-void QT7PlayerSession::stop()
-{
- if (m_state == QMediaPlayer::StoppedState)
- return;
-
- m_state = QMediaPlayer::StoppedState;
-
- [(QTMovie*)m_QTMovie setRate:0];
- setPosition(0);
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
- Q_EMIT positionChanged(position());
-}
-
-void QT7PlayerSession::setVolume(int volume)
-{
- if (m_volume == volume)
- return;
-
- m_volume = volume;
-
- if (m_QTMovie != 0)
- [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
-
- Q_EMIT volumeChanged(m_volume);
-}
-
-void QT7PlayerSession::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
-
- m_muted = muted;
-
- if (m_QTMovie != 0)
- [(QTMovie*)m_QTMovie setMuted:m_muted];
-
- Q_EMIT mutedChanged(muted);
-}
-
-QMediaContent QT7PlayerSession::media() const
-{
- return m_resources;
-}
-
-const QIODevice *QT7PlayerSession::mediaStream() const
-{
- return m_mediaStream;
-}
-
-void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << content.canonicalUrl();
-#endif
-
- if (m_QTMovie) {
- [(QTMovieObserver*)m_movieObserver setMovie:nil];
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- [(QTMovie*)m_QTMovie release];
- m_QTMovie = 0;
- m_resourceHandler.clear();
- }
-
- m_resources = content;
- m_mediaStream = stream;
- QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
-
- if (content.isNull()) {
- 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;
- }
-
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- if (m_mediaStatus != oldMediaStatus)
- Q_EMIT mediaStatusChanged(m_mediaStatus);
-
- QNetworkRequest request = content.canonicalResource().request();
-
- QVariant cookies = request.header(QNetworkRequest::CookieHeader);
- if (cookies.isValid()) {
- NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- QList<QNetworkCookie> cookieList = cookies.value<QList<QNetworkCookie> >();
-
- Q_FOREACH (const QNetworkCookie &requestCookie, cookieList) {
- NSMutableDictionary *p = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- qString2CFStringRef(requestCookie.name()), NSHTTPCookieName,
- qString2CFStringRef(requestCookie.value()), NSHTTPCookieValue,
- qString2CFStringRef(requestCookie.domain()), NSHTTPCookieDomain,
- qString2CFStringRef(requestCookie.path()), NSHTTPCookiePath,
- nil
- ];
- if (requestCookie.isSessionCookie())
- [p setObject:[NSString stringWithUTF8String:"TRUE"] forKey:NSHTTPCookieDiscard];
- else
- [p setObject:[NSDate dateWithTimeIntervalSince1970:requestCookie.expirationDate().toTime_t()] forKey:NSHTTPCookieExpires];
-
- [store setCookie:[NSHTTPCookie cookieWithProperties:p]];
- }
- }
-
- // Attempt multiple times to open the movie.
- // First try - attempt open in async mode
- openMovie(true);
-
- Q_EMIT positionChanged(position());
-}
-
-void QT7PlayerSession::openMovie(bool tryAsync)
-{
- QUrl requestUrl = m_resources.canonicalResource().request().url();
- if (requestUrl.scheme().isEmpty())
- requestUrl.setScheme(QLatin1String("file"));
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << requestUrl;
-#endif
-
- NSError *err = 0;
- NSString *urlString = [NSString stringWithUTF8String:requestUrl.toEncoded().constData()];
-
- NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute,
- [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute,
- [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute,
- [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute,
- nil];
-
-
- if (requestUrl.scheme() == QLatin1String("qrc")) {
- // Load from Qt resource
- m_resourceHandler.setResourceFile(QLatin1Char(':') + requestUrl.path());
- if (!m_resourceHandler.isValid()) {
- Q_EMIT error(QMediaPlayer::FormatError, tr("Attempting to play invalid Qt resource"));
- return;
- }
-
- CFDataRef resourceData =
- CFDataCreateWithBytesNoCopy(0, m_resourceHandler.data(), m_resourceHandler.size(), kCFAllocatorNull);
-
- QTDataReference *dataReference =
- [QTDataReference dataReferenceWithReferenceToData:(NSData*)resourceData
- name:qString2CFStringRef(requestUrl.path())
- MIMEType:nil];
-
- [attr setObject:dataReference forKey:QTMovieDataReferenceAttribute];
-
- CFRelease(resourceData);
- } else {
- [attr setObject:[NSURL URLWithString:urlString] forKey:QTMovieURLAttribute];
- }
-
- if (tryAsync && QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
- [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenAsyncRequiredAttribute"];
-// XXX: This is disabled for now. causes some problems with video playback for some formats
-// [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
- m_tryingAsync = true;
- }
- else
- m_tryingAsync = false;
-
- m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
- if (err != nil) {
- // First attempt to test for inability to perform async
-// if ([err code] == QTErrorMovieOpeningCannotBeAsynchronous) { XXX: error code unknown!
- if (m_tryingAsync) {
- m_tryingAsync = false;
- err = nil;
- [attr removeObjectForKey:@"QTMovieOpenAsyncRequiredAttribute"];
- m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
- }
- }
-
- if (err != nil) {
- m_QTMovie = 0;
- QString description = QString::fromUtf8([[err localizedDescription] UTF8String]);
- Q_EMIT error(QMediaPlayer::FormatError, description);
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << description;
-#endif
- }
- else {
- [(QTMovie*)m_QTMovie retain];
-
- [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
-
- if (m_state != QMediaPlayer::StoppedState && m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- processLoadStateChange();
-
- [(QTMovie*)m_QTMovie setMuted:m_muted];
- [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
- }
-}
-
-bool QT7PlayerSession::isAudioAvailable() const
-{
- if (!m_QTMovie)
- return false;
-
- AutoReleasePool pool;
- return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES;
-}
-
-bool QT7PlayerSession::isVideoAvailable() const
-{
- if (!m_QTMovie)
- return false;
-
- AutoReleasePool pool;
- return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES;
-}
-
-void QT7PlayerSession::processEOS()
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO;
-#endif
- Q_EMIT positionChanged(position());
- m_mediaStatus = QMediaPlayer::EndOfMedia;
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
- Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
- Q_EMIT mediaStatusChanged(m_mediaStatus);
-}
-
-void QT7PlayerSession::processLoadStateChange()
-{
- if (!m_QTMovie)
- return;
-
- AutoReleasePool pool;
-
- long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] longValue];
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << state;
-#endif
-
-#ifndef QUICKTIME_C_API_AVAILABLE
- enum {
- kMovieLoadStateError = -1L,
- kMovieLoadStateLoading = 1000,
- kMovieLoadStateLoaded = 2000,
- kMovieLoadStatePlayable = 10000,
- kMovieLoadStatePlaythroughOK = 20000,
- kMovieLoadStateComplete = 100000
- };
-#endif
-
- if (state == kMovieLoadStateError) {
- if (m_tryingAsync) {
- NSError *error = [(QTMovie*)m_QTMovie attributeForKey:@"QTMovieLoadStateErrorAttribute"];
- if ([error code] == componentNotThreadSafeErr) {
- // Last Async check, try again with no such flag
- openMovie(false);
- }
- }
- else {
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- 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;
- }
-
- QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
- bool isPlaying = (m_state != QMediaPlayer::StoppedState);
-
- if (state >= kMovieLoadStatePlaythroughOK) {
- newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
- } else if (state >= kMovieLoadStatePlayable)
- newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia;
- else if (state >= kMovieLoadStateLoading) {
- if (!isPlaying)
- newStatus = QMediaPlayer::LoadingMedia;
- else if (m_mediaStatus >= QMediaPlayer::LoadedMedia)
- newStatus = QMediaPlayer::StalledMedia;
- else
- newStatus = QMediaPlayer::LoadingMedia;
- }
-
- if (state >= kMovieLoadStatePlayable &&
- m_state == QMediaPlayer::PlayingState &&
- [(QTMovie*)m_QTMovie rate] == 0) {
-
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
-
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
- }
-
- if (state >= kMovieLoadStateLoaded) {
- 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);
- }
-
- if (newStatus != m_mediaStatus)
- Q_EMIT mediaStatusChanged(m_mediaStatus = newStatus);
-}
-
-void QT7PlayerSession::processVolumeChange()
-{
- if (!m_QTMovie)
- return;
-
- int newVolume = qRound(100.0f * [((QTMovie*)m_QTMovie) volume]);
-
- if (newVolume != m_volume) {
- Q_EMIT volumeChanged(m_volume = newVolume);
- }
-}
-
-void QT7PlayerSession::processNaturalSizeChange()
-{
- AutoReleasePool pool;
- NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << QSize(size.width, size.height);
-#endif
-
- if (m_videoOutput)
- m_videoOutput->updateNaturalSize(QSize(size.width, size.height));
-}
-
-void QT7PlayerSession::processPositionChange()
-{
- Q_EMIT positionChanged(position());
-}
-
-#include "moc_qt7playersession.cpp"
diff --git a/src/plugins/qt7/qcvdisplaylink.h b/src/plugins/qt7/qcvdisplaylink.h
deleted file mode 100644
index ec24a0aa9..000000000
--- a/src/plugins/qt7/qcvdisplaylink.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCVDISPLAYLINK_H
-#define QCVDISPLAYLINK_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qtmultimediadefs.h>
-
-#include <QuartzCore/CVDisplayLink.h>
-
-QT_BEGIN_NAMESPACE
-
-class QCvDisplayLink : public QObject
-{
-Q_OBJECT
-public:
- QCvDisplayLink(QObject *parent = 0);
- virtual ~QCvDisplayLink();
-
- bool isValid();
- 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
-
diff --git a/src/plugins/qt7/qcvdisplaylink.mm b/src/plugins/qt7/qcvdisplaylink.mm
deleted file mode 100644
index 890955492..000000000
--- a/src/plugins/qt7/qcvdisplaylink.mm
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 "qcvdisplaylink.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-
-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);
-
- QCvDisplayLink *link = (QCvDisplayLink *)displayLinkContext;
-
- link->displayLinkEvent(inOutputTime);
- return kCVReturnSuccess;
-}
-
-
-QCvDisplayLink::QCvDisplayLink(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);
- }
-}
-
-QCvDisplayLink::~QCvDisplayLink()
-{
- if (m_displayLink) {
- CVDisplayLinkStop(m_displayLink);
- CVDisplayLinkRelease(m_displayLink);
- m_displayLink = NULL;
- }
-}
-
-bool QCvDisplayLink::isValid()
-{
- return m_displayLink != 0;
-}
-
-bool QCvDisplayLink::isActive() const
-{
- return m_isActive;
-}
-
-void QCvDisplayLink::start()
-{
- if (m_displayLink && !m_isActive) {
- CVDisplayLinkStart(m_displayLink);
- m_isActive = true;
- }
-}
-
-void QCvDisplayLink::stop()
-{
- if (m_displayLink && m_isActive) {
- CVDisplayLinkStop(m_displayLink);
- m_isActive = false;
- }
-}
-
-void QCvDisplayLink::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 QCvDisplayLink::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);
-}
-
-#include "moc_qcvdisplaylink.cpp"
-
diff --git a/src/plugins/qt7/qt7.json b/src/plugins/qt7/qt7.json
deleted file mode 100644
index b4cebad99..000000000
--- a/src/plugins/qt7/qt7.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Keys": ["qt7"],
- "Services": ["org.qt-project.qt.mediaplayer"]
-}
diff --git a/src/plugins/qt7/qt7.pro b/src/plugins/qt7/qt7.pro
deleted file mode 100644
index b23eba40a..000000000
--- a/src/plugins/qt7/qt7.pro
+++ /dev/null
@@ -1,67 +0,0 @@
-# Avoid clash with a variable named `slots' in a Quartz header
-CONFIG += no_keywords
-
-TARGET = qqt7engine
-QT += multimedia-private network
-qtHaveModule(widgets) {
- QT += multimediawidgets-private widgets
-}
-
-PLUGIN_TYPE = mediaservice
-PLUGIN_CLASS_NAME = QT7ServicePlugin
-load(qt_plugin)
-
-!simulator {
-QT += opengl
-}
-
-#DEFINES += QT_DEBUG_QT7
-
-LIBS += -framework AppKit -framework AudioUnit \
- -framework AudioToolbox -framework CoreAudio \
- -framework QuartzCore -framework QTKit
-
-# QUICKTIME_C_API_AVAILABLE is true only on i386
-# so make sure to link QuickTime
-contains(QT_ARCH, i386) {
- LIBS += -framework QuickTime
-}
-
-HEADERS += \
- qt7backend.h \
- qt7videooutput.h \
- qt7serviceplugin.h
-
-OBJECTIVE_SOURCES += \
- qt7backend.mm \
- qt7serviceplugin.mm
-
-!simulator {
- HEADERS += \
- qt7movieviewoutput.h \
- qt7movierenderer.h \
- qt7ciimagevideobuffer.h \
- qcvdisplaylink.h
-
- OBJECTIVE_SOURCES += \
- qt7movieviewoutput.mm \
- qt7movierenderer.mm \
- qt7videooutput.mm \
- qt7ciimagevideobuffer.mm \
- qcvdisplaylink.mm
-
- qtHaveModule(widgets) {
- HEADERS += \
- qt7movieviewrenderer.h \
- qt7movievideowidget.h
-
- OBJECTIVE_SOURCES += \
- qt7movieviewrenderer.mm \
- qt7movievideowidget.mm
- }
-}
-
-include(mediaplayer/mediaplayer.pri)
-
-OTHER_FILES += \
- qt7.json
diff --git a/src/plugins/qt7/qt7backend.h b/src/plugins/qt7/qt7backend.h
deleted file mode 100644
index e2aa2c5d8..000000000
--- a/src/plugins/qt7/qt7backend.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7BACKEND_H
-#define QT7BACKEND_H
-
-#include "qtmultimediadefs.h"
-
-#include <QtCore/QString>
-
-#ifndef Q_OS_SIMULATOR
-#ifndef Q_OS_MAC64
-#define QUICKTIME_C_API_AVAILABLE
-#endif
-#endif // !defined(Q_WS_SIMULATOR)
-
-QT_BEGIN_NAMESPACE
-
-class AutoReleasePool
-{
-private:
- void *pool;
-public:
- AutoReleasePool();
- ~AutoReleasePool();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7ciimagevideobuffer.h b/src/plugins/qt7/qt7ciimagevideobuffer.h
deleted file mode 100644
index 2ad7957c3..000000000
--- a/src/plugins/qt7/qt7ciimagevideobuffer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7CIIMAGEVIDEOBUFFER_H
-#define QT7CIIMAGEVIDEOBUFFER_H
-
-#include "qt7backend.h"
-#import <QTKit/QTKit.h>
-
-#include <QtCore/qvariant.h>
-#include <qabstractvideobuffer.h>
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-class QT7CIImageVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- QT7CIImageVideoBuffer(CIImage *image);
-
- virtual ~QT7CIImageVideoBuffer();
-
- MapMode mapMode() const;
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
- void unmap();
- QVariant handle() const;
-
-private:
- CIImage *m_image;
- NSBitmapImageRep *m_buffer;
- MapMode m_mode;
-};
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7ciimagevideobuffer.mm b/src/plugins/qt7/qt7ciimagevideobuffer.mm
deleted file mode 100644
index adb1a689d..000000000
--- a/src/plugins/qt7/qt7ciimagevideobuffer.mm
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 "qt7ciimagevideobuffer.h"
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT7CIImageVideoBuffer::QT7CIImageVideoBuffer(CIImage *image)
- : QAbstractVideoBuffer(CoreImageHandle)
- , m_image(image)
- , m_buffer(0)
- , m_mode(NotMapped)
-{
- [m_image retain];
-}
-
-QT7CIImageVideoBuffer::~QT7CIImageVideoBuffer()
-{
- [m_image release];
- [m_buffer release];
-}
-
-QAbstractVideoBuffer::MapMode QT7CIImageVideoBuffer::mapMode() const
-{
- return m_mode;
-}
-
-uchar *QT7CIImageVideoBuffer::map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int *bytesPerLine)
-{
- if (mode == NotMapped || m_mode != NotMapped || !m_image)
- return 0;
-
- if (!m_buffer) {
- //swap R and B channels
- CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues:
- @"inputImage", m_image,
- @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0],
- @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0],
- @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0],
- @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1],
- @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0],
- nil];
- CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
-
- m_buffer = [[NSBitmapImageRep alloc] initWithCIImage:img];
- }
-
- if (numBytes)
- *numBytes = [m_buffer bytesPerPlane];
-
- if (bytesPerLine)
- *bytesPerLine = [m_buffer bytesPerRow];
-
- m_mode = mode;
-
- return [m_buffer bitmapData];
-}
-
-void QT7CIImageVideoBuffer::unmap()
-{
- m_mode = NotMapped;
-}
-
-QVariant QT7CIImageVideoBuffer::handle() const
-{
- return QVariant::fromValue<void*>(m_image);
-}
-
diff --git a/src/plugins/qt7/qt7movierenderer.h b/src/plugins/qt7/qt7movierenderer.h
deleted file mode 100644
index 8abbaf847..000000000
--- a/src/plugins/qt7/qt7movierenderer.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIERENDERER_H
-#define QT7MOVIERENDERER_H
-
-#include "qt7backend.h"
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideorenderercontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-#include <QuartzCore/CVOpenGLTexture.h>
-#include <QuickTime/QuickTime.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLContext;
-
-class QCvDisplayLink;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieRenderer : public QT7VideoRendererControl
-{
-Q_OBJECT
-public:
- QT7MovieRenderer(QObject *parent = 0);
- virtual ~QT7MovieRenderer();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
-
- QSize nativeSize() const;
-
-private Q_SLOTS:
- void updateVideoFrame(const CVTimeStamp &ts);
-
-private:
- void setupVideoOutput();
- bool createPixelBufferVisualContext();
- bool createGLVisualContext();
-
- void *m_movie;
-
- QMutex m_mutex;
-
- QCvDisplayLink *m_displayLink;
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTVisualContextRef m_visualContext;
- bool m_usingGLContext;
- const QGLContext *m_currentGLContext;
- QSize m_pixelBufferContextGeometry;
-#endif
- QAbstractVideoSurface *m_surface;
- QSize m_nativeSize;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movierenderer.mm b/src/plugins/qt7/qt7movierenderer.mm
deleted file mode 100644
index 9110b821e..000000000
--- a/src/plugins/qt7/qt7movierenderer.mm
+++ /dev/null
@@ -1,481 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movierenderer.h"
-#include "qt7playersession.h"
-#include "qt7ciimagevideobuffer.h"
-#include "qcvdisplaylink.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <qabstractvideobuffer.h>
-#include <qabstractvideosurface.h>
-#include <qvideosurfaceformat.h>
-
-#include <QtOpenGL/QGLContext>
-
-QT_USE_NAMESPACE
-
-//#define USE_MAIN_MONITOR_COLOR_SPACE 1
-
-class CVGLTextureVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- CVGLTextureVideoBuffer(CVOpenGLTextureRef buffer)
- : QAbstractVideoBuffer(GLTextureHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- CVOpenGLTextureRetain(m_buffer);
- }
-
- virtual ~CVGLTextureVideoBuffer()
- {
- CVOpenGLTextureRelease(m_buffer);
- }
-
- QVariant handle() const
- {
- GLuint id = CVOpenGLTextureGetName(m_buffer);
- return QVariant(int(id));
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (numBytes)
- *numBytes = 0;
-
- if (bytesPerLine)
- *bytesPerLine = 0;
-
- m_mode = mode;
- return 0;
- }
-
- void unmap() { m_mode = NotMapped; }
-
-private:
- CVOpenGLTextureRef m_buffer;
- MapMode m_mode;
-};
-
-
-class CVPixelBufferVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- CVPixelBufferVideoBuffer(CVPixelBufferRef buffer)
- : QAbstractVideoBuffer(NoHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- CVPixelBufferRetain(m_buffer);
- }
-
- virtual ~CVPixelBufferVideoBuffer()
- {
- CVPixelBufferRelease(m_buffer);
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (mode != NotMapped && m_mode == NotMapped) {
- CVPixelBufferLockBaseAddress(m_buffer, 0);
-
- if (numBytes)
- *numBytes = CVPixelBufferGetDataSize(m_buffer);
-
- if (bytesPerLine)
- *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer);
-
- m_mode = mode;
-
- return (uchar*)CVPixelBufferGetBaseAddress(m_buffer);
- } else {
- return 0;
- }
- }
-
- void unmap()
- {
- if (m_mode != NotMapped) {
- m_mode = NotMapped;
- CVPixelBufferUnlockBaseAddress(m_buffer, 0);
- }
- }
-
-private:
- CVPixelBufferRef m_buffer;
- MapMode m_mode;
-};
-
-
-
-QT7MovieRenderer::QT7MovieRenderer(QObject *parent)
- :QT7VideoRendererControl(parent),
- m_movie(0),
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_visualContext(0),
- m_usingGLContext(false),
- m_currentGLContext(0),
-#endif
- m_surface(0)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer";
-#endif
- m_displayLink = new QCvDisplayLink(this);
- connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
-}
-
-
-bool QT7MovieRenderer::createGLVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- CGLContextObj cglContext = CGLGetCurrentContext();
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, cglContext,
- cglPixelFormat, NULL, &m_visualContext);
- if (err != noErr)
- qWarning() << "Could not create visual context (OpenGL)";
-
- return (err == noErr);
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-static bool DictionarySetValue(CFMutableDictionaryRef dict, CFStringRef key, SInt32 value)
-{
- CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- if (number) {
- CFDictionarySetValue( dict, key, number );
- CFRelease( number );
- return true;
- }
- return false;
-}
-#endif // QUICKTIME_C_API_AVAILABLE
-
-bool QT7MovieRenderer::createPixelBufferVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- if (m_visualContext) {
- QTVisualContextRelease(m_visualContext);
- m_visualContext = 0;
- }
-
- m_pixelBufferContextGeometry = m_nativeSize;
-
- CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- //DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32ARGBPixelFormat );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferWidthKey, m_nativeSize.width() );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferHeightKey, m_nativeSize.height() );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferBytesPerRowAlignmentKey, 16);
- //CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
-
- CFMutableDictionaryRef visualContextOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(visualContextOptions, kQTVisualContextPixelBufferAttributesKey, pixelBufferOptions);
-
- CGColorSpaceRef colorSpace = NULL;
-
-#if USE_MAIN_MONITOR_COLOR_SPACE
- CMProfileRef sysprof = NULL;
-
- // Get the Systems Profile for the main display
- if (CMGetSystemProfile(&sysprof) == noErr) {
- // Create a colorspace with the systems profile
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);
- CMCloseProfile(sysprof);
- }
-#endif
-
- if (!colorSpace)
- colorSpace = CGColorSpaceCreateDeviceRGB();
-
- CFDictionarySetValue(visualContextOptions, kQTVisualContextOutputColorSpaceKey, colorSpace);
-
- OSStatus err = QTPixelBufferContextCreate(kCFAllocatorDefault,
- visualContextOptions,
- &m_visualContext);
- CFRelease(pixelBufferOptions);
- CFRelease(visualContextOptions);
-
- if (err != noErr) {
- qWarning() << "Could not create visual context (PixelBuffer)";
- return false;
- }
-
- return true;
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-
-QT7MovieRenderer::~QT7MovieRenderer()
-{
- m_displayLink->stop();
-}
-
-void QT7MovieRenderer::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer::setupVideoOutput" << m_movie;
-#endif
-
- if (m_movie == 0 || m_surface == 0) {
- m_displayLink->stop();
- return;
- }
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- bool usedGLContext = m_usingGLContext;
-
- if (!m_nativeSize.isEmpty()) {
-
- bool glSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
-
- //Try rendering using opengl textures first:
- if (glSupported) {
- QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle);
-
- if (m_surface->isActive())
- m_surface->stop();
-
- if (!m_surface->start(format)) {
- qWarning() << "failed to start video surface" << m_surface->error();
- qWarning() << "Surface format:" << format;
- glSupported = false;
- } else {
- m_usingGLContext = true;
- }
-
- }
-
- if (!glSupported) {
- m_usingGLContext = false;
- QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
-
- if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Surface format was changed, stop the surface.";
-#endif
- m_surface->stop();
- }
-
- if (!m_surface->isActive()) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Starting the surface with format" << format;
-#endif
- if (!m_surface->start(format)) {
- qWarning() << "failed to start video surface" << m_surface->error();
- qWarning() << "Surface format:" << format;
- }
- }
- }
- }
-
-
- if (m_visualContext) {
- //check if the visual context still can be reused
- if (usedGLContext != m_usingGLContext ||
- (m_usingGLContext && (m_currentGLContext != QGLContext::currentContext())) ||
- (!m_usingGLContext && (m_pixelBufferContextGeometry != m_nativeSize))) {
- QTVisualContextRelease(m_visualContext);
- m_pixelBufferContextGeometry = QSize();
- m_visualContext = 0;
- }
- }
-
- if (!m_nativeSize.isEmpty()) {
- if (!m_visualContext) {
- if (m_usingGLContext) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Building OpenGL visual context" << m_nativeSize;
-#endif
- m_currentGLContext = QGLContext::currentContext();
- if (!createGLVisualContext()) {
- qWarning() << "QT7MovieRenderer: failed to create visual context";
- return;
- }
- } else {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Building Pixel Buffer visual context" << m_nativeSize;
-#endif
- if (!createPixelBufferVisualContext()) {
- qWarning() << "QT7MovieRenderer: failed to create visual context";
- return;
- }
- }
- }
-
- // targets a Movie to render into a visual context
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
-
- m_displayLink->start();
- }
-#endif
-
-}
-
-void QT7MovieRenderer::setMovie(void *movie)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer::setMovie" << movie;
-#endif
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QMutexLocker locker(&m_mutex);
-
- if (m_movie != movie) {
- if (m_movie) {
- //ensure the old movie doesn't hold the visual context, otherwise it can't be reused
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
- }
-#else
- Q_UNUSED(movie);
-#endif
-}
-
-void QT7MovieRenderer::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-QAbstractVideoSurface *QT7MovieRenderer::surface() const
-{
- return m_surface;
-}
-
-void QT7MovieRenderer::setSurface(QAbstractVideoSurface *surface)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "Set video surface" << surface;
-#endif
-
- if (surface == m_surface)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive())
- m_surface->stop();
-
- m_surface = surface;
- setupVideoOutput();
-}
-
-
-QSize QT7MovieRenderer::nativeSize() const
-{
- return m_nativeSize;
-}
-
-void QT7MovieRenderer::updateVideoFrame(const CVTimeStamp &ts)
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive() &&
- m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
-
- CVImageBufferRef imageBuffer = NULL;
-
- OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &imageBuffer);
-
- if (status == noErr && imageBuffer) {
- QAbstractVideoBuffer *buffer = 0;
-
- if (m_usingGLContext) {
- buffer = new QT7CIImageVideoBuffer([CIImage imageWithCVImageBuffer:imageBuffer]);
- CVOpenGLTextureRelease((CVOpenGLTextureRef)imageBuffer);
- } else {
- buffer = new CVPixelBufferVideoBuffer((CVPixelBufferRef)imageBuffer);
- //buffer = new QT7CIImageVideoBuffer( [CIImage imageWithCVImageBuffer:imageBuffer] );
- CVPixelBufferRelease((CVPixelBufferRef)imageBuffer);
- }
-
- QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_RGB32);
- m_surface->present(frame);
- QTVisualContextTask(m_visualContext);
- }
- }
-#else
- Q_UNUSED(ts);
-#endif
-}
-
-#include "moc_qt7movierenderer.cpp"
diff --git a/src/plugins/qt7/qt7movievideowidget.h b/src/plugins/qt7/qt7movievideowidget.h
deleted file mode 100644
index 655037698..000000000
--- a/src/plugins/qt7/qt7movievideowidget.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIDEOWIDGET_H
-#define QT7MOVIEVIDEOWIDGET_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-#include <QuartzCore/CVOpenGLTexture.h>
-#include <QuickTime/QuickTime.h>
-
-class GLVideoWidget;
-
-QT_BEGIN_NAMESPACE
-
-class QCvDisplayLink;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieVideoWidget : public QT7VideoWidgetControl
-{
-Q_OBJECT
-public:
- QT7MovieVideoWidget(QObject *parent = 0);
- virtual ~QT7MovieVideoWidget();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QWidget *videoWidget();
-
- bool isFullScreen() const;
- void setFullScreen(bool fullScreen);
-
- QSize nativeSize() const;
-
- 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();
- bool createVisualContext();
-
- void updateColors();
-
- void *m_movie;
- GLVideoWidget *m_videoWidget;
-
- QCvDisplayLink *m_displayLink;
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTVisualContextRef m_visualContext;
-#endif
-
- bool m_fullscreen;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
- int m_brightness;
- int m_contrast;
- int m_hue;
- int m_saturation;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movievideowidget.mm b/src/plugins/qt7/qt7movievideowidget.mm
deleted file mode 100644
index ec9367bcc..000000000
--- a/src/plugins/qt7/qt7movievideowidget.mm
+++ /dev/null
@@ -1,437 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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 "qt7backend.h"
-
-#import <QTKit/QTDataReference.h>
-#import <QTKit/QTMovie.h>
-#import <QTKit/QTMovieView.h>
-#import <QTKit/QTMovieLayer.h>
-#import <AppKit/NSImage.h>
-#import <OpenGL/glu.h>
-
-
-#include "qt7playercontrol.h"
-#include "qt7movievideowidget.h"
-#include "qt7playersession.h"
-#include "qcvdisplaylink.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <QGLWidget>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#import <QuartzCore/QuartzCore.h>
-
-#include "math.h"
-
-QT_USE_NAMESPACE
-
-class GLVideoWidget : public QGLWidget
-{
-public:
-
- GLVideoWidget(QWidget *parent, const QGLFormat &format)
- : QGLWidget(format, parent),
- m_texRef(0),
- m_nativeSize(640,480),
- m_aspectRatioMode(Qt::KeepAspectRatio)
- {
- setAutoFillBackground(false);
- }
-
- void initializeGL()
- {
- QColor bgColor = palette().color(QPalette::Background);
- glClearColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF(), bgColor.alphaF());
- }
-
- void resizeGL(int w, int h)
- {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glViewport(0, 0, GLsizei(w), GLsizei(h));
- gluOrtho2D(0, GLsizei(w), 0, GLsizei(h));
- updateGL();
- }
-
- void paintGL()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- if (!m_texRef)
- return;
-
- glPushMatrix();
- glDisable(GL_CULL_FACE);
- GLenum target = CVOpenGLTextureGetTarget(m_texRef);
- glEnable(target);
-
- glBindTexture(target, CVOpenGLTextureGetName(m_texRef));
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- GLfloat lowerLeft[2], lowerRight[2], upperRight[2], upperLeft[2];
- CVOpenGLTextureGetCleanTexCoords(m_texRef, lowerLeft, lowerRight, upperRight, upperLeft);
-
- glBegin(GL_QUADS);
- QRect rect = displayRect();
- glTexCoord2f(lowerLeft[0], lowerLeft[1]);
- glVertex2i(rect.topLeft().x(), rect.topLeft().y());
- glTexCoord2f(lowerRight[0], lowerRight[1]);
- glVertex2i(rect.topRight().x() + 1, rect.topRight().y());
- glTexCoord2f(upperRight[0], upperRight[1]);
- glVertex2i(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
- glTexCoord2f(upperLeft[0], upperLeft[1]);
- glVertex2i(rect.bottomLeft().x(), rect.bottomLeft().y() + 1);
- glEnd();
- glPopMatrix();
- }
-
- void setCVTexture(CVOpenGLTextureRef texRef)
- {
- if (m_texRef)
- CVOpenGLTextureRelease(m_texRef);
-
- m_texRef = texRef;
-
- if (m_texRef)
- CVOpenGLTextureRetain(m_texRef);
-
- if (isVisible()) {
- makeCurrent();
- paintGL();
- swapBuffers();
- }
- }
-
- QSize sizeHint() const
- {
- return m_nativeSize;
- }
-
- void setNativeSize(const QSize &size)
- {
- m_nativeSize = size;
- }
-
- void setAspectRatioMode(Qt::AspectRatioMode mode)
- {
- if (m_aspectRatioMode != mode) {
- m_aspectRatioMode = mode;
- update();
- }
- }
-
-private:
- QRect 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;
- }
-
- CVOpenGLTextureRef m_texRef;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
-};
-
-QT7MovieVideoWidget::QT7MovieVideoWidget(QObject *parent)
- :QT7VideoWidgetControl(parent),
- m_movie(0),
- m_videoWidget(0),
- m_fullscreen(false),
- m_aspectRatioMode(Qt::KeepAspectRatio),
- m_brightness(0),
- m_contrast(0),
- m_hue(0),
- m_saturation(0)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieVideoWidget";
-#endif
-
- QGLFormat format = QGLFormat::defaultFormat();
- format.setSwapInterval(1); // Vertical sync (avoid tearing)
- m_videoWidget = new GLVideoWidget(0, format);
-
- m_displayLink = new QCvDisplayLink(this);
-
- connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
-
- if (!createVisualContext()) {
- qWarning() << "QT7MovieVideoWidget: failed to create visual context";
- }
-}
-
-bool QT7MovieVideoWidget::createVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_videoWidget->makeCurrent();
-
- AutoReleasePool pool;
- CGLContextObj cglContext = CGLGetCurrentContext();
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- CFTypeRef keys[] = { kQTVisualContextOutputColorSpaceKey };
- CGColorSpaceRef colorSpace = NULL;
- CMProfileRef sysprof = NULL;
-
- // Get the Systems Profile for the main display
- if (CMGetSystemProfile(&sysprof) == noErr) {
- // Create a colorspace with the systems profile
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);
- CMCloseProfile(sysprof);
- }
-
- if (!colorSpace)
- colorSpace = CGColorSpaceCreateDeviceRGB();
-
- CFDictionaryRef textureContextAttributes = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **)keys,
- (const void **)&colorSpace, 1,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault,
- cglContext,
- cglPixelFormat,
- textureContextAttributes,
- &m_visualContext);
- if (err != noErr)
- qWarning() << "Could not create visual context (OpenGL)";
-
-
- return (err == noErr);
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-QT7MovieVideoWidget::~QT7MovieVideoWidget()
-{
- m_displayLink->stop();
- [(QTMovie*)m_movie release];
- delete m_videoWidget;
-}
-
-QWidget *QT7MovieVideoWidget::videoWidget()
-{
- return m_videoWidget;
-}
-
-void QT7MovieVideoWidget::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieVideoWidget::setupVideoOutput" << m_movie;
-#endif
-
- if (m_movie == 0) {
- m_displayLink->stop();
- return;
- }
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
- m_videoWidget->setNativeSize(m_nativeSize);
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- // targets a Movie to render into a visual context
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
-#endif
-
- m_displayLink->start();
-}
-
-void QT7MovieVideoWidget::setMovie(void *movie)
-{
- if (m_movie == movie)
- return;
-
- if (m_movie) {
-#ifdef QUICKTIME_C_API_AVAILABLE
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
-#endif
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
-}
-
-void QT7MovieVideoWidget::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-bool QT7MovieVideoWidget::isFullScreen() const
-{
- return m_fullscreen;
-}
-
-void QT7MovieVideoWidget::setFullScreen(bool fullScreen)
-{
- m_fullscreen = fullScreen;
-}
-
-QSize QT7MovieVideoWidget::nativeSize() const
-{
- return m_nativeSize;
-}
-
-Qt::AspectRatioMode QT7MovieVideoWidget::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void QT7MovieVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
- m_videoWidget->setAspectRatioMode(mode);
-}
-
-int QT7MovieVideoWidget::brightness() const
-{
- return m_brightness;
-}
-
-void QT7MovieVideoWidget::setBrightness(int brightness)
-{
- m_brightness = brightness;
- updateColors();
-}
-
-int QT7MovieVideoWidget::contrast() const
-{
- return m_contrast;
-}
-
-void QT7MovieVideoWidget::setContrast(int contrast)
-{
- m_contrast = contrast;
- updateColors();
-}
-
-int QT7MovieVideoWidget::hue() const
-{
- return m_hue;
-}
-
-void QT7MovieVideoWidget::setHue(int hue)
-{
- m_hue = hue;
- updateColors();
-}
-
-int QT7MovieVideoWidget::saturation() const
-{
- return m_saturation;
-}
-
-void QT7MovieVideoWidget::setSaturation(int saturation)
-{
- m_saturation = saturation;
- updateColors();
-}
-
-void QT7MovieVideoWidget::updateColors()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- if (m_movie) {
- QTMovie *movie = (QTMovie*)m_movie;
-
- Float32 value;
- value = m_brightness/100.0;
- SetMovieVisualBrightness([movie quickTimeMovie], value, 0);
- value = pow(2, m_contrast/50.0);
- SetMovieVisualContrast([movie quickTimeMovie], value, 0);
- value = m_hue/100.0;
- SetMovieVisualHue([movie quickTimeMovie], value, 0);
- value = 1.0+m_saturation/100.0;
- SetMovieVisualSaturation([movie quickTimeMovie], value, 0);
- }
-#endif
-}
-
-void QT7MovieVideoWidget::updateVideoFrame(const CVTimeStamp &ts)
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- // check for new frame
- if (m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
- CVOpenGLTextureRef currentFrame = NULL;
-
- // get a "frame" (image buffer) from the Visual Context, indexed by the provided time
- OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &currentFrame);
-
- // the above call may produce a null frame so check for this first
- // if we have a frame, then draw it
- if (status == noErr && currentFrame) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "render video frame";
-#endif
- m_videoWidget->setCVTexture(currentFrame);
- CVOpenGLTextureRelease(currentFrame);
- }
- QTVisualContextTask(m_visualContext);
- }
-#else
- Q_UNUSED(ts);
-#endif
-}
-
-#include "moc_qt7movievideowidget.cpp"
diff --git a/src/plugins/qt7/qt7movieviewoutput.h b/src/plugins/qt7/qt7movieviewoutput.h
deleted file mode 100644
index 874de1a09..000000000
--- a/src/plugins/qt7/qt7movieviewoutput.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIEWOUTPUT_H
-#define QT7MOVIEVIEWOUTPUT_H
-
-#include <QtCore/qobject.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieViewOutput : public QT7VideoWindowControl
-{
-public:
- QT7MovieViewOutput(QObject *parent = 0);
- ~QT7MovieViewOutput();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- WId winId() const;
- void setWinId(WId id);
-
- QRect displayRect() const;
- void setDisplayRect(const QRect &rect);
-
- bool isFullScreen() const;
- void setFullScreen(bool fullScreen);
-
- void repaint();
-
- QSize nativeSize() const;
-
- 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:
- void setupVideoOutput();
-
- void *m_movie;
- void *m_movieView;
- bool m_layouted;
-
- WId m_winId;
- QRect m_displayRect;
- bool m_fullscreen;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
- int m_brightness;
- int m_contrast;
- int m_hue;
- int m_saturation;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movieviewoutput.mm b/src/plugins/qt7/qt7movieviewoutput.mm
deleted file mode 100644
index 4fcf01d39..000000000
--- a/src/plugins/qt7/qt7movieviewoutput.mm
+++ /dev/null
@@ -1,339 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movieviewoutput.h"
-#include "qt7playersession.h"
-#include <QtCore/qdebug.h>
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT_USE_NAMESPACE
-
-#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
-
-@interface TransparentQTMovieView : QTMovieView
-{
-@private
- QRect *m_drawRect;
- qreal m_brightness, m_contrast, m_saturation, m_hue;
-}
-
-- (TransparentQTMovieView *) init;
-- (void) setDrawRect:(QRect &)rect;
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
-- (void) setContrast:(qreal) contrast;
-@end
-
-@implementation TransparentQTMovieView
-
-- (TransparentQTMovieView *) init
-{
- self = [super initWithFrame:NSZeroRect];
- if (self) {
- [self setControllerVisible:NO];
- [self setContrast:1.0];
- [self setDelegate:self];
- }
- return self;
-}
-
-- (void) dealloc
-{
- [super dealloc];
-}
-
-- (void) setContrast:(qreal) contrast
-{
- m_hue = 0.0;
- m_brightness = 0.0;
- m_contrast = contrast;
- m_saturation = 1.0;
-}
-
-
-- (void) setDrawRect:(QRect &)rect
-{
- *m_drawRect = rect;
-
- NSRect nsrect;
- nsrect.origin.x = m_drawRect->x();
- nsrect.origin.y = m_drawRect->y();
- nsrect.size.width = m_drawRect->width();
- nsrect.size.height = m_drawRect->height();
- [self setFrame:nsrect];
-}
-
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
-{
- // This method is called from QTMovieView just
- // before the image will be drawn.
- Q_UNUSED(view);
-
- if ( !qFuzzyCompare(m_brightness, 0.0) ||
- !qFuzzyCompare(m_contrast, 1.0) ||
- !qFuzzyCompare(m_saturation, 1.0)){
- CIFilter *colorFilter = [CIFilter filterWithName:@"CIColorControls"];
- [colorFilter setValue:[NSNumber numberWithFloat:m_brightness] forKey:@"inputBrightness"];
- [colorFilter setValue:[NSNumber numberWithFloat:(m_contrast < 1) ? m_contrast : 1 + ((m_contrast-1)*3)] forKey:@"inputContrast"];
- [colorFilter setValue:[NSNumber numberWithFloat:m_saturation] forKey:@"inputSaturation"];
- [colorFilter setValue:img forKey:@"inputImage"];
- img = [colorFilter valueForKey:@"outputImage"];
- }
-
- /*if (m_hue){
- CIFilter *colorFilter = [CIFilter filterWithName:@"CIHueAdjust"];
- [colorFilter setValue:[NSNumber numberWithFloat:(m_hue * 3.14)] forKey:@"inputAngle"];
- [colorFilter setValue:img forKey:@"inputImage"];
- img = [colorFilter valueForKey:@"outputImage"];
- }*/
-
- return img;
-}
-
-
-VIDEO_TRANSPARENT(mouseDown);
-VIDEO_TRANSPARENT(mouseDragged);
-VIDEO_TRANSPARENT(mouseUp);
-VIDEO_TRANSPARENT(mouseMoved);
-VIDEO_TRANSPARENT(mouseEntered);
-VIDEO_TRANSPARENT(mouseExited);
-VIDEO_TRANSPARENT(rightMouseDown);
-VIDEO_TRANSPARENT(rightMouseDragged);
-VIDEO_TRANSPARENT(rightMouseUp);
-VIDEO_TRANSPARENT(otherMouseDown);
-VIDEO_TRANSPARENT(otherMouseDragged);
-VIDEO_TRANSPARENT(otherMouseUp);
-VIDEO_TRANSPARENT(keyDown);
-VIDEO_TRANSPARENT(keyUp);
-VIDEO_TRANSPARENT(scrollWheel)
-
-@end
-
-
-QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent)
- :QT7VideoWindowControl(parent),
- m_movie(0),
- m_movieView(0),
- m_layouted(false),
- m_winId(0),
- m_fullscreen(false),
- m_aspectRatioMode(Qt::KeepAspectRatio),
- m_brightness(0),
- m_contrast(0),
- m_hue(0),
- m_saturation(0)
-{
-}
-
-QT7MovieViewOutput::~QT7MovieViewOutput()
-{
- [(QTMovieView*)m_movieView release];
- [(QTMovie*)m_movie release];
-}
-
-void QT7MovieViewOutput::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieViewOutput::setupVideoOutput" << m_movie << m_winId;
-#endif
- if (m_movie == 0 || m_winId <= 0)
- return;
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
-
- if (!m_movieView)
- m_movieView = [[TransparentQTMovieView alloc] init];
-
- [(QTMovieView*)m_movieView setControllerVisible:NO];
- [(QTMovieView*)m_movieView setMovie:(QTMovie*)m_movie];
-
- [(NSView *)m_winId addSubview:(QTMovieView*)m_movieView];
- m_layouted = true;
-
- setDisplayRect(m_displayRect);
-}
-
-void QT7MovieViewOutput::setMovie(void *movie)
-{
- if (m_movie != movie) {
- if (m_movie) {
- if (m_movieView)
- [(QTMovieView*)m_movieView setMovie:nil];
-
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
-
- if (m_movie)
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
- }
-}
-
-void QT7MovieViewOutput::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- Q_EMIT nativeSizeChanged();
- }
-}
-
-WId QT7MovieViewOutput::winId() const
-{
- return m_winId;
-}
-
-void QT7MovieViewOutput::setWinId(WId id)
-{
- if (m_winId != id) {
- if (m_movieView && m_layouted) {
- [(QTMovieView*)m_movieView removeFromSuperview];
- m_layouted = false;
- }
-
- m_winId = id;
- setupVideoOutput();
- }
-}
-
-QRect QT7MovieViewOutput::displayRect() const
-{
- return m_displayRect;
-}
-
-void QT7MovieViewOutput::setDisplayRect(const QRect &rect)
-{
- m_displayRect = rect;
-
- if (m_movieView) {
- AutoReleasePool pool;
- [(QTMovieView*)m_movieView setPreservesAspectRatio:(m_aspectRatioMode == Qt::KeepAspectRatio ? YES : NO)];
- [(QTMovieView*)m_movieView setFrame:NSMakeRect(m_displayRect.x(),
- m_displayRect.y(),
- m_displayRect.width(),
- m_displayRect.height())];
- }
-
-}
-
-bool QT7MovieViewOutput::isFullScreen() const
-{
- return m_fullscreen;
-}
-
-void QT7MovieViewOutput::setFullScreen(bool fullScreen)
-{
- m_fullscreen = fullScreen;
- setDisplayRect(m_displayRect);
-}
-
-void QT7MovieViewOutput::repaint()
-{
-}
-
-QSize QT7MovieViewOutput::nativeSize() const
-{
- return m_nativeSize;
-}
-
-Qt::AspectRatioMode QT7MovieViewOutput::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void QT7MovieViewOutput::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
- setDisplayRect(m_displayRect);
-}
-
-int QT7MovieViewOutput::brightness() const
-{
- return m_brightness;
-}
-
-void QT7MovieViewOutput::setBrightness(int brightness)
-{
- m_brightness = brightness;
-}
-
-int QT7MovieViewOutput::contrast() const
-{
- return m_contrast;
-}
-
-void QT7MovieViewOutput::setContrast(int contrast)
-{
- m_contrast = contrast;
- [(TransparentQTMovieView*)m_movieView setContrast:(contrast/100.0+1.0)];
-}
-
-int QT7MovieViewOutput::hue() const
-{
- return m_hue;
-}
-
-void QT7MovieViewOutput::setHue(int hue)
-{
- m_hue = hue;
-}
-
-int QT7MovieViewOutput::saturation() const
-{
- return m_saturation;
-}
-
-void QT7MovieViewOutput::setSaturation(int saturation)
-{
- m_saturation = saturation;
-}
-
diff --git a/src/plugins/qt7/qt7movieviewrenderer.h b/src/plugins/qt7/qt7movieviewrenderer.h
deleted file mode 100644
index 2416fe7b3..000000000
--- a/src/plugins/qt7/qt7movieviewrenderer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIEWRENDERER_H
-#define QT7MOVIEVIEWRENDERER_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-#include <qvideoframe.h>
-
-#include <QuartzCore/CIContext.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVideoFrame;
-
-class QT7PlayerSession;
-class QT7PlayerService;
-class QGLWidget;
-class QGLFramebufferObject;
-class QWindow;
-class QOpenGLContext;
-
-class QT7MovieViewRenderer : public QT7VideoRendererControl
-{
-public:
- QT7MovieViewRenderer(QObject *parent = 0);
- ~QT7MovieViewRenderer();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
-
- void renderFrame(const QVideoFrame &);
-
-protected:
- bool event(QEvent *event);
-
-private:
- void setupVideoOutput();
- QVideoFrame convertCIImageToGLTexture(const QVideoFrame &frame);
-
- void *m_movie;
- void *m_movieView;
- QSize m_nativeSize;
- QAbstractVideoSurface *m_surface;
- QVideoFrame m_currentFrame;
- QWindow *m_window;
- QOpenGLContext *m_context;
- QGLFramebufferObject *m_fbo;
- CIContext *m_ciContext;
-
- bool m_pendingRenderEvent;
- QMutex m_mutex;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movieviewrenderer.mm b/src/plugins/qt7/qt7movieviewrenderer.mm
deleted file mode 100644
index a59031577..000000000
--- a/src/plugins/qt7/qt7movieviewrenderer.mm
+++ /dev/null
@@ -1,509 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 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$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movieviewrenderer.h"
-#include "qt7playersession.h"
-#include "qt7ciimagevideobuffer.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/qwindow.h>
-#include <QtGui/qopenglcontext.h>
-#include <QtOpenGL/qgl.h>
-#include <QtOpenGL/qglframebufferobject.h>
-
-#include <QtCore/qreadwritelock.h>
-
-#include <qabstractvideobuffer.h>
-#include <qabstractvideosurface.h>
-#include <qvideosurfaceformat.h>
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT_USE_NAMESPACE
-
-class NSBitmapVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- NSBitmapVideoBuffer(NSBitmapImageRep *buffer)
- : QAbstractVideoBuffer(NoHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- [m_buffer retain];
- }
-
- virtual ~NSBitmapVideoBuffer()
- {
- [m_buffer release];
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (mode != NotMapped && m_mode == NotMapped) {
- if (numBytes)
- *numBytes = [m_buffer bytesPerPlane];
-
- if (bytesPerLine)
- *bytesPerLine = [m_buffer bytesPerRow];
-
- m_mode = mode;
-
- return [m_buffer bitmapData];
- } else {
- return 0;
- }
- }
-
- void unmap() { m_mode = NotMapped; }
-
-private:
- NSBitmapImageRep *m_buffer;
- MapMode m_mode;
-};
-
-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;
-};
-
-
-#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
-
-@interface HiddenQTMovieView : QTMovieView
-{
-@private
- QWindow *m_window;
- QT7MovieViewRenderer *m_renderer;
- QReadWriteLock m_rendererLock;
-}
-
-- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
-- (void) setRenderer:(QT7MovieViewRenderer *)renderer;
-- (void) setDrawRect:(const QRect &)rect;
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
-@end
-
-@implementation HiddenQTMovieView
-
-- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer
-{
- self = [super initWithFrame:NSZeroRect];
- if (self) {
- [self setControllerVisible:NO];
- [self setDelegate:self];
-
- QWriteLocker lock(&self->m_rendererLock);
- self->m_renderer = renderer;
-
- 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)];
- }
- return self;
-}
-
-- (void) dealloc
-{
- self->m_window->deleteLater();
- [super dealloc];
-}
-
-- (void) setRenderer:(QT7MovieViewRenderer *)renderer
-{
- QWriteLocker lock(&m_rendererLock);
- m_renderer = renderer;
-}
-
-- (void) setDrawRect:(const QRect &)rect
-{
- NSRect nsrect;
- nsrect.origin.x = rect.x();
- nsrect.origin.y = rect.y();
- nsrect.size.width = rect.width();
- nsrect.size.height = rect.height();
- [self setFrame:nsrect];
-}
-
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
-{
- // This method is called from QTMovieView just
- // before the image will be drawn.
- Q_UNUSED(view);
- QReadLocker lock(&m_rendererLock);
- AutoReleasePool pool;
-
- if (m_renderer) {
- CGRect bounds = [img extent];
- int w = bounds.size.width;
- int h = bounds.size.height;
-
- QVideoFrame frame;
-
- QAbstractVideoSurface *surface = m_renderer->surface();
- if (!surface || !surface->isActive())
- return img;
-
- if (surface->surfaceFormat().handleType() == QAbstractVideoBuffer::CoreImageHandle ||
- surface->surfaceFormat().handleType() == QAbstractVideoBuffer::GLTextureHandle) {
- //surface supports rendering of opengl based CIImage
- frame = QVideoFrame(new QT7CIImageVideoBuffer(img), QSize(w,h), QVideoFrame::Format_RGB32 );
- } else {
- //Swap R and B colors
- CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues:
- @"inputImage", img,
- @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0],
- @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0],
- @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0],
- @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1],
- @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0],
- nil];
- CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
- NSBitmapImageRep *bitmap =[[NSBitmapImageRep alloc] initWithCIImage:img];
- //requesting the bitmap data is slow,
- //but it's better to do it here to avoid blocking the main thread for a long.
- [bitmap bitmapData];
- frame = QVideoFrame(new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
- [bitmap release];
- }
-
- m_renderer->renderFrame(frame);
- }
-
- return img;
-}
-
-// Override this method so that the movie doesn't stop if
-// the window becomes invisible
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow
-{
- Q_UNUSED(newWindow);
-}
-
-
-VIDEO_TRANSPARENT(mouseDown);
-VIDEO_TRANSPARENT(mouseDragged);
-VIDEO_TRANSPARENT(mouseUp);
-VIDEO_TRANSPARENT(mouseMoved);
-VIDEO_TRANSPARENT(mouseEntered);
-VIDEO_TRANSPARENT(mouseExited);
-VIDEO_TRANSPARENT(rightMouseDown);
-VIDEO_TRANSPARENT(rightMouseDragged);
-VIDEO_TRANSPARENT(rightMouseUp);
-VIDEO_TRANSPARENT(otherMouseDown);
-VIDEO_TRANSPARENT(otherMouseDragged);
-VIDEO_TRANSPARENT(otherMouseUp);
-VIDEO_TRANSPARENT(keyDown);
-VIDEO_TRANSPARENT(keyUp);
-VIDEO_TRANSPARENT(scrollWheel)
-
-@end
-
-
-QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
- :QT7VideoRendererControl(parent),
- m_movie(0),
- m_movieView(0),
- m_surface(0),
- m_window(0),
- m_context(0),
- m_fbo(0),
- m_ciContext(0),
- m_pendingRenderEvent(false)
-{
-}
-
-QT7MovieViewRenderer::~QT7MovieViewRenderer()
-{
- [(HiddenQTMovieView*)m_movieView setRenderer:0];
-
- QMutexLocker locker(&m_mutex);
- m_currentFrame = QVideoFrame();
- [(HiddenQTMovieView*)m_movieView release];
- [m_ciContext release];
- delete m_fbo;
- delete m_window;
-}
-
-void QT7MovieViewRenderer::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieViewRenderer::setupVideoOutput" << m_movie << m_surface;
-#endif
-
- HiddenQTMovieView *movieView = (HiddenQTMovieView*)m_movieView;
-
- if (movieView && !m_movie) {
- [movieView setMovie:nil];
- }
-
- if (m_movie) {
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
-
- m_nativeSize = QSize(size.width, size.height);
-
- if (!movieView) {
- movieView = [[HiddenQTMovieView alloc] initWithRenderer:this];
- m_movieView = movieView;
- [movieView setControllerVisible:NO];
- }
-
- [movieView setMovie:(QTMovie*)m_movie];
- [movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
- } else {
- m_nativeSize = QSize();
- }
-
- if (m_surface && !m_nativeSize.isEmpty()) {
- bool coreImageFrameSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::CoreImageHandle).isEmpty();
- bool glTextureSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
-
- QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle;
- QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_RGB32;
-
- if (coreImageFrameSupported) {
- handleType = QAbstractVideoBuffer::CoreImageHandle;
- } else if (glTextureSupported) {
- handleType = QAbstractVideoBuffer::GLTextureHandle;
- pixelFormat = QVideoFrame::Format_BGR32;
- }
-
- QVideoSurfaceFormat format(m_nativeSize, pixelFormat, handleType);
-
- if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Surface format was changed, stop the surface.";
-#endif
- m_surface->stop();
- }
-
- if (!m_surface->isActive()) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Starting the surface with format" << format;
-#endif
- if (!m_surface->start(format))
- qWarning() << "failed to start video surface" << m_surface->error();
- }
- }
-}
-
-/*!
- Render the CIImage based video frame to FBO and return the video frame with resulting texture
-*/
-QVideoFrame QT7MovieViewRenderer::convertCIImageToGLTexture(const QVideoFrame &frame)
-{
- if (frame.handleType() != QAbstractVideoBuffer::CoreImageHandle)
- return QVideoFrame();
-
- if (!m_window) {
- QOpenGLContext *qGlContext = 0;
-
- if (m_surface)
- qGlContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
-
- if (qGlContext) {
- m_window = new QWindow();
-
- 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();
- }
- }
-
- if (!m_context)
- return QVideoFrame();
-
- m_context->makeCurrent(m_window);
-
- if (!m_fbo || m_fbo->size() != frame.size()) {
- delete m_fbo;
- m_fbo = new QGLFramebufferObject(frame.size());
- }
-
- CIImage *ciImg = (CIImage*)(frame.handle().value<void*>());
- if (ciImg) {
- AutoReleasePool pool;
-
- QPainter p(m_fbo);
- p.beginNativePainting();
- CGLContextObj cglContext = CGLGetCurrentContext();
- if (cglContext) {
- if (!m_ciContext) {
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- m_ciContext = [CIContext contextWithCGLContext:cglContext
- pixelFormat:cglPixelFormat
- colorSpace:nil
- options:nil];
-
- [m_ciContext retain];
- }
-
- QRect viewport = QRect(0, 0, frame.width(), frame.height());
- CGRect sRect = CGRectMake(viewport.x(), viewport.y(), viewport.width(), viewport.height());
- CGRect dRect = CGRectMake(viewport.x(), viewport.y(), viewport.width(), viewport.height());
-
- [m_ciContext drawImage:ciImg inRect:dRect fromRect:sRect];
- }
-
- p.endNativePainting();
-
- QAbstractVideoBuffer *buffer = new TextureVideoBuffer(m_fbo->texture());
- return QVideoFrame(buffer, frame.size(), QVideoFrame::Format_BGR32);
- }
-
- return QVideoFrame();
-}
-
-void QT7MovieViewRenderer::setMovie(void *movie)
-{
- if (movie == m_movie)
- return;
-
- QMutexLocker locker(&m_mutex);
- m_movie = movie;
- setupVideoOutput();
-}
-
-void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
-{
- return m_surface;
-}
-
-void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface)
-{
- if (surface == m_surface)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive())
- m_surface->stop();
-
- m_surface = surface;
- setupVideoOutput();
-}
-
-void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
-{
- QMutexLocker locker(&m_mutex);
- m_currentFrame = frame;
-
- if (!m_pendingRenderEvent)
- qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
-
- m_pendingRenderEvent = true;
-}
-
-bool QT7MovieViewRenderer::event(QEvent *event)
-{
- if (event->type() == QEvent::User) {
- QMutexLocker locker(&m_mutex);
- m_pendingRenderEvent = false;
-
- if (m_surface->isActive()) {
- //For GL texture frames, render in the main thread CIImage based buffers
- //to FBO shared with video surface shared context
- if (m_surface->surfaceFormat().handleType() == QAbstractVideoBuffer::GLTextureHandle) {
- m_currentFrame = convertCIImageToGLTexture(m_currentFrame);
- if (m_currentFrame.isValid())
- m_surface->present(m_currentFrame);
- } else {
- m_surface->present(m_currentFrame);
- }
- }
-
- m_currentFrame = QVideoFrame();
- }
-
- return QT7VideoRendererControl::event(event);
-}
diff --git a/src/plugins/qt7/qt7serviceplugin.h b/src/plugins/qt7/qt7serviceplugin.h
deleted file mode 100644
index 2e04297ff..000000000
--- a/src/plugins/qt7/qt7serviceplugin.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QT7SERVICEPLUGIN_H
-#define QT7SERVICEPLUGIN_H
-
-#include <qmediaserviceproviderplugin.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7ServicePlugin
- : public QMediaServiceProviderPlugin
- , public QMediaServiceSupportedFormatsInterface
- , public QMediaServiceFeaturesInterface
-{
- Q_OBJECT
- Q_INTERFACES(QMediaServiceFeaturesInterface)
- Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "qt7.json")
-
-public:
- QT7ServicePlugin();
-
- QMediaService* create(QString const& key);
- void release(QMediaService *service);
-
- QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
- QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const;
- QStringList supportedMimeTypes() const;
-
-private:
- void buildSupportedTypes();
-
- QStringList m_supportedMimeTypes;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERSERVICEPLUGIN_H
diff --git a/src/plugins/qt7/qt7videooutput.h b/src/plugins/qt7/qt7videooutput.h
deleted file mode 100644
index 86fc273dd..000000000
--- a/src/plugins/qt7/qt7videooutput.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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:LGPL21$
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7VIDEOOUTPUTCONTROL_H
-#define QT7VIDEOOUTPUTCONTROL_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qsize.h>
-
-#include <qvideowindowcontrol.h>
-#ifndef QT_NO_WIDGETS
-#include <qvideowidgetcontrol.h>
-#endif
-#include <qvideorenderercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-
-class QT7VideoOutput {
-public:
- virtual ~QT7VideoOutput() {}
- virtual void setMovie(void *movie) = 0;
- virtual void updateNaturalSize(const QSize &newSize) = 0;
-};
-
-#define QT7VideoOutput_iid \
- "org.qt-project.qt.QT7VideoOutput/5.0"
-Q_DECLARE_INTERFACE(QT7VideoOutput, QT7VideoOutput_iid)
-
-class QT7VideoWindowControl : public QVideoWindowControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoWindowControl() {}
-
-protected:
- QT7VideoWindowControl(QObject *parent)
- :QVideoWindowControl(parent)
- {}
-};
-
-class QT7VideoRendererControl : public QVideoRendererControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoRendererControl() {}
-
-protected:
- QT7VideoRendererControl(QObject *parent)
- :QVideoRendererControl(parent)
- {}
-};
-
-#ifndef QT_NO_WIDGETS
-class QT7VideoWidgetControl : public QVideoWidgetControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoWidgetControl() {}
-
-protected:
- QT7VideoWidgetControl(QObject *parent)
- :QVideoWidgetControl(parent)
- {}
-};
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
index 59a9f661f..4f8f03836 100644
--- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
@@ -404,6 +404,7 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode)
Q_UNUSED(mode)
QList<QByteArray> devices;
+#ifndef Q_OS_WINCE
//enumerate device fullnames through directshow api
CoInitialize(NULL);
ICreateDevEnum *pDevEnum = NULL;
@@ -455,6 +456,35 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode)
}
}
CoUninitialize();
+#else // Q_OS_WINCE
+ if (mode == QAudio::AudioOutput) {
+ WAVEOUTCAPS woc;
+ unsigned long iNumDevs,i;
+ iNumDevs = waveOutGetNumDevs();
+ for (i=0;i<iNumDevs;i++) {
+ if (waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS))
+ == MMSYSERR_NOERROR) {
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ ds << quint32(i) << QString::fromWCharArray(woc.szPname);
+ devices.append(device);
+ }
+ }
+ } else {
+ WAVEINCAPS woc;
+ unsigned long iNumDevs,i;
+ iNumDevs = waveInGetNumDevs();
+ for (i=0;i<iNumDevs;i++) {
+ if (waveInGetDevCaps(i, &woc, sizeof(WAVEINCAPS))
+ == MMSYSERR_NOERROR) {
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ ds << quint32(i) << QString::fromWCharArray(woc.szPname);
+ devices.append(device);
+ }
+ }
+ }
+#endif // !Q_OS_WINCE
return devices;
}
diff --git a/src/plugins/windowsaudio/qwindowsaudioinput.cpp b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
index 376854373..2a3d34293 100644
--- a/src/plugins/windowsaudio/qwindowsaudioinput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
@@ -698,7 +698,7 @@ qint64 QWindowsAudioInput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return timeStampOpened.elapsed()*1000;
+ return timeStampOpened.elapsed() * qint64(1000);
}
void QWindowsAudioInput::reset()
diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
index 659ee3a0c..a9230139c 100644
--- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
@@ -674,7 +674,7 @@ qint64 QWindowsAudioOutput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return timeStampOpened.elapsed()*1000;
+ return timeStampOpened.elapsed() * qint64(1000);
}
QAudio::Error QWindowsAudioOutput::error() const
diff --git a/src/plugins/windowsaudio/windowsaudio.pro b/src/plugins/windowsaudio/windowsaudio.pro
index a1a327953..ead73251b 100644
--- a/src/plugins/windowsaudio/windowsaudio.pro
+++ b/src/plugins/windowsaudio/windowsaudio.pro
@@ -5,7 +5,8 @@ PLUGIN_TYPE = audio
PLUGIN_CLASS_NAME = QWindowsAudioPlugin
load(qt_plugin)
-LIBS += -lwinmm -lstrmiids -lole32 -loleaut32
+LIBS += -lstrmiids -lole32 -loleaut32
+!wince*:LIBS += -lwinmm
HEADERS += \
qwindowsaudioplugin.h \
diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp
new file mode 100644
index 000000000..619e97315
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameracontrol.cpp
@@ -0,0 +1,783 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwinrtcameracontrol.h"
+#include "qwinrtcameravideorenderercontrol.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
+#include "qwinrtcameraimagecapturecontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QPointer>
+
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <wrl.h>
+#include <windows.devices.enumeration.h>
+#include <windows.media.capture.h>
+#include <windows.storage.streams.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Media;
+using namespace ABI::Windows::Media::Capture;
+using namespace ABI::Windows::Media::Devices;
+using namespace ABI::Windows::Media::MediaProperties;
+using namespace ABI::Windows::Storage::Streams;
+
+QT_USE_NAMESPACE
+
+#define RETURN_VOID_AND_EMIT_ERROR(msg) \
+ if (FAILED(hr)) { \
+ emit error(QCamera::CameraError, qt_error_string(hr)); \
+ RETURN_VOID_IF_FAILED(msg); \
+ }
+
+class CriticalSectionLocker
+{
+public:
+ CriticalSectionLocker(CRITICAL_SECTION *section)
+ : m_section(section)
+ {
+ EnterCriticalSection(m_section);
+ }
+ ~CriticalSectionLocker()
+ {
+ LeaveCriticalSection(m_section);
+ }
+private:
+ CRITICAL_SECTION *m_section;
+};
+
+class MediaStream : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IMFStreamSink, IMFMediaEventGenerator, IMFMediaTypeHandler>
+{
+public:
+ MediaStream(IMFMediaType *type, IMFMediaSink *mediaSink, QWinRTCameraVideoRendererControl *videoRenderer)
+ : m_type(type), m_sink(mediaSink), m_videoRenderer(videoRenderer)
+ {
+ Q_ASSERT(m_videoRenderer);
+
+ InitializeCriticalSectionEx(&m_mutex, 0, 0);
+
+ HRESULT hr;
+ hr = MFCreateEventQueue(&m_eventQueue);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &m_workQueueId);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ ~MediaStream()
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ m_eventQueue->Shutdown();
+ DeleteCriticalSection(&m_mutex);
+ }
+
+ HRESULT RequestSample()
+ {
+ if (m_pendingSamples.load() < 3) {
+ m_pendingSamples.ref();
+ return QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetEvent(DWORD flags, IMFMediaEvent **event) Q_DECL_OVERRIDE
+ {
+ EnterCriticalSection(&m_mutex);
+ // Create an extra reference to avoid deadlock
+ ComPtr<IMFMediaEventQueue> eventQueue = m_eventQueue;
+ LeaveCriticalSection(&m_mutex);
+
+ return eventQueue->GetEvent(flags, event);
+ }
+
+ HRESULT __stdcall BeginGetEvent(IMFAsyncCallback *callback, IUnknown *state) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ HRESULT hr = m_eventQueue->BeginGetEvent(callback, state);
+ return hr;
+ }
+
+ HRESULT __stdcall EndGetEvent(IMFAsyncResult *result, IMFMediaEvent **event) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ return m_eventQueue->EndGetEvent(result, event);
+ }
+
+ HRESULT __stdcall QueueEvent(MediaEventType eventType, const GUID &extendedType, HRESULT status, const PROPVARIANT *value) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ return m_eventQueue->QueueEventParamVar(eventType, extendedType, status, value);
+ }
+
+ HRESULT __stdcall GetMediaSink(IMFMediaSink **mediaSink) Q_DECL_OVERRIDE
+ {
+ *mediaSink = m_sink;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetIdentifier(DWORD *identifier) Q_DECL_OVERRIDE
+ {
+ *identifier = 0;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeHandler(IMFMediaTypeHandler **handler) Q_DECL_OVERRIDE
+ {
+ return QueryInterface(IID_PPV_ARGS(handler));
+ }
+
+ HRESULT __stdcall ProcessSample(IMFSample *sample) Q_DECL_OVERRIDE
+ {
+ ComPtr<IMFMediaBuffer> buffer;
+ HRESULT hr = sample->GetBufferByIndex(0, &buffer);
+ RETURN_HR_IF_FAILED("Failed to get buffer from camera sample");
+ ComPtr<IMF2DBuffer> buffer2d;
+ hr = buffer.As(&buffer2d);
+ RETURN_HR_IF_FAILED("Failed to cast camera sample buffer to 2D buffer");
+
+ m_pendingSamples.deref();
+ m_videoRenderer->queueBuffer(buffer2d.Get());
+
+ return hr;
+ }
+
+ HRESULT __stdcall PlaceMarker(MFSTREAMSINK_MARKER_TYPE type, const PROPVARIANT *value, const PROPVARIANT *context) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(type);
+ Q_UNUSED(value);
+ QueueEvent(MEStreamSinkMarker, GUID_NULL, S_OK, context);
+ return S_OK;
+ }
+
+ HRESULT __stdcall Flush() Q_DECL_OVERRIDE
+ {
+ m_videoRenderer->discardBuffers();
+ m_pendingSamples.store(0);
+ return S_OK;
+ }
+
+ HRESULT __stdcall IsMediaTypeSupported(IMFMediaType *type, IMFMediaType **) Q_DECL_OVERRIDE
+ {
+ HRESULT hr;
+ GUID majorType;
+ hr = type->GetMajorType(&majorType);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!IsEqualGUID(majorType, MFMediaType_Video))
+ return MF_E_INVALIDMEDIATYPE;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeCount(DWORD *typeCount) Q_DECL_OVERRIDE
+ {
+ *typeCount = 1;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeByIndex(DWORD index, IMFMediaType **type) Q_DECL_OVERRIDE
+ {
+ if (index == 0)
+ return m_type.CopyTo(type);
+ return E_BOUNDS;
+ }
+
+ HRESULT __stdcall SetCurrentMediaType(IMFMediaType *type) Q_DECL_OVERRIDE
+ {
+ if (FAILED(IsMediaTypeSupported(type, Q_NULLPTR)))
+ return MF_E_INVALIDREQUEST;
+
+ m_type = type;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetCurrentMediaType(IMFMediaType **type) Q_DECL_OVERRIDE
+ {
+ return m_type.CopyTo(type);
+ }
+
+ HRESULT __stdcall GetMajorType(GUID *majorType) Q_DECL_OVERRIDE
+ {
+ return m_type->GetMajorType(majorType);
+ }
+
+private:
+ CRITICAL_SECTION m_mutex;
+ ComPtr<IMFMediaType> m_type;
+ IMFMediaSink *m_sink;
+ ComPtr<IMFMediaEventQueue> m_eventQueue;
+ DWORD m_workQueueId;
+
+ QWinRTCameraVideoRendererControl *m_videoRenderer;
+ QAtomicInt m_pendingSamples;
+};
+
+class MediaSink : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IMediaExtension, IMFMediaSink, IMFClockStateSink>
+{
+public:
+ MediaSink(IMediaEncodingProfile *encodingProfile, QWinRTCameraVideoRendererControl *videoRenderer)
+ : m_videoRenderer(videoRenderer)
+ {
+ HRESULT hr;
+ ComPtr<IVideoEncodingProperties> videoProperties;
+ hr = encodingProfile->get_Video(&videoProperties);
+ RETURN_VOID_IF_FAILED("Failed to get video properties");
+ ComPtr<IMFMediaType> videoType;
+ hr = MFCreateMediaTypeFromProperties(videoProperties.Get(), &videoType);
+ RETURN_VOID_IF_FAILED("Failed to create video type");
+ m_stream = Make<MediaStream>(videoType.Get(), this, videoRenderer);
+ }
+
+ ~MediaSink()
+ {
+ }
+
+ HRESULT RequestSample()
+ {
+ return m_stream->RequestSample();
+ }
+
+ HRESULT __stdcall SetProperties(Collections::IPropertySet *configuration) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(configuration);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall GetCharacteristics(DWORD *characteristics) Q_DECL_OVERRIDE
+ {
+ *characteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_RATELESS;
+ return S_OK;
+ }
+
+ HRESULT __stdcall AddStreamSink(DWORD streamSinkIdentifier, IMFMediaType *mediaType, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(streamSinkIdentifier);
+ Q_UNUSED(mediaType);
+ Q_UNUSED(streamSink);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall RemoveStreamSink(DWORD streamSinkIdentifier) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(streamSinkIdentifier);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall GetStreamSinkCount(DWORD *streamSinkCount) Q_DECL_OVERRIDE
+ {
+ *streamSinkCount = 1;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetStreamSinkByIndex(DWORD index, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ if (index == 0)
+ return m_stream.CopyTo(streamSink);
+ return MF_E_INVALIDINDEX;
+ }
+
+ HRESULT __stdcall GetStreamSinkById(DWORD streamSinkIdentifier, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ // ID and index are always 0
+ HRESULT hr = GetStreamSinkByIndex(streamSinkIdentifier, streamSink);
+ return hr == MF_E_INVALIDINDEX ? MF_E_INVALIDSTREAMNUMBER : hr;
+ }
+
+ HRESULT __stdcall SetPresentationClock(IMFPresentationClock *presentationClock) Q_DECL_OVERRIDE
+ {
+ HRESULT hr = S_OK;
+ m_presentationClock = presentationClock;
+ if (m_presentationClock)
+ hr = m_presentationClock->AddClockStateSink(this);
+ return hr;
+ }
+
+ HRESULT __stdcall GetPresentationClock(IMFPresentationClock **presentationClock) Q_DECL_OVERRIDE
+ {
+ return m_presentationClock.CopyTo(presentationClock);
+ }
+
+ HRESULT __stdcall Shutdown() Q_DECL_OVERRIDE
+ {
+ m_stream->Flush();
+ m_videoRenderer->setActive(false);
+ return m_presentationClock->Stop();
+ }
+
+ HRESULT __stdcall OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+ Q_UNUSED(clockStartOffset);
+
+ m_videoRenderer->setActive(true);
+
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnClockStop(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(false);
+
+ return m_stream->QueueEvent(MEStreamSinkStopped, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockPause(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(false);
+
+ return m_stream->QueueEvent(MEStreamSinkPaused, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockRestart(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(true);
+
+ return m_stream->QueueEvent(MEStreamSinkStarted, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockSetRate(MFTIME systemTime, float rate) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+ Q_UNUSED(rate);
+ return E_NOTIMPL;
+ }
+
+private:
+ ComPtr<MediaStream> m_stream;
+ ComPtr<IMFPresentationClock> m_presentationClock;
+
+ QWinRTCameraVideoRendererControl *m_videoRenderer;
+};
+
+class QWinRTCameraControlPrivate
+{
+public:
+ QCamera::State state;
+ QCamera::Status status;
+ QCamera::CaptureModes captureMode;
+
+ ComPtr<IMediaCapture> capture;
+ ComPtr<IMediaCaptureVideoPreview> capturePreview;
+ EventRegistrationToken captureFailedCookie;
+ EventRegistrationToken recordLimitationCookie;
+
+ ComPtr<IMediaEncodingProfileStatics> encodingProfileFactory;
+
+ ComPtr<IMediaEncodingProfile> encodingProfile;
+ ComPtr<MediaSink> mediaSink;
+
+ QSize size;
+ QPointer<QWinRTCameraVideoRendererControl> videoRenderer;
+ QPointer<QWinRTVideoDeviceSelectorControl> videoDeviceSelector;
+ QPointer<QWinRTCameraImageCaptureControl> imageCaptureControl;
+};
+
+QWinRTCameraControl::QWinRTCameraControl(QObject *parent)
+ : QCameraControl(parent), d_ptr(new QWinRTCameraControlPrivate)
+{
+ Q_D(QWinRTCameraControl);
+
+ d->state = QCamera::UnloadedState;
+ d->status = QCamera::UnloadedStatus;
+ d->captureMode = QCamera::CaptureStillImage;
+ d->captureFailedCookie.value = 0;
+ d->recordLimitationCookie.value = 0;
+ d->videoRenderer = new QWinRTCameraVideoRendererControl(d->size, this);
+ connect(d->videoRenderer, &QWinRTCameraVideoRendererControl::bufferRequested,
+ this, &QWinRTCameraControl::onBufferRequested);
+ d->videoDeviceSelector = new QWinRTVideoDeviceSelectorControl(this);
+ d->imageCaptureControl = new QWinRTCameraImageCaptureControl(this);
+}
+
+QWinRTCameraControl::~QWinRTCameraControl()
+{
+ setState(QCamera::UnloadedState);
+}
+
+QCamera::State QWinRTCameraControl::state() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->state;
+}
+
+void QWinRTCameraControl::setState(QCamera::State state)
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->state == state)
+ return;
+
+ HRESULT hr;
+ switch (state) {
+ case QCamera::ActiveState: {
+ // Capture has not been created or initialized
+ if (d->state == QCamera::UnloadedState) {
+ hr = initialize();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initialize media capture");
+ }
+ Q_ASSERT(d->state == QCamera::LoadedState);
+
+ d->mediaSink = Make<MediaSink>(d->encodingProfile.Get(), d->videoRenderer);
+ ComPtr<IAsyncAction> op;
+ hr = d->capturePreview->StartPreviewToCustomSinkAsync(d->encodingProfile.Get(), d->mediaSink.Get(), &op);
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initiate capture");
+ if (d->status != QCamera::StartingStatus) {
+ d->status = QCamera::StartingStatus;
+ emit statusChanged(d->status);
+ }
+
+ hr = QWinRTFunctions::await(op);
+ if (FAILED(hr)) {
+ emit error(QCamera::CameraError, qt_error_string(hr));
+ setState(QCamera::UnloadedState); // Unload everything, as initialize() will need be called again
+ return;
+ }
+
+ d->state = QCamera::ActiveState;
+ emit stateChanged(d->state);
+ d->status = QCamera::ActiveStatus;
+ emit statusChanged(d->status);
+ break;
+ }
+ case QCamera::LoadedState: {
+ // If moving from unloaded, initialize the camera
+ if (d->state == QCamera::UnloadedState) {
+ hr = initialize();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initialize media capture");
+ }
+ // fall through
+ }
+ case QCamera::UnloadedState: {
+ // Stop the camera if it is running (transition to LoadedState)
+ if (d->status == QCamera::ActiveStatus) {
+ ComPtr<IAsyncAction> op;
+ hr = d->capturePreview->StopPreviewAsync(&op);
+ RETURN_VOID_AND_EMIT_ERROR("Failed to stop camera preview");
+ if (d->status != QCamera::StoppingStatus) {
+ d->status = QCamera::StoppingStatus;
+ emit statusChanged(d->status);
+ }
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QWinRTFunctions::await(op); // Synchronize unloading
+ if (FAILED(hr))
+ emit error(QCamera::InvalidRequestError, qt_error_string(hr));
+
+ d->mediaSink->Shutdown();
+ d->mediaSink.Reset();
+
+ d->state = QCamera::LoadedState;
+ emit stateChanged(d->state);
+
+ d->status = QCamera::LoadedStatus;
+ emit statusChanged(d->status);
+ }
+ // Completely unload if needed
+ if (state == QCamera::UnloadedState) {
+ if (!d->capture) // Already unloaded
+ break;
+
+ if (d->status != QCamera::UnloadingStatus) {
+ d->status = QCamera::UnloadingStatus;
+ emit statusChanged(d->status);
+ }
+
+ if (d->capture && d->captureFailedCookie.value) {
+ hr = d->capture->remove_Failed(d->captureFailedCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->captureFailedCookie.value = 0;
+ }
+ if (d->capture && d->recordLimitationCookie.value) {
+ d->capture->remove_RecordLimitationExceeded(d->recordLimitationCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->recordLimitationCookie.value = 0;
+ }
+ ComPtr<IClosable> capture;
+ hr = d->capture.As(&capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = capture->Close();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to close the capture manger");
+ d->capture.Reset();
+ if (d->state != QCamera::UnloadedState) {
+ d->state = QCamera::UnloadedState;
+ emit stateChanged(d->state);
+ }
+ if (d->status != QCamera::UnloadedStatus) {
+ d->status = QCamera::UnloadedStatus;
+ emit statusChanged(d->status);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+QCamera::Status QWinRTCameraControl::status() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->status;
+}
+
+QCamera::CaptureModes QWinRTCameraControl::captureMode() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->captureMode;
+}
+
+void QWinRTCameraControl::setCaptureMode(QCamera::CaptureModes mode)
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->captureMode == mode)
+ return;
+
+ if (!isCaptureModeSupported(mode)) {
+ qWarning("Unsupported capture mode: %d", mode);
+ return;
+ }
+
+ d->captureMode = mode;
+ emit captureModeChanged(d->captureMode);
+}
+
+bool QWinRTCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+ return mode >= QCamera::CaptureViewfinder && mode <= QCamera::CaptureStillImage;
+}
+
+bool QWinRTCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const
+{
+ Q_UNUSED(changeType);
+
+ return status == QCamera::UnloadedStatus; // For now, assume shutdown is required for all property changes
+}
+
+QVideoRendererControl *QWinRTCameraControl::videoRenderer() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->videoRenderer;
+}
+
+QVideoDeviceSelectorControl *QWinRTCameraControl::videoDeviceSelector() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->videoDeviceSelector;
+}
+
+QCameraImageCaptureControl *QWinRTCameraControl::imageCaptureControl() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->imageCaptureControl;
+}
+
+IMediaCapture *QWinRTCameraControl::handle() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->capture.Get();
+}
+
+QSize QWinRTCameraControl::imageSize() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->size;
+}
+
+void QWinRTCameraControl::onBufferRequested()
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->mediaSink)
+ d->mediaSink->RequestSample();
+}
+
+HRESULT QWinRTCameraControl::initialize()
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->status != QCamera::LoadingStatus) {
+ d->status = QCamera::LoadingStatus;
+ emit statusChanged(d->status);
+ }
+
+ HRESULT hr;
+ ComPtr<IInspectable> capture;
+ hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCapture).Get(),
+ &capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = capture.As(&d->capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture.As(&d->capturePreview);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture->add_Failed(Callback<IMediaCaptureFailedEventHandler>(this, &QWinRTCameraControl::onCaptureFailed).Get(),
+ &d->captureFailedCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture->add_RecordLimitationExceeded(Callback<IRecordLimitationExceededEventHandler>(this, &QWinRTCameraControl::onRecordLimitationExceeded).Get(),
+ &d->recordLimitationCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(),
+ IID_PPV_ARGS(&d->encodingProfileFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ int deviceIndex = d->videoDeviceSelector->selectedDevice();
+ if (deviceIndex < 0)
+ deviceIndex = d->videoDeviceSelector->defaultDevice();
+
+ const QString deviceName = d->videoDeviceSelector->deviceName(deviceIndex);
+ if (deviceName.isEmpty()) {
+ qWarning("No video device available or selected.");
+ return E_FAIL;
+ }
+
+ ComPtr<IMediaCaptureInitializationSettings> settings;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(),
+ &settings);
+ Q_ASSERT_SUCCEEDED(hr);
+ HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), deviceName.length());
+ hr = settings->put_VideoDeviceId(deviceId.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = settings->put_StreamingCaptureMode(StreamingCaptureMode_Video);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = settings->put_PhotoCaptureSource(PhotoCaptureSource_Auto);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncAction> op;
+ hr = d->capture->InitializeWithSettingsAsync(settings.Get(), &op);
+ RETURN_HR_IF_FAILED("Failed to begin initialization of media capture manager");
+ hr = QWinRTFunctions::await(op, QWinRTFunctions::ProcessThreadEvents);
+ if (hr == E_ACCESSDENIED) {
+ qWarning("Access denied when initializing the media capture manager. "
+ "Check your manifest settings for microphone and webcam access.");
+ }
+ RETURN_HR_IF_FAILED("Failed to initialize media capture manager");
+
+ ComPtr<IVideoDeviceController> videoDeviceController;
+ hr = d->capture->get_VideoDeviceController(&videoDeviceController);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IMediaDeviceController> deviceController;
+ hr = videoDeviceController.As(&deviceController);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<IMediaEncodingProperties *>> encodingPropertiesList;
+ hr = deviceController->GetAvailableMediaStreamProperties(MediaStreamType_Photo, &encodingPropertiesList);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->size = QSize();
+ ComPtr<IVideoEncodingProperties> videoEncodingProperties;
+ quint32 encodingPropertiesListSize;
+ hr = encodingPropertiesList->get_Size(&encodingPropertiesListSize);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (quint32 i = 0; i < encodingPropertiesListSize; ++i) {
+ ComPtr<IMediaEncodingProperties> properties;
+ hr = encodingPropertiesList->GetAt(i, &properties);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVideoEncodingProperties> videoProperties;
+ hr = properties.As(&videoEncodingProperties);
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 width, height;
+ hr = videoEncodingProperties->get_Width(&width);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = videoEncodingProperties->get_Height(&height);
+ Q_ASSERT_SUCCEEDED(hr);
+ // Choose the highest-quality format
+ if (int(width * height) > d->size.width() * d->size.height()) {
+ d->size = QSize(width, height);
+ videoEncodingProperties = videoProperties;
+ }
+ }
+
+ if (!videoEncodingProperties || d->size.isEmpty()) {
+ hr = MF_E_INVALID_FORMAT;
+ RETURN_HR_IF_FAILED("Failed to find a suitable video format");
+ }
+
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(),
+ &d->encodingProfile);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->encodingProfile->put_Video(videoEncodingProperties.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ if (d->videoRenderer)
+ d->videoRenderer->setSize(d->size);
+
+ if (SUCCEEDED(hr) && d->state != QCamera::LoadedState) {
+ d->state = QCamera::LoadedState;
+ emit stateChanged(d->state);
+ }
+ if (SUCCEEDED(hr) && d->status != QCamera::LoadedStatus) {
+ d->status = QCamera::LoadedStatus;
+ emit statusChanged(d->status);
+ }
+ return hr;
+}
+
+HRESULT QWinRTCameraControl::onCaptureFailed(IMediaCapture *, IMediaCaptureFailedEventArgs *args)
+{
+ HRESULT hr;
+ UINT32 code;
+ hr = args->get_Code(&code);
+ RETURN_HR_IF_FAILED("Failed to get error code");
+ HString message;
+ args->get_Message(message.GetAddressOf());
+ RETURN_HR_IF_FAILED("Failed to get error message");
+ quint32 messageLength;
+ const wchar_t *messageBuffer = message.GetRawBuffer(&messageLength);
+ emit error(QCamera::CameraError, QString::fromWCharArray(messageBuffer, messageLength));
+ setState(QCamera::LoadedState);
+ return S_OK;
+}
+
+HRESULT QWinRTCameraControl::onRecordLimitationExceeded(IMediaCapture *)
+{
+ emit error(QCamera::CameraError, QStringLiteral("Recording limit exceeded."));
+ setState(QCamera::LoadedState);
+ return S_OK;
+}
diff --git a/src/plugins/winrt/qwinrtcameracontrol.h b/src/plugins/winrt/qwinrtcameracontrol.h
new file mode 100644
index 000000000..e75f7e476
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameracontrol.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QWINRTCAMERACONTROL_H
+#define QWINRTCAMERACONTROL_H
+
+#include <QtMultimedia/QCameraControl>
+#include <QtCore/qt_windows.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Media {
+ namespace Capture {
+ struct IMediaCapture;
+ struct IMediaCaptureFailedEventArgs;
+ }
+ }
+ namespace Foundation {
+ struct IAsyncAction;
+ enum class AsyncStatus;
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QVideoRendererControl;
+class QVideoDeviceSelectorControl;
+class QCameraImageCaptureControl;
+
+class QWinRTCameraControlPrivate;
+class QWinRTCameraControl : public QCameraControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraControl(QObject *parent = 0);
+ ~QWinRTCameraControl();
+
+ QCamera::State state() const Q_DECL_OVERRIDE;
+ void setState(QCamera::State state) Q_DECL_OVERRIDE;
+
+ QCamera::Status status() const Q_DECL_OVERRIDE;
+
+ QCamera::CaptureModes captureMode() const Q_DECL_OVERRIDE;
+ void setCaptureMode(QCamera::CaptureModes mode) Q_DECL_OVERRIDE;
+ bool isCaptureModeSupported(QCamera::CaptureModes mode) const Q_DECL_OVERRIDE;
+
+ bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const Q_DECL_OVERRIDE;
+
+ QVideoRendererControl *videoRenderer() const;
+ QVideoDeviceSelectorControl *videoDeviceSelector() const;
+ QCameraImageCaptureControl *imageCaptureControl() const;
+
+ ABI::Windows::Media::Capture::IMediaCapture *handle() const;
+ QSize imageSize() const;
+
+private slots:
+ void onBufferRequested();
+
+private:
+ HRESULT enumerateDevices();
+ HRESULT initialize();
+ HRESULT onCaptureFailed(ABI::Windows::Media::Capture::IMediaCapture *,
+ ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs *);
+ HRESULT onRecordLimitationExceeded(ABI::Windows::Media::Capture::IMediaCapture *);
+
+ QScopedPointer<QWinRTCameraControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERACONTROL_H
diff --git a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
new file mode 100644
index 000000000..f5151c619
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwinrtcameraimagecapturecontrol.h"
+#include "qwinrtcameracontrol.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QGlobalStatic>
+#include <QtCore/QPointer>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QVector>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtMultimedia/private/qmediastoragelocation_p.h>
+
+#include <wrl.h>
+#include <windows.media.capture.h>
+#include <windows.media.devices.h>
+#include <windows.media.mediaproperties.h>
+#include <windows.storage.streams.h>
+#include <windows.graphics.imaging.h>
+#include <robuffer.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Media::Capture;
+using namespace ABI::Windows::Media::Devices;
+using namespace ABI::Windows::Media::MediaProperties;
+using namespace ABI::Windows::Storage::Streams;
+using namespace ABI::Windows::Graphics::Imaging;
+
+QT_USE_NAMESPACE
+
+#define wchar(str) reinterpret_cast<const wchar_t *>(str.utf16())
+
+struct QWinRTCameraImageCaptureControlGlobal
+{
+ QWinRTCameraImageCaptureControlGlobal()
+ {
+ HRESULT hr;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_ImageEncodingProperties).Get(),
+ &encodingPropertiesFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(),
+ &dataReaderFactory);
+ }
+
+ ComPtr<IImageEncodingPropertiesStatics2> encodingPropertiesFactory;
+ ComPtr<IBufferFactory> bufferFactory;
+ ComPtr<IDataReaderFactory> dataReaderFactory;
+};
+Q_GLOBAL_STATIC(QWinRTCameraImageCaptureControlGlobal, g)
+
+struct CaptureRequest
+{
+ quint16 id;
+ QString fileName;
+ ComPtr<IImageEncodingProperties> imageFormat;
+ ComPtr<IRandomAccessStream> stream;
+ ComPtr<IAsyncAction> op;
+};
+
+class QWinRTCameraImageCaptureControlPrivate
+{
+public:
+ QPointer<QWinRTCameraControl> cameraControl;
+ QHash<IAsyncAction *, CaptureRequest> requests;
+ quint16 currentCaptureId;
+ QMediaStorageLocation location;
+
+ void onCameraStateChanged()
+ {
+
+ }
+};
+
+QWinRTCameraImageCaptureControl::QWinRTCameraImageCaptureControl(QWinRTCameraControl *parent)
+ : QCameraImageCaptureControl(parent), d_ptr(new QWinRTCameraImageCaptureControlPrivate)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ d->cameraControl = parent;
+ connect(d->cameraControl, &QCameraControl::stateChanged,
+ this, &QWinRTCameraImageCaptureControl::readyForCaptureChanged);
+ d->currentCaptureId = 0;
+}
+
+bool QWinRTCameraImageCaptureControl::isReadyForCapture() const
+{
+ Q_D(const QWinRTCameraImageCaptureControl);
+ return d->cameraControl->state() == QCamera::ActiveState;
+}
+
+QCameraImageCapture::DriveMode QWinRTCameraImageCaptureControl::driveMode() const
+{
+ return QCameraImageCapture::SingleImageCapture;
+}
+
+void QWinRTCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+ Q_UNUSED(mode);
+}
+
+int QWinRTCameraImageCaptureControl::capture(const QString &fileName)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ ++d->currentCaptureId;
+ IMediaCapture *capture = d->cameraControl->handle();
+ if (!capture) {
+ emit error(d->currentCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
+ return -1;
+ }
+
+ CaptureRequest request = {
+ d->currentCaptureId,
+ d->location.generateFileName(fileName, QMediaStorageLocation::Pictures, QStringLiteral("IMG_"),
+ fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix())
+ };
+
+ HRESULT hr;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(),
+ &request.stream);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = g->encodingPropertiesFactory->CreateBmp(&request.imageFormat);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ const QSize imageSize = d->cameraControl->imageSize();
+ hr = request.imageFormat->put_Width(imageSize.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = request.imageFormat->put_Height(imageSize.height());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = capture->CapturePhotoToStreamAsync(request.imageFormat.Get(), request.stream.Get(), &request.op);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->requests.insert(request.op.Get(), request);
+
+ hr = request.op->put_Completed(Callback<IAsyncActionCompletedHandler>(
+ this, &QWinRTCameraImageCaptureControl::onCaptureCompleted).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ return request.id;
+}
+
+void QWinRTCameraImageCaptureControl::cancelCapture()
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ QHash<IAsyncAction *, CaptureRequest>::iterator it = d->requests.begin();
+ while (it != d->requests.end()) {
+ ComPtr<IAsyncInfo> info;
+ it->op.As(&info);
+ info->Cancel();
+ it = d->requests.erase(it);
+ }
+}
+
+HRESULT QWinRTCameraImageCaptureControl::onCaptureCompleted(IAsyncAction *asyncInfo, AsyncStatus status)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ if (status == Canceled || !d->requests.contains(asyncInfo))
+ return S_OK;
+
+ CaptureRequest request = d->requests.take(asyncInfo);
+
+ HRESULT hr;
+ if (status == Error) {
+ hr = asyncInfo->GetResults();
+ emit error(request.id, QCameraImageCapture::ResourceError, qt_error_string(hr));
+ return S_OK;
+ }
+
+ quint64 dataLength;
+ hr = request.stream->get_Size(&dataLength);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (dataLength == 0 || dataLength > INT_MAX) {
+ emit error(request.id, QCameraImageCapture::FormatError, tr("Invalid photo data length."));
+ return S_OK;
+ }
+
+ ComPtr<IBitmapDecoderStatics> bitmapFactory;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapDecoder).Get(),
+ &bitmapFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<BitmapDecoder *>> op;
+ hr = bitmapFactory->CreateAsync(request.stream.Get(), &op);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IBitmapDecoder> decoder;
+ hr = QWinRTFunctions::await(op, decoder.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<BitmapFrame *>> op2;
+ hr = decoder->GetFrameAsync(0, &op2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IBitmapFrame> frame;
+ hr = QWinRTFunctions::await(op2, frame.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IBitmapTransform> transform;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapTransform).Get(),
+ &transform);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<PixelDataProvider *>> op3;
+ hr = frame->GetPixelDataTransformedAsync(BitmapPixelFormat_Rgba8, BitmapAlphaMode_Straight,
+ transform.Get(), ExifOrientationMode_IgnoreExifOrientation,
+ ColorManagementMode_DoNotColorManage, &op3);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IPixelDataProvider> pixelDataProvider;
+ hr = QWinRTFunctions::await(op3, pixelDataProvider.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ UINT32 pixelDataSize;
+ BYTE *pixelData;
+ hr = pixelDataProvider->DetachPixelData(&pixelDataSize, &pixelData);
+
+ UINT32 pixelHeight;
+ hr = frame->get_PixelHeight(&pixelHeight);
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 pixelWidth;
+ hr = frame->get_PixelWidth(&pixelWidth);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QImage image(pixelData, pixelWidth, pixelHeight, QImage::Format_RGBA8888,
+ reinterpret_cast<QImageCleanupFunction>(&CoTaskMemFree), pixelData);
+ emit imageCaptured(request.id, image);
+ if (image.save(request.fileName))
+ emit imageSaved(request.id, request.fileName);
+ else
+ emit error(request.id, QCameraImageCapture::ResourceError, tr("Image saving failed"));
+
+ return S_OK;
+}
diff --git a/src/plugins/qt7/qt7serviceplugin.mm b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.h
index 731f278a1..5150e4d3a 100644
--- a/src/plugins/qt7/qt7serviceplugin.mm
+++ b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
@@ -39,80 +39,48 @@
**
****************************************************************************/
-#import <Foundation/Foundation.h>
-#import <QTKit/QTKit.h>
+#ifndef QWINRTCAMERAIMAGECAPTURECONTROL_H
+#define QWINRTCAMERAIMAGECAPTURECONTROL_H
-#include <QtCore/qstring.h>
-#include <QtCore/qdebug.h>
+#include <QtMultimedia/QCameraImageCaptureControl>
+#include <QtCore/qt_windows.h>
-#include "qt7backend.h"
-#include "qt7serviceplugin.h"
-#include "qt7playerservice.h"
-
-#include <qmediaserviceproviderplugin.h>
-
-QT_BEGIN_NAMESPACE
-
-
-QT7ServicePlugin::QT7ServicePlugin()
-{
- buildSupportedTypes();
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ struct IAsyncAction;
+ enum class AsyncStatus;
+ }
+ }
}
-QMediaService* QT7ServicePlugin::create(QString const& key)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7ServicePlugin::create" << key;
-#endif
-#ifdef QMEDIA_QT7_PLAYER
- if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
- return new QT7PlayerService;
-#endif
- qWarning() << "unsupported key:" << key;
-
- return 0;
-}
+QT_BEGIN_NAMESPACE
-void QT7ServicePlugin::release(QMediaService *service)
-{
- delete service;
-}
+class QWinRTCameraControl;
-QMediaServiceProviderHint::Features QT7ServicePlugin::supportedFeatures(
- const QByteArray &service) const
+class QWinRTCameraImageCaptureControlPrivate;
+class QWinRTCameraImageCaptureControl : public QCameraImageCaptureControl
{
- if (service == Q_MEDIASERVICE_MEDIAPLAYER)
- return QMediaServiceProviderHint::VideoSurface;
- else
- return QMediaServiceProviderHint::Features();
-}
+ Q_OBJECT
+public:
+ explicit QWinRTCameraImageCaptureControl(QWinRTCameraControl *parent);
-QMultimedia::SupportEstimate QT7ServicePlugin::hasSupport(const QString &mimeType, const QStringList& codecs) const
-{
- Q_UNUSED(codecs);
+ bool isReadyForCapture() const Q_DECL_OVERRIDE;
- if (m_supportedMimeTypes.contains(mimeType))
- return QMultimedia::ProbablySupported;
+ QCameraImageCapture::DriveMode driveMode() const Q_DECL_OVERRIDE;
+ void setDriveMode(QCameraImageCapture::DriveMode mode) Q_DECL_OVERRIDE;
- return QMultimedia::MaybeSupported;
-}
+ int capture(const QString &fileName) Q_DECL_OVERRIDE;
+ void cancelCapture() Q_DECL_OVERRIDE;
-QStringList QT7ServicePlugin::supportedMimeTypes() const
-{
- return m_supportedMimeTypes;
-}
+private:
+ HRESULT onCaptureCompleted(ABI::Windows::Foundation::IAsyncAction *,
+ ABI::Windows::Foundation::AsyncStatus);
-void QT7ServicePlugin::buildSupportedTypes()
-{
- AutoReleasePool pool;
- NSArray *utis = [QTMovie movieTypesWithOptions:QTIncludeCommonTypes];
- for (NSString *uti in utis) {
- NSString* mimeType = (NSString*)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType);
- if (mimeType != 0) {
- m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String]));
- [mimeType release];
- }
- }
-}
+ QScopedPointer<QWinRTCameraImageCaptureControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraImageCaptureControl)
+};
QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAIMAGECAPTURECONTROL_H
diff --git a/src/plugins/qt7/qt7videooutput.mm b/src/plugins/winrt/qwinrtcamerainfocontrol.cpp
index 53486c4e4..c16b83be8 100644
--- a/src/plugins/qt7/qt7videooutput.mm
+++ b/src/plugins/winrt/qwinrtcamerainfocontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
@@ -39,53 +39,22 @@
**
****************************************************************************/
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-#include <QtCore/qdebug.h>
+#include "qwinrtcamerainfocontrol.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
QT_USE_NAMESPACE
-/*
-QT7VideoOutputControl::QT7VideoOutputControl(QObject *parent)
- :QVideoOutputControl(parent),
- m_session(0),
- m_output(QVideoOutputControl::NoOutput)
+QWinRTCameraInfoControl::QWinRTCameraInfoControl(QObject *parent)
+ : QCameraInfoControl(parent)
{
}
-QT7VideoOutputControl::~QT7VideoOutputControl()
+QCamera::Position QWinRTCameraInfoControl::cameraPosition(const QString &deviceName) const
{
+ return QWinRTVideoDeviceSelectorControl::cameraPosition(deviceName);
}
-void QT7VideoOutputControl::setSession(QT7PlayerSession *session)
+int QWinRTCameraInfoControl::cameraOrientation(const QString &deviceName) const
{
- m_session = session;
+ return QWinRTVideoDeviceSelectorControl::cameraOrientation(deviceName);
}
-
-QList<QVideoOutputControl::Output> QT7VideoOutputControl::availableOutputs() const
-{
- return m_outputs;
-}
-
-void QT7VideoOutputControl::enableOutput(QVideoOutputControl::Output output)
-{
- if (!m_outputs.contains(output))
- m_outputs.append(output);
-}
-
-QVideoOutputControl::Output QT7VideoOutputControl::output() const
-{
- return m_output;
-}
-
-void QT7VideoOutputControl::setOutput(Output output)
-{
- if (m_output != output) {
- m_output = output;
- Q_EMIT videoOutputChanged(m_output);
- }
-}
-
-#include "moc_qt7videooutputcontrol.cpp"
-
-*/
diff --git a/src/plugins/winrt/qwinrtcamerainfocontrol.h b/src/plugins/winrt/qwinrtcamerainfocontrol.h
new file mode 100644
index 000000000..bf430f038
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcamerainfocontrol.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QWINRTCAMERAINFOCONTROL_H
+#define QWINRTCAMERAINFOCONTROL_H
+
+#include <QtMultimedia/QCameraInfoControl>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCameraInfoControl : public QCameraInfoControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraInfoControl(QObject *parent = 0);
+
+ QCamera::Position cameraPosition(const QString &deviceName) const Q_DECL_OVERRIDE;
+ int cameraOrientation(const QString &deviceName) const Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAINFOCONTROL_H
diff --git a/src/plugins/winrt/qwinrtcameraservice.cpp b/src/plugins/winrt/qwinrtcameraservice.cpp
new file mode 100644
index 000000000..239a1e883
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraservice.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwinrtcameraservice.h"
+#include "qwinrtcameracontrol.h"
+#include "qwinrtcamerainfocontrol.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QPointer>
+#include <QtMultimedia/QCameraImageCaptureControl>
+#include <QtMultimedia/QVideoRendererControl>
+#include <QtMultimedia/QVideoDeviceSelectorControl>
+
+QT_USE_NAMESPACE
+
+class QWinRTCameraServicePrivate
+{
+public:
+ QPointer<QWinRTCameraControl> cameraControl;
+ QPointer<QWinRTCameraInfoControl> cameraInfoControl;
+};
+
+QWinRTCameraService::QWinRTCameraService(QObject *parent)
+ : QMediaService(parent), d_ptr(new QWinRTCameraServicePrivate)
+{
+}
+
+QMediaControl *QWinRTCameraService::requestControl(const char *name)
+{
+ Q_D(QWinRTCameraService);
+
+ if (qstrcmp(name, QCameraControl_iid) == 0) {
+ if (!d->cameraControl)
+ d->cameraControl = new QWinRTCameraControl(this);
+ return d->cameraControl;
+ }
+
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->videoRenderer();
+ }
+
+ if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->videoDeviceSelector();
+ }
+
+ if (qstrcmp(name, QCameraInfoControl_iid) == 0) {
+ if (!d->cameraInfoControl)
+ d->cameraInfoControl = new QWinRTCameraInfoControl(this);
+ return d->cameraInfoControl;
+ }
+
+ if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->imageCaptureControl();
+ }
+
+ return Q_NULLPTR;
+}
+
+void QWinRTCameraService::releaseControl(QMediaControl *control)
+{
+ Q_UNUSED(control);
+}
diff --git a/src/plugins/winrt/qwinrtcameraservice.h b/src/plugins/winrt/qwinrtcameraservice.h
new file mode 100644
index 000000000..19e93a818
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraservice.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QWINRTCAMERASERVICE_H
+#define QWINRTCAMERASERVICE_H
+
+#include <QtMultimedia/QMediaService>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCameraServicePrivate;
+class QWinRTCameraService : public QMediaService
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraService(QObject *parent = 0);
+
+ QMediaControl *requestControl(const char *name) Q_DECL_OVERRIDE;
+ void releaseControl(QMediaControl *control) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWinRTCameraServicePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraService)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERASERVICE_H
diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
new file mode 100644
index 000000000..e7e75da27
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwinrtcameravideorenderercontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QSize>
+#include <QtCore/QVector>
+
+#include <d3d11.h>
+#include <mfapi.h>
+#include <wrl.h>
+using namespace Microsoft::WRL;
+
+QT_USE_NAMESPACE
+
+class D3DVideoBlitter
+{
+public:
+ D3DVideoBlitter(ID3D11Device *device, ID3D11Texture2D *target)
+ : m_d3dDevice(device), m_target(target)
+ {
+ HRESULT hr;
+ ComPtr<IDXGIResource> targetResource;
+ hr = target->QueryInterface(IID_PPV_ARGS(&targetResource));
+ Q_ASSERT_SUCCEEDED(hr);
+ HANDLE sharedHandle;
+ hr = targetResource->GetSharedHandle(&sharedHandle);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = m_d3dDevice->OpenSharedResource(sharedHandle, IID_PPV_ARGS(&m_targetTexture));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = m_d3dDevice.As(&m_videoDevice);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ ID3D11Device *device() const
+ {
+ return m_d3dDevice.Get();
+ }
+
+ ID3D11Texture2D *target() const
+ {
+ return m_target;
+ }
+
+ void blit(ID3D11Texture2D *texture)
+ {
+ HRESULT hr;
+ D3D11_TEXTURE2D_DESC desc;
+ texture->GetDesc(&desc);
+ if (!m_videoEnumerator) {
+ D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoProcessorDesc = {
+ D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
+ { 0 }, desc.Width, desc.Height,
+ { 0 }, desc.Width, desc.Height,
+ D3D11_VIDEO_USAGE_PLAYBACK_NORMAL
+ };
+ hr = m_videoDevice->CreateVideoProcessorEnumerator(&videoProcessorDesc, &m_videoEnumerator);
+ RETURN_VOID_IF_FAILED("Failed to create video enumerator");
+ }
+
+ if (!m_videoProcessor) {
+ hr = m_videoDevice->CreateVideoProcessor(m_videoEnumerator.Get(), 0, &m_videoProcessor);
+ RETURN_VOID_IF_FAILED("Failed to create video processor");
+ }
+
+ if (!m_outputView) {
+ D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
+ hr = m_videoDevice->CreateVideoProcessorOutputView(
+ m_targetTexture.Get(), m_videoEnumerator.Get(), &outputDesc, &m_outputView);
+ RETURN_VOID_IF_FAILED("Failed to create video output view");
+ }
+
+ D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = {
+ 0, D3D11_VPIV_DIMENSION_TEXTURE2D, { 0, 0 }
+ };
+ ComPtr<ID3D11VideoProcessorInputView> inputView;
+ hr = m_videoDevice->CreateVideoProcessorInputView(
+ texture, m_videoEnumerator.Get(), &inputViewDesc, &inputView);
+ RETURN_VOID_IF_FAILED("Failed to create video input view");
+
+ ComPtr<ID3D11DeviceContext> context;
+ ComPtr<ID3D11VideoContext> videoContext;
+ m_d3dDevice->GetImmediateContext(&context);
+ hr = context.As(&videoContext);
+ RETURN_VOID_IF_FAILED("Failed to get video context");
+
+ D3D11_VIDEO_PROCESSOR_STREAM stream = { TRUE };
+ stream.pInputSurface = inputView.Get();
+ hr = videoContext->VideoProcessorBlt(
+ m_videoProcessor.Get(), m_outputView.Get(), 0, 1, &stream);
+ RETURN_VOID_IF_FAILED("Failed to get blit video frame");
+ }
+
+private:
+ ComPtr<ID3D11Device> m_d3dDevice;
+ ComPtr<ID3D11Texture2D> m_targetTexture;
+ ID3D11Texture2D *m_target;
+ ComPtr<ID3D11VideoDevice> m_videoDevice;
+ ComPtr<ID3D11VideoProcessorEnumerator> m_videoEnumerator;
+ ComPtr<ID3D11VideoProcessor> m_videoProcessor;
+ ComPtr<ID3D11VideoProcessorOutputView> m_outputView;
+};
+
+class QWinRTCameraVideoRendererControlPrivate
+{
+public:
+ QScopedPointer<D3DVideoBlitter> blitter;
+ QVector<ComPtr<IMF2DBuffer>> buffers;
+};
+
+QWinRTCameraVideoRendererControl::QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent)
+ : QWinRTAbstractVideoRendererControl(size, parent), d_ptr(new QWinRTCameraVideoRendererControlPrivate)
+{
+}
+
+QWinRTCameraVideoRendererControl::~QWinRTCameraVideoRendererControl()
+{
+ shutdown();
+}
+
+bool QWinRTCameraVideoRendererControl::render(ID3D11Texture2D *target)
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+
+ if (d->buffers.isEmpty()) {
+ emit bufferRequested();
+ return false;
+ }
+
+ HRESULT hr;
+ ComPtr<IMF2DBuffer> buffer = d->buffers.takeFirst();
+
+ ComPtr<ID3D11Texture2D> sourceTexture;
+ ComPtr<IMFDXGIBuffer> dxgiBuffer;
+ hr = buffer.As(&dxgiBuffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = dxgiBuffer->GetResource(IID_PPV_ARGS(&sourceTexture));
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "The video frame does not support texture output; aborting rendering.");
+ return false;
+ }
+
+ ComPtr<ID3D11Device> device;
+ sourceTexture->GetDevice(&device);
+ if (!d->blitter || d->blitter->device() != device.Get() || d->blitter->target() != target)
+ d->blitter.reset(new D3DVideoBlitter(device.Get(), target));
+
+ d->blitter->blit(sourceTexture.Get());
+
+ emit bufferRequested();
+ return true;
+}
+
+void QWinRTCameraVideoRendererControl::queueBuffer(IMF2DBuffer *buffer)
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+ Q_ASSERT(buffer);
+ d->buffers.append(buffer);
+}
+
+void QWinRTCameraVideoRendererControl::discardBuffers()
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+ d->buffers.clear();
+}
diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.h b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h
new file mode 100644
index 000000000..ed8b3388d
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QWINRTCAMERAVIDEORENDERERCONTROL_H
+#define QWINRTCAMERAVIDEORENDERERCONTROL_H
+
+#include "qwinrtabstractvideorenderercontrol.h"
+
+struct IMF2DBuffer;
+
+QT_BEGIN_NAMESPACE
+
+class QVideoSurfaceFormat;
+class QWinRTCameraVideoRendererControlPrivate;
+class QWinRTCameraVideoRendererControl : public QWinRTAbstractVideoRendererControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent);
+ ~QWinRTCameraVideoRendererControl();
+
+ bool render(ID3D11Texture2D *texture) Q_DECL_OVERRIDE;
+ void queueBuffer(IMF2DBuffer *buffer);
+ void discardBuffers();
+
+signals:
+ void bufferRequested();
+
+private:
+ QScopedPointer<QWinRTCameraVideoRendererControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraVideoRendererControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAVIDEORENDERERCONTROL_H
diff --git a/src/plugins/winrt/qwinrtserviceplugin.cpp b/src/plugins/winrt/qwinrtserviceplugin.cpp
index 5d49b44a4..036d63e39 100644
--- a/src/plugins/winrt/qwinrtserviceplugin.cpp
+++ b/src/plugins/winrt/qwinrtserviceplugin.cpp
@@ -44,6 +44,8 @@
#include "qwinrtserviceplugin.h"
#include "qwinrtmediaplayerservice.h"
+#include "qwinrtcameraservice.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
QT_USE_NAMESPACE
@@ -52,6 +54,9 @@ QMediaService *QWinRTServicePlugin::create(QString const &key)
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
return new QWinRTMediaPlayerService(this);
+ if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+ return new QWinRTCameraService(this);
+
return Q_NULLPTR;
}
@@ -68,3 +73,37 @@ QMediaServiceProviderHint::Features QWinRTServicePlugin::supportedFeatures(
return QMediaServiceProviderHint::Features();
}
+
+QCamera::Position QWinRTServicePlugin::cameraPosition(const QByteArray &device) const
+{
+ return QWinRTVideoDeviceSelectorControl::cameraPosition(device);
+}
+
+int QWinRTServicePlugin::cameraOrientation(const QByteArray &device) const
+{
+ return QWinRTVideoDeviceSelectorControl::cameraOrientation(device);
+}
+
+QList<QByteArray> QWinRTServicePlugin::devices(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::deviceNames();
+
+ return QList<QByteArray>();
+}
+
+QString QWinRTServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::deviceDescription(device);
+
+ return QString();
+}
+
+QByteArray QWinRTServicePlugin::defaultDevice(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::defaultDeviceName();
+
+ return QByteArray();
+}
diff --git a/src/plugins/winrt/qwinrtserviceplugin.h b/src/plugins/winrt/qwinrtserviceplugin.h
index aaac79c7b..9fabadb4f 100644
--- a/src/plugins/winrt/qwinrtserviceplugin.h
+++ b/src/plugins/winrt/qwinrtserviceplugin.h
@@ -48,15 +48,29 @@ QT_USE_NAMESPACE
class QWinRTServicePlugin : public QMediaServiceProviderPlugin
, public QMediaServiceFeaturesInterface
+ , public QMediaServiceCameraInfoInterface
+ , public QMediaServiceSupportedDevicesInterface
+ , public QMediaServiceDefaultDeviceInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_INTERFACES(QMediaServiceCameraInfoInterface)
+ Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
+ Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "winrt.json")
public:
QMediaService *create(QString const &key);
void release(QMediaService *service);
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
+
+ QCamera::Position cameraPosition(const QByteArray &device) const Q_DECL_OVERRIDE;
+ int cameraOrientation(const QByteArray &device) const Q_DECL_OVERRIDE;
+
+ QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
+ QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
+
+ QByteArray defaultDevice(const QByteArray &service) const Q_DECL_OVERRIDE;
};
#endif // QWINRTSERVICEPLUGIN_H
diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp
new file mode 100644
index 000000000..8058c3dad
--- /dev/null
+++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwinrtvideodeviceselectorcontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QVector>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QEventLoop>
+#include <QtCore/QGlobalStatic>
+
+#include <wrl.h>
+#include <windows.devices.enumeration.h>
+
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+typedef ITypedEventHandler<DeviceWatcher *, DeviceInformation *> DeviceInformationHandler;
+typedef ITypedEventHandler<DeviceWatcher *, DeviceInformationUpdate *> DeviceInformationUpdateHandler;
+typedef ITypedEventHandler<DeviceWatcher *, IInspectable *> DeviceEnumerationCompletedHandler;
+
+QT_USE_NAMESPACE
+
+static QString deviceName(IDeviceInformation *device)
+{
+ HRESULT hr;
+ HString id;
+ hr = device->get_Id(id.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 length;
+ const wchar_t *buffer = id.GetRawBuffer(&length);
+ return QString::fromWCharArray(buffer, length);
+}
+
+static QString deviceDescription(IDeviceInformation *device)
+{
+ HRESULT hr;
+ HString name;
+ hr = device->get_Name(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 length;
+ const wchar_t *buffer = name.GetRawBuffer(&length);
+ return QString::fromWCharArray(buffer, length);
+}
+
+struct QWinRTVideoDeviceSelectorControlGlobal
+{
+ QWinRTVideoDeviceSelectorControlGlobal()
+ : defaultDeviceIndex(-1)
+ {
+ HRESULT hr;
+ ComPtr<IDeviceInformationStatics> deviceWatcherFactory;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(),
+ IID_PPV_ARGS(&deviceWatcherFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcherFactory->CreateWatcherDeviceClass(DeviceClass_VideoCapture, &deviceWatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Added(
+ Callback<DeviceInformationHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceAdded).Get(),
+ &deviceAddedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Removed(
+ Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceRemoved).Get(),
+ &deviceRemovedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Updated(
+ Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceUpdated).Get(),
+ &deviceUpdatedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Synchronously populate the devices on construction
+ ComPtr<IAsyncOperation<DeviceInformationCollection *>> op;
+ hr = deviceWatcherFactory->FindAllAsyncDeviceClass(DeviceClass_VideoCapture, &op);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<DeviceInformation *>> deviceList;
+ hr = QWinRTFunctions::await(op, deviceList.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 deviceCount;
+ hr = deviceList->get_Size(&deviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (quint32 i = 0; i < deviceCount; ++i) {
+ IDeviceInformation *device;
+ hr = deviceList->GetAt(i, &device);
+ Q_ASSERT_SUCCEEDED(hr);
+ onDeviceAdded(Q_NULLPTR, device);
+ }
+
+ // If there is no default device provided by the API, choose the first one
+ if (!devices.isEmpty() && defaultDeviceIndex < 0)
+ defaultDeviceIndex = 0;
+ }
+
+ ~QWinRTVideoDeviceSelectorControlGlobal()
+ {
+ HRESULT hr;
+ hr = deviceWatcher->remove_Added(deviceAddedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcher->remove_Removed(deviceRemovedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcher->remove_Updated(deviceUpdatedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+private:
+ HRESULT onDeviceAdded(IDeviceWatcher *, IDeviceInformation *device)
+ {
+ const QString name = deviceName(device);
+ if (deviceIndex.contains(name))
+ return S_OK;
+
+ devices.append(device);
+ const int index = devices.size() - 1;
+ deviceIndex.insert(name, index);
+
+ HRESULT hr;
+ boolean isDefault;
+ hr = device->get_IsDefault(&isDefault);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (isDefault)
+ defaultDeviceIndex = index;
+
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+ HRESULT onDeviceRemoved(IDeviceWatcher *, IDeviceInformationUpdate *device)
+ {
+ HRESULT hr;
+ HString id;
+ hr = device->get_Id(id.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ HString name;
+ hr = device->get_Id(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 nameLength;
+ const wchar_t *nameString = name.GetRawBuffer(&nameLength);
+ const int index = deviceIndex.take(QString::fromWCharArray(nameString, nameLength));
+ if (index >= 0)
+ devices.remove(index);
+
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+ HRESULT onDeviceUpdated(IDeviceWatcher *, IDeviceInformationUpdate *)
+ {
+ // A name or description may have changed, so emit devicesChanged
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+public:
+ void addWatcher(QWinRTVideoDeviceSelectorControl *control)
+ {
+ watchers.append(control);
+
+ HRESULT hr;
+ DeviceWatcherStatus status;
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (status != DeviceWatcherStatus_Started) {
+ // We can't immediately Start() if we have just called Stop()
+ while (status == DeviceWatcherStatus_Stopping) {
+ QThread::yieldCurrentThread();
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ hr = deviceWatcher->Start();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ }
+
+ void removeWatcher(QWinRTVideoDeviceSelectorControl *control)
+ {
+ watchers.removeAll(control);
+
+ if (!watchers.isEmpty())
+ return;
+
+ HRESULT hr;
+ DeviceWatcherStatus status;
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (status == DeviceWatcherStatus_Stopped || status == DeviceWatcherStatus_Stopping)
+ return;
+
+ hr = deviceWatcher->Stop();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ QVector<ComPtr<IDeviceInformation>> devices;
+ QHash<QString, int> deviceIndex;
+ int defaultDeviceIndex;
+
+private:
+ ComPtr<IDeviceWatcher> deviceWatcher;
+ QList<QWinRTVideoDeviceSelectorControl *> watchers;
+ EventRegistrationToken deviceAddedToken;
+ EventRegistrationToken deviceRemovedToken;
+ EventRegistrationToken deviceUpdatedToken;
+};
+Q_GLOBAL_STATIC(QWinRTVideoDeviceSelectorControlGlobal, g)
+
+class QWinRTVideoDeviceSelectorControlPrivate
+{
+public:
+ int selectedDevice;
+};
+
+QWinRTVideoDeviceSelectorControl::QWinRTVideoDeviceSelectorControl(QObject *parent)
+ : QVideoDeviceSelectorControl(parent), d_ptr(new QWinRTVideoDeviceSelectorControlPrivate)
+{
+ Q_D(QWinRTVideoDeviceSelectorControl);
+ d->selectedDevice = -1;
+ g->addWatcher(this);
+}
+
+QWinRTVideoDeviceSelectorControl::~QWinRTVideoDeviceSelectorControl()
+{
+ if (g.isDestroyed())
+ return;
+
+ g->removeWatcher(this);
+}
+
+int QWinRTVideoDeviceSelectorControl::deviceCount() const
+{
+ return g->devices.size();
+}
+
+QString QWinRTVideoDeviceSelectorControl::deviceName(int index) const
+{
+ if (index < 0 || index >= g->devices.size())
+ return QString();
+
+ return ::deviceName(g->devices.at(index).Get());
+}
+
+QString QWinRTVideoDeviceSelectorControl::deviceDescription(int index) const
+{
+ if (index < 0 || index >= g->devices.size())
+ return QString();
+
+ return ::deviceDescription(g->devices.at(index).Get());
+}
+
+int QWinRTVideoDeviceSelectorControl::defaultDevice() const
+{
+ return g->defaultDeviceIndex;
+}
+
+int QWinRTVideoDeviceSelectorControl::selectedDevice() const
+{
+ Q_D(const QWinRTVideoDeviceSelectorControl);
+ return d->selectedDevice;
+}
+
+QCamera::Position QWinRTVideoDeviceSelectorControl::cameraPosition(const QString &deviceName)
+{
+ int deviceIndex = g->deviceIndex.value(deviceName);
+ IDeviceInformation *deviceInfo = g->devices.value(deviceIndex).Get();
+ if (!deviceInfo)
+ return QCamera::UnspecifiedPosition;
+
+ ComPtr<IEnclosureLocation> enclosureLocation;
+ HRESULT hr;
+ hr = deviceInfo->get_EnclosureLocation(&enclosureLocation);
+ RETURN_IF_FAILED("Failed to get camera enclosure location", return QCamera::UnspecifiedPosition);
+ if (!enclosureLocation)
+ return QCamera::UnspecifiedPosition;
+
+ Panel panel;
+ hr = enclosureLocation->get_Panel(&panel);
+ RETURN_IF_FAILED("Failed to get camera panel location", return QCamera::UnspecifiedPosition);
+
+ switch (panel) {
+ case Panel_Front:
+ return QCamera::FrontFace;
+ case Panel_Back:
+ return QCamera::BackFace;
+ default:
+ break;
+ }
+ return QCamera::UnspecifiedPosition;
+}
+
+int QWinRTVideoDeviceSelectorControl::cameraOrientation(const QString &deviceName)
+{
+ Q_UNUSED(deviceName);
+ return 0;
+}
+
+QList<QByteArray> QWinRTVideoDeviceSelectorControl::deviceNames()
+{
+ QList<QByteArray> devices;
+ foreach (const QString &device, g->deviceIndex.keys())
+ devices.append(device.toUtf8());
+
+ return devices;
+}
+
+QByteArray QWinRTVideoDeviceSelectorControl::deviceDescription(const QByteArray &deviceName)
+{
+ int deviceIndex = g->deviceIndex.value(QString::fromUtf8(deviceName), -1);
+ if (deviceIndex < 0)
+ return QByteArray();
+
+ return ::deviceDescription(g->devices.value(deviceIndex).Get()).toUtf8();
+}
+
+QByteArray QWinRTVideoDeviceSelectorControl::defaultDeviceName()
+{
+ if (g->defaultDeviceIndex < 0)
+ return QByteArray();
+
+ return ::deviceName(g->devices.value(g->defaultDeviceIndex).Get()).toUtf8();
+}
+
+void QWinRTVideoDeviceSelectorControl::setSelectedDevice(int index)
+{
+ Q_D(QWinRTVideoDeviceSelectorControl);
+
+ int selectedDevice = index;
+ if (index < 0 || index >= g->devices.size())
+ selectedDevice = -1;
+
+ if (d->selectedDevice != selectedDevice) {
+ d->selectedDevice = selectedDevice;
+ emit selectedDeviceChanged(d->selectedDevice);
+ emit selectedDeviceChanged(deviceName(d->selectedDevice));
+ }
+}
diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h
new file mode 100644
index 000000000..2143b3ea8
--- /dev/null
+++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QWINRTVIDEODEVICESELECTORCONTROL_H
+#define QWINRTVIDEODEVICESELECTORCONTROL_H
+
+#include <QtMultimedia/QVideoDeviceSelectorControl>
+#include <QtMultimedia/QCameraInfoControl>
+#include <QtCore/qt_windows.h>
+
+struct IInspectable;
+namespace ABI {
+ namespace Windows {
+ namespace Devices {
+ namespace Enumeration {
+ struct IDeviceInformation;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTVideoDeviceSelectorControlPrivate;
+class QWinRTVideoDeviceSelectorControl : public QVideoDeviceSelectorControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTVideoDeviceSelectorControl(QObject *parent = 0);
+ ~QWinRTVideoDeviceSelectorControl();
+
+ int deviceCount() const Q_DECL_OVERRIDE;
+
+ QString deviceName(int index) const Q_DECL_OVERRIDE;
+ QString deviceDescription(int index) const Q_DECL_OVERRIDE;
+
+ int defaultDevice() const Q_DECL_OVERRIDE;
+ int selectedDevice() const Q_DECL_OVERRIDE;
+
+ static QCamera::Position cameraPosition(const QString &deviceName);
+ static int cameraOrientation(const QString &deviceName);
+ static QList<QByteArray> deviceNames();
+ static QByteArray deviceDescription(const QByteArray &deviceName);
+ static QByteArray defaultDeviceName();
+
+public slots:
+ void setSelectedDevice(int index) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWinRTVideoDeviceSelectorControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTVideoDeviceSelectorControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTVIDEODEVICESELECTORCONTROL_H
diff --git a/src/plugins/winrt/winrt.json b/src/plugins/winrt/winrt.json
index b85cfeb12..9af79cc37 100644
--- a/src/plugins/winrt/winrt.json
+++ b/src/plugins/winrt/winrt.json
@@ -1,4 +1,4 @@
{
"Keys": ["winrt"],
- "Services": ["org.qt-project.qt.mediaplayer"]
+ "Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.camera"]
}
diff --git a/src/plugins/winrt/winrt.pro b/src/plugins/winrt/winrt.pro
index 0ea90d22e..04db71e75 100644
--- a/src/plugins/winrt/winrt.pro
+++ b/src/plugins/winrt/winrt.pro
@@ -5,21 +5,33 @@ PLUGIN_TYPE=mediaservice
PLUGIN_CLASS_NAME = WinRTServicePlugin
load(qt_plugin)
-LIBS += -lmfplat -lmfuuid -loleaut32 -ld3d11
+LIBS += -lmfplat -lmfuuid -loleaut32 -ld3d11 -lruntimeobject
HEADERS += \
qwinrtabstractvideorenderercontrol.h \
+ qwinrtcameracontrol.h \
+ qwinrtcamerainfocontrol.h \
+ qwinrtcameraimagecapturecontrol.h \
+ qwinrtcameraservice.h \
+ qwinrtcameravideorenderercontrol.h \
qwinrtmediaplayercontrol.h \
qwinrtmediaplayerservice.h \
qwinrtplayerrenderercontrol.h \
- qwinrtserviceplugin.h
+ qwinrtserviceplugin.h \
+ qwinrtvideodeviceselectorcontrol.h
SOURCES += \
qwinrtabstractvideorenderercontrol.cpp \
+ qwinrtcameracontrol.cpp \
+ qwinrtcamerainfocontrol.cpp \
+ qwinrtcameraimagecapturecontrol.cpp \
+ qwinrtcameraservice.cpp \
+ qwinrtcameravideorenderercontrol.cpp \
qwinrtmediaplayercontrol.cpp \
qwinrtmediaplayerservice.cpp \
qwinrtplayerrenderercontrol.cpp \
- qwinrtserviceplugin.cpp
+ qwinrtserviceplugin.cpp \
+ qwinrtvideodeviceselectorcontrol.cpp
OTHER_FILES += \
winrt.json
diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
index 93c1841bc..da69f926f 100644
--- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
+++ b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
@@ -236,7 +236,6 @@ void MFAudioDecoderControl::handleMediaSourceReady()
}
if (m_sourceResolver->mediaSource()) {
- IMFPresentationDescriptor *pd = 0;
if (mediaType && m_resampler) {
HRESULT hr = S_OK;
hr = m_resampler->SetInputType(m_mfInputStreamID, mediaType, 0);
@@ -246,9 +245,11 @@ void MFAudioDecoderControl::handleMediaSourceReady()
qWarning() << "MFAudioDecoderControl: failed to SetInputType of resampler" << hr;
}
}
+ IMFPresentationDescriptor *pd;
if (SUCCEEDED(m_sourceResolver->mediaSource()->CreatePresentationDescriptor(&pd))) {
UINT64 duration = 0;
pd->GetUINT64(MF_PD_DURATION, &duration);
+ pd->Release();
duration /= 10000;
if (m_duration != qint64(duration)) {
m_duration = qint64(duration);
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp
index a1b63321c..42d0dea4e 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/wmf/evrd3dpresentengine.cpp
@@ -48,7 +48,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <WinUser.h>
@@ -331,34 +330,36 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
IMFMediaBuffer* buffer = NULL;
IDirect3DSurface9* surface = NULL;
- if (sample) {
- // Get the buffer from the sample.
- hr = sample->GetBufferByIndex(0, &buffer);
- if (FAILED(hr))
- goto done;
+ if (m_surface && m_surface->isActive()) {
+ if (sample) {
+ // Get the buffer from the sample.
+ hr = sample->GetBufferByIndex(0, &buffer);
+ if (FAILED(hr))
+ goto done;
+
+ // Get the surface from the buffer.
+ hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
+ if (FAILED(hr))
+ goto done;
+ }
- // Get the surface from the buffer.
- hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
- if (FAILED(hr))
- goto done;
- }
+ if (surface && updateTexture(surface)) {
+ QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
+ m_surfaceFormat.frameSize(),
+ m_surfaceFormat.pixelFormat());
- if (surface && updateTexture(surface)) {
- QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ LONGLONG startTime = -1;
+ if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
+ frame.setStartTime(startTime * 0.1);
- // WMF uses 100-nanosecond units, Qt uses microseconds
- LONGLONG startTime = -1;
- if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
- frame.setStartTime(startTime * 0.1);
+ LONGLONG duration = -1;
+ if (SUCCEEDED(sample->GetSampleDuration(&duration)))
+ frame.setEndTime((startTime + duration) * 0.1);
+ }
- LONGLONG duration = -1;
- if (SUCCEEDED(sample->GetSampleDuration(&duration)))
- frame.setEndTime((startTime + duration) * 0.1);
+ m_surface->present(frame);
}
-
- m_surface->present(frame);
}
done:
@@ -420,18 +421,19 @@ void D3DPresentEngine::createOffscreenTexture()
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
m_eglDisplay = static_cast<EGLDisplay*>(
nativeInterface->nativeResourceForContext("eglDisplay", currentContext));
- m_eglConfig = static_cast<EGLDisplay*>(
+ m_eglConfig = static_cast<EGLConfig*>(
nativeInterface->nativeResourceForContext("eglConfig", currentContext));
currentContext->functions()->glGenTextures(1, &m_glTexture);
int w = m_surfaceFormat.frameWidth();
int h = m_surfaceFormat.frameHeight();
+ bool hasAlpha = currentContext->format().hasAlpha();
EGLint attribs[] = {
EGL_WIDTH, w,
EGL_HEIGHT, h,
- EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
EGL_NONE
};
@@ -450,7 +452,7 @@ void D3DPresentEngine::createOffscreenTexture()
m_device->CreateTexture(w, h, 1,
D3DUSAGE_RENDERTARGET,
- D3DFMT_X8R8G8B8,
+ hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&m_texture,
&share_handle);
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 77b19f1b0..a01c0b92c 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -242,14 +242,19 @@ void MFPlayerSession::handleSourceError(long hr)
void MFPlayerSession::handleMediaSourceReady()
{
- if (QMediaPlayer::LoadingMedia != m_status || !m_sourceResolver)
+ if (QMediaPlayer::LoadingMedia != m_status || !m_sourceResolver || m_sourceResolver != sender())
return;
#ifdef DEBUG_MEDIAFOUNDATION
qDebug() << "handleMediaSourceReady";
#endif
HRESULT hr = S_OK;
- IMFPresentationDescriptor* sourcePD;
IMFMediaSource* mediaSource = m_sourceResolver->mediaSource();
+
+ DWORD dwCharacteristics = 0;
+ mediaSource->GetCharacteristics(&dwCharacteristics);
+ emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
+
+ IMFPresentationDescriptor* sourcePD;
hr = mediaSource->CreatePresentationDescriptor(&sourcePD);
if (SUCCEEDED(hr)) {
m_duration = 0;
@@ -258,6 +263,7 @@ void MFPlayerSession::handleMediaSourceReady()
//convert from 100 nanosecond to milisecond
emit durationUpdate(qint64(m_duration / 10000));
setupPlaybackTopology(mediaSource, sourcePD);
+ sourcePD->Release();
} else {
changeStatus(QMediaPlayer::InvalidMedia);
emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
@@ -415,12 +421,15 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
if (SUCCEEDED(hr)) {
hr = node->SetUINT32(MF_TOPONODE_STREAMID, sinkID);
if (SUCCEEDED(hr)) {
- if (SUCCEEDED(topology->AddNode(node)))
+ if (SUCCEEDED(topology->AddNode(node))) {
+ handler->Release();
return node;
+ }
}
}
}
}
+ handler->Release();
}
node->Release();
return NULL;
@@ -609,42 +618,39 @@ HRESULT BindOutputNode(IMFTopologyNode *pNode)
// Sets the IMFStreamSink pointers on all of the output nodes in a topology.
HRESULT BindOutputNodes(IMFTopology *pTopology)
{
- DWORD cNodes = 0;
-
- IMFCollection *collection = NULL;
- IUnknown *element = NULL;
- IMFTopologyNode *node = NULL;
+ IMFCollection *collection;
// Get the collection of output nodes.
HRESULT hr = pTopology->GetOutputNodeCollection(&collection);
// Enumerate all of the nodes in the collection.
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(hr)) {
+ DWORD cNodes;
hr = collection->GetElementCount(&cNodes);
- if (SUCCEEDED(hr)) {
- for (DWORD i = 0; i < cNodes; i++) {
- hr = collection->GetElement(i, &element);
- if (FAILED(hr))
- break;
+ if (SUCCEEDED(hr)) {
+ for (DWORD i = 0; i < cNodes; i++) {
+ IUnknown *element;
+ hr = collection->GetElement(i, &element);
+ if (FAILED(hr))
+ break;
- hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
- if (FAILED(hr))
- break;
+ IMFTopologyNode *node;
+ hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
+ element->Release();
+ if (FAILED(hr))
+ break;
- // Bind this node.
- hr = BindOutputNode(node);
- if (FAILED(hr))
- break;
+ // Bind this node.
+ hr = BindOutputNode(node);
+ node->Release();
+ if (FAILED(hr))
+ break;
+ }
}
+ collection->Release();
}
- if (collection)
- collection->Release();
- if (element)
- element->Release();
- if (node)
- node->Release();
return hr;
}
@@ -1395,14 +1401,17 @@ int MFPlayerSession::bufferStatus()
if (!m_netsourceStatistics)
return 0;
PROPVARIANT var;
+ PropVariantInit(&var);
PROPERTYKEY key;
key.fmtid = MFNETSOURCE_STATISTICS;
key.pid = MFNETSOURCE_BUFFERPROGRESS_ID;
int progress = -1;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
+ // GetValue returns S_FALSE if the property is not available, which has
+ // a value > 0. We therefore can't use the SUCCEEDED macro here.
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
progress = var.lVal;
+ PropVariantClear(&var);
}
- PropVariantClear(&var);
#ifdef DEBUG_MEDIAFOUNDATION
qDebug() << "bufferStatus: progress = " << progress;
@@ -1413,22 +1422,30 @@ int MFPlayerSession::bufferStatus()
QMediaTimeRange MFPlayerSession::availablePlaybackRanges()
{
- if (!m_netsourceStatistics)
- return QMediaTimeRange();
+ // defaults to the whole media
+ qint64 start = 0;
+ qint64 end = qint64(m_duration / 10000);
- qint64 start = 0, end = 0;
- PROPVARIANT var;
- PROPERTYKEY key;
- key.fmtid = MFNETSOURCE_STATISTICS;
- key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
- start = qint64(var.uhVal.QuadPart / 10000);
- key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
- end = qint64(var.uhVal.QuadPart / 10000);
+ if (m_netsourceStatistics) {
+ PROPVARIANT var;
+ PropVariantInit(&var);
+ PROPERTYKEY key;
+ key.fmtid = MFNETSOURCE_STATISTICS;
+ key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
+ // GetValue returns S_FALSE if the property is not available, which has
+ // a value > 0. We therefore can't use the SUCCEEDED macro here.
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
+ start = qint64(var.uhVal.QuadPart / 10000);
+ PropVariantClear(&var);
+ PropVariantInit(&var);
+ key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
+ end = qint64(var.uhVal.QuadPart / 10000);
+ PropVariantClear(&var);
+ }
}
}
- PropVariantClear(&var);
+
return QMediaTimeRange(start, end);
}
@@ -1491,8 +1508,11 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
}
}
- if (!m_closing)
+ if (!m_closing) {
emit sessionEvent(pEvent);
+ } else {
+ pEvent->Release();
+ }
return S_OK;
}
@@ -1615,13 +1635,6 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
}
}
- if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
- setVolumeInternal(m_muted ? 0 : m_volume);
-
- DWORD dwCharacteristics = 0;
- m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
- emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
-
// Topology is resolved and successfuly set, this happens only after loading a new media.
// Make sure we always start the media from the beginning
m_varStart.vt = VT_I8;
@@ -1688,6 +1701,9 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
}
}
MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));
+
+ if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
+ setVolumeInternal(m_muted ? 0 : m_volume);
}
}
}
diff --git a/src/plugins/wmf/samplegrabber.cpp b/src/plugins/wmf/samplegrabber.cpp
index 016482e5d..0a11d8bb8 100644
--- a/src/plugins/wmf/samplegrabber.cpp
+++ b/src/plugins/wmf/samplegrabber.cpp
@@ -155,6 +155,9 @@ STDMETHODIMP AudioSampleGrabberCallback::OnProcessSample(REFGUID guidMajorMediaT
if (llSampleTime == _I64_MAX) {
// Set default QAudioBuffer start time
llSampleTime = -1;
+ } else {
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ llSampleTime /= 10;
}
foreach (MFAudioProbeControl* probe, m_audioProbes)
diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
index e993609ad..72cbc9614 100644
--- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
+++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
@@ -212,7 +212,7 @@ public:
stride /= 4;
}
- m_width = qreal(m_frame.width() / stride);
+ m_width = qreal(m_frame.width()) / stride;
textureSize.setWidth(stride);
if (m_textureSize != textureSize) {
diff --git a/tests/auto/integration/qmediaplayerbackend/testdata/nokia-tune.mp3 b/tests/auto/integration/qmediaplayerbackend/testdata/nokia-tune.mp3
index 674c83405..2435f65b8 100644
--- a/tests/auto/integration/qmediaplayerbackend/testdata/nokia-tune.mp3
+++ b/tests/auto/integration/qmediaplayerbackend/testdata/nokia-tune.mp3
Binary files differ
diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
index ea9dcdf36..ddf438ba6 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -39,6 +39,7 @@
#include "qaudioprobe.h"
#include "qvideoprobe.h"
#include <qmediaplaylist.h>
+#include <qmediametadata.h>
//TESTED_COMPONENT=src/multimedia
@@ -71,20 +72,24 @@ private slots:
void volumeAcrossFiles();
void initialVolume();
void seekPauseSeek();
+ void seekInStoppedState();
void subsequentPlayback();
void probes();
void playlist();
void surfaceTest_data();
void surfaceTest();
+ void metadata();
private:
QMediaContent selectVideoFile(const QStringList& mediaCandidates);
- QMediaContent selectSoundFile(const QStringList& mediaCandidates);
+ QMediaContent selectMediaFile(const QStringList& mediaCandidates);
//one second local wav file
QMediaContent localWavFile;
+ QMediaContent localWavFile2;
QMediaContent localVideoFile;
QMediaContent localCompressedSoundFile;
+ QMediaContent localFileWithMetadata;
bool m_inCISystem;
};
@@ -169,17 +174,17 @@ QMediaContent tst_QMediaPlayerBackend::selectVideoFile(const QStringList& mediaC
return QMediaContent();
}
-QMediaContent tst_QMediaPlayerBackend::selectSoundFile(const QStringList& mediaCandidates)
+QMediaContent tst_QMediaPlayerBackend::selectMediaFile(const QStringList& mediaCandidates)
{
QMediaPlayer player;
QSignalSpy errorSpy(&player, SIGNAL(error(QMediaPlayer::Error)));
foreach (QString s, mediaCandidates) {
- QFileInfo soundFile(s);
- if (!soundFile.exists())
+ QFileInfo mediaFile(s);
+ if (!mediaFile.exists())
continue;
- QMediaContent media = QMediaContent(QUrl::fromLocalFile(soundFile.absoluteFilePath()));
+ QMediaContent media = QMediaContent(QUrl::fromLocalFile(mediaFile.absoluteFilePath()));
player.setMedia(media);
player.play();
@@ -205,17 +210,26 @@ void tst_QMediaPlayerBackend::initTestCase()
localWavFile = QMediaContent(QUrl::fromLocalFile(wavFile.absoluteFilePath()));
+ const QString testFileName2 = QFINDTESTDATA("testdata/_test.wav");
+ QFileInfo wavFile2(testFileName2);
+
+ QVERIFY(wavFile2.exists());
+
+ localWavFile2 = QMediaContent(QUrl::fromLocalFile(wavFile2.absoluteFilePath()));
+
qRegisterMetaType<QMediaContent>();
QStringList mediaCandidates;
mediaCandidates << QFINDTESTDATA("testdata/colors.ogv");
mediaCandidates << QFINDTESTDATA("testdata/colors.mp4");
- localVideoFile = selectVideoFile(mediaCandidates);
+ localVideoFile = selectMediaFile(mediaCandidates);
mediaCandidates.clear();
mediaCandidates << QFINDTESTDATA("testdata/nokia-tune.mkv");
mediaCandidates << QFINDTESTDATA("testdata/nokia-tune.mp3");
- localCompressedSoundFile = selectSoundFile(mediaCandidates);
+ localCompressedSoundFile = selectMediaFile(mediaCandidates);
+
+ localFileWithMetadata = selectMediaFile(QStringList() << QFINDTESTDATA("testdata/nokia-tune.mp3"));
qgetenv("QT_TEST_CI").toInt(&m_inCISystem,10);
}
@@ -239,6 +253,7 @@ void tst_QMediaPlayerBackend::loadMedia()
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent)));
player.setMedia(localWavFile);
@@ -247,11 +262,13 @@ void tst_QMediaPlayerBackend::loadMedia()
QVERIFY(player.mediaStatus() != QMediaPlayer::NoMedia);
QVERIFY(player.mediaStatus() != QMediaPlayer::InvalidMedia);
QVERIFY(player.media() == localWavFile);
+ QVERIFY(player.currentMedia() == localWavFile);
QCOMPARE(stateSpy.count(), 0);
QVERIFY(statusSpy.count() > 0);
QCOMPARE(mediaSpy.count(), 1);
QCOMPARE(mediaSpy.last()[0].value<QMediaContent>(), localWavFile);
+ QCOMPARE(currentMediaSpy.last()[0].value<QMediaContent>(), localWavFile);
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
@@ -267,6 +284,7 @@ void tst_QMediaPlayerBackend::unloadMedia()
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent)));
QSignalSpy positionSpy(&player, SIGNAL(positionChanged(qint64)));
QSignalSpy durationSpy(&player, SIGNAL(positionChanged(qint64)));
@@ -285,6 +303,7 @@ void tst_QMediaPlayerBackend::unloadMedia()
stateSpy.clear();
statusSpy.clear();
mediaSpy.clear();
+ currentMediaSpy.clear();
positionSpy.clear();
durationSpy.clear();
@@ -295,10 +314,12 @@ void tst_QMediaPlayerBackend::unloadMedia()
QCOMPARE(player.state(), QMediaPlayer::StoppedState);
QCOMPARE(player.mediaStatus(), QMediaPlayer::NoMedia);
QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.currentMedia(), QMediaContent());
QVERIFY(!stateSpy.isEmpty());
QVERIFY(!statusSpy.isEmpty());
QVERIFY(!mediaSpy.isEmpty());
+ QVERIFY(!currentMediaSpy.isEmpty());
QVERIFY(!positionSpy.isEmpty());
}
@@ -327,7 +348,7 @@ void tst_QMediaPlayerBackend::playPauseStop()
QTRY_VERIFY(statusSpy.count() > 0 &&
statusSpy.last()[0].value<QMediaPlayer::MediaStatus>() == QMediaPlayer::BufferedMedia);
- QTRY_VERIFY(player.position() > 0);
+ QTRY_VERIFY(player.position() > 100);
QVERIFY(player.duration() > 0);
QVERIFY(positionSpy.count() > 0);
QVERIFY(positionSpy.last()[0].value<qint64>() > 0);
@@ -361,6 +382,63 @@ void tst_QMediaPlayerBackend::playPauseStop()
QCOMPARE(player.position(), qint64(0));
QCOMPARE(positionSpy.last()[0].value<qint64>(), qint64(0));
QVERIFY(player.duration() > 0);
+
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(stateSpy.count(), 1);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::PlayingState);
+ QCOMPARE(statusSpy.count(), 1); // Should not go through Loading again when play -> stop -> play
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::BufferedMedia);
+
+ player.stop();
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.setMedia(localWavFile2);
+
+ QTRY_VERIFY(statusSpy.count() > 0);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ player.play();
+
+ QTRY_VERIFY(player.position() > 100);
+
+ player.setMedia(localWavFile);
+
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), 0);
+
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.play();
+
+ QTRY_VERIFY(player.position() > 100);
+
+ player.setMedia(QMediaContent());
+
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::NoMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::NoMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), 0);
+ QCOMPARE(player.duration(), 0);
}
@@ -383,17 +461,25 @@ void tst_QMediaPlayerBackend::processEOS()
QVERIFY(statusSpy.count() > 0);
QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
//at EOS the position stays at the end of file
- QVERIFY(player.position() > 900);
+ QCOMPARE(player.position(), player.duration());
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), player.duration());
stateSpy.clear();
statusSpy.clear();
+ positionSpy.clear();
player.play();
//position is reset to start
QTRY_VERIFY(player.position() < 100);
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.first()[0].value<qint64>(), 0);
QCOMPARE(player.state(), QMediaPlayer::PlayingState);
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
@@ -406,13 +492,16 @@ void tst_QMediaPlayerBackend::processEOS()
player.setPosition(900);
//wait up to 5 seconds for EOS
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+ QVERIFY(statusSpy.count() > 0);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
- //ensure the positionChanged() signal is emitted
- QVERIFY(positionSpy.count() > 0);
-
- QCOMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
//position stays at the end of file
- QVERIFY(player.position() > 900);
+ QCOMPARE(player.position(), player.duration());
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), player.duration());
//after setPosition EndOfMedia status should be reset to Loaded
stateSpy.clear();
@@ -608,7 +697,7 @@ void tst_QMediaPlayerBackend::initialVolume()
void tst_QMediaPlayerBackend::seekPauseSeek()
{
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QMediaPlayer player;
@@ -674,6 +763,125 @@ void tst_QMediaPlayerBackend::seekPauseSeek()
}
}
+void tst_QMediaPlayerBackend::seekInStoppedState()
+{
+ if (localVideoFile.isNull())
+ QSKIP("No supported video file");
+
+ QMediaPlayer player;
+ player.setNotifyInterval(500);
+
+ QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy positionSpy(&player, SIGNAL(positionChanged(qint64)));
+
+ player.setMedia(localVideoFile);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QVERIFY(player.isSeekable());
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ qint64 position = 5000;
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+
+ // ------
+ // Same tests but after play() --> stop()
+
+ player.stop();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.position(), 0);
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+
+ // ------
+ // Same tests but after reaching the end of the media
+
+ player.setPosition(player.duration() - 500);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), player.duration());
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+}
+
void tst_QMediaPlayerBackend::subsequentPlayback()
{
#ifdef Q_OS_LINUX
@@ -717,7 +925,7 @@ void tst_QMediaPlayerBackend::subsequentPlayback()
void tst_QMediaPlayerBackend::probes()
{
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QMediaPlayer *player = new QMediaPlayer;
@@ -733,8 +941,9 @@ void tst_QMediaPlayerBackend::probes()
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), &probeHandler, SLOT(processBuffer(QAudioBuffer)));
connect(audioProbe, SIGNAL(flush()), &probeHandler, SLOT(flushAudio()));
- QVERIFY(videoProbe->setSource(player));
- QVERIFY(audioProbe->setSource(player));
+ if (!videoProbe->setSource(player))
+ QSKIP("QVideoProbe is not supported");
+ audioProbe->setSource(player);
player->setMedia(localVideoFile);
QTRY_COMPARE(player->mediaStatus(), QMediaPlayer::LoadedMedia);
@@ -831,7 +1040,7 @@ void tst_QMediaPlayerBackend::playlist()
errorSpy.clear();
// <<< Invalid2 - 1st pass >>>
- fileInfo.setFile((QFINDTESTDATA("testdata/invalid_media2.m3u")));
+ fileInfo.setFile(QFINDTESTDATA("/testdata/invalid_media2.m3u"));
player.setMedia(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
player.play();
@@ -864,7 +1073,7 @@ void tst_QMediaPlayerBackend::playlist()
errorSpy.clear();
// <<< Recursive - 1st pass >>>
- fileInfo.setFile((QFINDTESTDATA("testdata/recursive_master.m3u")));
+ fileInfo.setFile(QFINDTESTDATA("testdata/recursive_master.m3u"));
player.setMedia(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
player.play();
@@ -929,7 +1138,7 @@ void tst_QMediaPlayerBackend::surfaceTest()
{
// 25 fps video file
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QFETCH(QList<QVideoFrame::PixelFormat>, formatsList);
@@ -943,6 +1152,39 @@ void tst_QMediaPlayerBackend::surfaceTest()
QVERIFY(surface.m_totalFrames >= 25);
}
+void tst_QMediaPlayerBackend::metadata()
+{
+ if (localFileWithMetadata.isNull())
+ QSKIP("No supported media file");
+
+ QMediaPlayer player;
+
+ QSignalSpy metadataAvailableSpy(&player, SIGNAL(metaDataAvailableChanged(bool)));
+ QSignalSpy metadataChangedSpy(&player, SIGNAL(metaDataChanged()));
+
+ player.setMedia(localFileWithMetadata);
+
+ QTRY_VERIFY(player.isMetaDataAvailable());
+ QCOMPARE(metadataAvailableSpy.count(), 1);
+ QVERIFY(metadataAvailableSpy.last()[0].toBool());
+ QVERIFY(metadataChangedSpy.count() > 0);
+
+ QCOMPARE(player.metaData(QMediaMetaData::Title).toString(), QStringLiteral("Nokia Tune"));
+ QCOMPARE(player.metaData(QMediaMetaData::ContributingArtist).toString(), QStringLiteral("TestArtist"));
+ QCOMPARE(player.metaData(QMediaMetaData::AlbumTitle).toString(), QStringLiteral("TestAlbum"));
+
+ metadataAvailableSpy.clear();
+ metadataChangedSpy.clear();
+
+ player.setMedia(QMediaContent());
+
+ QVERIFY(!player.isMetaDataAvailable());
+ QCOMPARE(metadataAvailableSpy.count(), 1);
+ QVERIFY(!metadataAvailableSpy.last()[0].toBool());
+ QCOMPARE(metadataChangedSpy.count(), 1);
+ QVERIFY(player.availableMetaData().isEmpty());
+}
+
TestVideoSurface::TestVideoSurface(bool storeFrames):
m_totalFrames(0),
m_storeFrames(storeFrames)
diff --git a/tests/auto/unit/qmediaplaylist/testdata/trash.pls b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
index 639c22b0c..639c22b0c 100644
--- a/tests/auto/unit/qmediaplaylist/testdata/trash.pls
+++ b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
diff --git a/tests/auto/unit/qmediaplaylist/testdata/test.pls b/tests/auto/unit/qmediaplaylist/testdata/test.pls
index 42a14f395..18832b101 100644
--- a/tests/auto/unit/qmediaplaylist/testdata/test.pls
+++ b/tests/auto/unit/qmediaplaylist/testdata/test.pls
@@ -3,7 +3,7 @@
File1=http://test.host/path
Title1=First
Length1=-1
-File2= http://test.host/path
+File2= http://test.host/path
Title2=Second
Length2=-1
File3=testfile
diff --git a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
index a1250e59e..b867604e8 100644
--- a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
+++ b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
@@ -463,14 +463,15 @@ void tst_QMediaPlaylist::loadPLSFile()
QVERIFY(!loadFailedSpy.isEmpty());
QVERIFY(playlist.error() != QMediaPlaylist::NoError);
- // Try to load bogus playlist
+ // Try to load empty playlist
loadSpy.clear();
loadFailedSpy.clear();
- testFileName = QFINDTESTDATA("testdata/trash.pls");
+ testFileName = QFINDTESTDATA("testdata/empty.pls");
playlist.load(QUrl::fromLocalFile(testFileName));
- QTRY_VERIFY(loadSpy.isEmpty());
- QVERIFY(!loadFailedSpy.isEmpty());
- QVERIFY(playlist.error() == QMediaPlaylist::FormatError);
+ QTRY_VERIFY(!loadSpy.isEmpty());
+ QVERIFY(loadFailedSpy.isEmpty());
+ QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+ QCOMPARE(playlist.mediaCount(), 0);
// Try to load regular playlist
loadSpy.clear();
@@ -485,30 +486,30 @@ void tst_QMediaPlaylist::loadPLSFile()
QCOMPARE(playlist.media(0).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
QCOMPARE(playlist.media(1).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
testFileName = QFINDTESTDATA("testdata/testfile");
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QCOMPARE(playlist.media(2).canonicalUrl(),
QUrl::fromLocalFile(testFileName));
testFileName = QFINDTESTDATA("testdata");
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QCOMPARE(playlist.media(3).canonicalUrl(),
QUrl::fromLocalFile(testFileName + "/testdir/testfile"));
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QCOMPARE(playlist.media(4).canonicalUrl(), QUrl(QLatin1String("file:///testdir/testfile")));
QCOMPARE(playlist.media(5).canonicalUrl(), QUrl(QLatin1String("file://path/name#suffix")));
//ensure #2 suffix is not stripped from path
testFileName = QFINDTESTDATA("testdata/testfile2#suffix");
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QCOMPARE(playlist.media(6).canonicalUrl(), QUrl::fromLocalFile(testFileName));
// Try to load a totem-pl generated playlist
+ // (Format doesn't respect the spec)
loadSpy.clear();
loadFailedSpy.clear();
+ playlist.clear();
testFileName = QFINDTESTDATA("testdata/totem-pl-example.pls");
playlist.load(QUrl::fromLocalFile(testFileName));
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QTRY_VERIFY(!loadSpy.isEmpty());
- QEXPECT_FAIL("", "See QTBUG-40515", Continue);
QVERIFY(loadFailedSpy.isEmpty());
+ QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+ QCOMPARE(playlist.mediaCount(), 1);
+ QCOMPARE(playlist.media(0).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
+
// check ability to load from QNetworkRequest
loadSpy.clear();