summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorMichael Goddard <michael.goddard@nokia.com>2011-10-06 14:31:58 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-07 06:16:34 +0200
commit03f22bcdaf1f80083618856d6e4140d3062f175b (patch)
treefdfbf0895f4fbd91fb1f4a247cf09e28a1056096 /src/multimedia
parent55bc4f2b46b0099d187db16e049d760cd55626e6 (diff)
Rename QtMultimediaKit to QtMultimedia.
There are a few legacy bits left in place so it passes CI, and then qt5.git etc can be updated. Change-Id: I6b082e50e6958c72fdabc2974992e16d90dafa3a Reviewed-on: http://codereview.qt-project.org/5368 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jonas Rabbe <jonas.rabbe@nokia.com>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/audio/audio.pri60
-rw-r--r--src/multimedia/audio/qaudio.cpp103
-rw-r--r--src/multimedia/audio/qaudio.h74
-rw-r--r--src/multimedia/audio/qaudio_mac.cpp145
-rw-r--r--src/multimedia/audio/qaudio_mac_p.h145
-rw-r--r--src/multimedia/audio/qaudiodevicefactory.cpp288
-rw-r--r--src/multimedia/audio/qaudiodevicefactory_p.h100
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo.cpp483
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo.h116
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp535
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.h129
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp351
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_mac_p.h99
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp465
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.h120
-rw-r--r--src/multimedia/audio/qaudioformat.cpp407
-rw-r--r--src/multimedia/audio/qaudioformat.h109
-rw-r--r--src/multimedia/audio/qaudioinput.cpp402
-rw-r--r--src/multimedia/audio/qaudioinput.h114
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.cpp867
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.h191
-rw-r--r--src/multimedia/audio/qaudioinput_mac_p.cpp989
-rw-r--r--src/multimedia/audio/qaudioinput_mac_p.h174
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.cpp642
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.h179
-rw-r--r--src/multimedia/audio/qaudiooutput.cpp404
-rw-r--r--src/multimedia/audio/qaudiooutput.h117
-rw-r--r--src/multimedia/audio/qaudiooutput_alsa_p.cpp834
-rw-r--r--src/multimedia/audio/qaudiooutput_alsa_p.h175
-rw-r--r--src/multimedia/audio/qaudiooutput_mac_p.cpp734
-rw-r--r--src/multimedia/audio/qaudiooutput_mac_p.h174
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.cpp715
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.h175
-rw-r--r--src/multimedia/audio/qaudiopluginloader.cpp176
-rw-r--r--src/multimedia/audio/qaudiopluginloader_p.h100
-rw-r--r--src/multimedia/audio/qaudiosystem.cpp436
-rw-r--r--src/multimedia/audio/qaudiosystem.h141
-rw-r--r--src/multimedia/audio/qaudiosystemplugin.cpp143
-rw-r--r--src/multimedia/audio/qaudiosystemplugin.h96
-rw-r--r--src/multimedia/effects/effects.pri36
-rw-r--r--src/multimedia/effects/qsamplecache_p.cpp398
-rw-r--r--src/multimedia/effects/qsamplecache_p.h161
-rw-r--r--src/multimedia/effects/qsoundeffect.cpp301
-rw-r--r--src/multimedia/effects/qsoundeffect_p.h143
-rw-r--r--src/multimedia/effects/qsoundeffect_pulse_p.cpp957
-rw-r--r--src/multimedia/effects/qsoundeffect_pulse_p.h163
-rw-r--r--src/multimedia/effects/qsoundeffect_qmedia_p.cpp233
-rw-r--r--src/multimedia/effects/qsoundeffect_qmedia_p.h122
-rw-r--r--src/multimedia/effects/qsoundeffect_qsound_p.cpp222
-rw-r--r--src/multimedia/effects/qsoundeffect_qsound_p.h121
-rw-r--r--src/multimedia/effects/qwavedecoder_p.cpp232
-rw-r--r--src/multimedia/effects/qwavedecoder_p.h137
-rw-r--r--src/multimedia/multimedia.pro156
-rw-r--r--src/multimedia/qaudiocapturesource.cpp275
-rw-r--r--src/multimedia/qaudiocapturesource.h103
-rw-r--r--src/multimedia/qaudioencodercontrol.cpp167
-rw-r--r--src/multimedia/qaudioencodercontrol.h95
-rw-r--r--src/multimedia/qaudioendpointselector.cpp140
-rw-r--r--src/multimedia/qaudioendpointselector.h86
-rw-r--r--src/multimedia/qaudionamespace.qdoc70
-rw-r--r--src/multimedia/qcamera.cpp1035
-rw-r--r--src/multimedia/qcamera.h238
-rw-r--r--src/multimedia/qcameracapturebufferformatcontrol.cpp117
-rw-r--r--src/multimedia/qcameracapturebufferformatcontrol.h81
-rw-r--r--src/multimedia/qcameracapturedestinationcontrol.cpp121
-rw-r--r--src/multimedia/qcameracapturedestinationcontrol.h81
-rw-r--r--src/multimedia/qcameracontrol.cpp215
-rw-r--r--src/multimedia/qcameracontrol.h101
-rw-r--r--src/multimedia/qcameraexposure.cpp646
-rw-r--r--src/multimedia/qcameraexposure.h185
-rw-r--r--src/multimedia/qcameraexposurecontrol.cpp252
-rw-r--r--src/multimedia/qcameraexposurecontrol.h124
-rw-r--r--src/multimedia/qcameraflashcontrol.cpp141
-rw-r--r--src/multimedia/qcameraflashcontrol.h87
-rw-r--r--src/multimedia/qcamerafocus.cpp478
-rw-r--r--src/multimedia/qcamerafocus.h183
-rw-r--r--src/multimedia/qcamerafocuscontrol.cpp253
-rw-r--r--src/multimedia/qcamerafocuscontrol.h103
-rw-r--r--src/multimedia/qcameraimagecapture.cpp681
-rw-r--r--src/multimedia/qcameraimagecapture.h170
-rw-r--r--src/multimedia/qcameraimagecapturecontrol.cpp208
-rw-r--r--src/multimedia/qcameraimagecapturecontrol.h99
-rw-r--r--src/multimedia/qcameraimageprocessing.cpp352
-rw-r--r--src/multimedia/qcameraimageprocessing.h124
-rw-r--r--src/multimedia/qcameraimageprocessingcontrol.cpp169
-rw-r--r--src/multimedia/qcameraimageprocessingcontrol.h100
-rw-r--r--src/multimedia/qcameralockscontrol.cpp134
-rw-r--r--src/multimedia/qcameralockscontrol.h86
-rw-r--r--src/multimedia/qimageencodercontrol.cpp142
-rw-r--r--src/multimedia/qimageencodercontrol.h91
-rw-r--r--src/multimedia/qlocalmediaplaylistprovider.cpp194
-rw-r--r--src/multimedia/qlocalmediaplaylistprovider.h87
-rw-r--r--src/multimedia/qmediabackgroundplaybackcontrol.cpp149
-rw-r--r--src/multimedia/qmediabackgroundplaybackcontrol.h83
-rw-r--r--src/multimedia/qmediabindableinterface.cpp85
-rw-r--r--src/multimedia/qmediabindableinterface.h77
-rw-r--r--src/multimedia/qmediacontainercontrol.cpp126
-rw-r--r--src/multimedia/qmediacontainercontrol.h80
-rw-r--r--src/multimedia/qmediacontent.cpp254
-rw-r--r--src/multimedia/qmediacontent.h95
-rw-r--r--src/multimedia/qmediacontrol.cpp138
-rw-r--r--src/multimedia/qmediacontrol.h87
-rw-r--r--src/multimedia/qmediacontrol_p.h80
-rw-r--r--src/multimedia/qmediaencodersettings.cpp822
-rw-r--r--src/multimedia/qmediaencodersettings.h168
-rw-r--r--src/multimedia/qmediaenumdebug.h79
-rw-r--r--src/multimedia/qmediaimageviewer.cpp604
-rw-r--r--src/multimedia/qmediaimageviewer.h142
-rw-r--r--src/multimedia/qmediaimageviewerservice.cpp463
-rw-r--r--src/multimedia/qmediaimageviewerservice_p.h147
-rw-r--r--src/multimedia/qmedianetworkaccesscontrol.cpp103
-rw-r--r--src/multimedia/qmedianetworkaccesscontrol.h83
-rw-r--r--src/multimedia/qmediaobject.cpp423
-rw-r--r--src/multimedia/qmediaobject.h118
-rw-r--r--src/multimedia/qmediaobject_p.h99
-rw-r--r--src/multimedia/qmediaplayer.cpp1139
-rw-r--r--src/multimedia/qmediaplayer.h227
-rw-r--r--src/multimedia/qmediaplayercontrol.cpp414
-rw-r--r--src/multimedia/qmediaplayercontrol.h131
-rw-r--r--src/multimedia/qmediaplaylist.cpp756
-rw-r--r--src/multimedia/qmediaplaylist.h154
-rw-r--r--src/multimedia/qmediaplaylist_p.h177
-rw-r--r--src/multimedia/qmediaplaylistcontrol.cpp219
-rw-r--r--src/multimedia/qmediaplaylistcontrol.h98
-rw-r--r--src/multimedia/qmediaplaylistioplugin.cpp204
-rw-r--r--src/multimedia/qmediaplaylistioplugin.h126
-rw-r--r--src/multimedia/qmediaplaylistnavigator.cpp568
-rw-r--r--src/multimedia/qmediaplaylistnavigator.h115
-rw-r--r--src/multimedia/qmediaplaylistprovider.cpp329
-rw-r--r--src/multimedia/qmediaplaylistprovider.h115
-rw-r--r--src/multimedia/qmediaplaylistprovider_p.h80
-rw-r--r--src/multimedia/qmediaplaylistsourcecontrol.cpp128
-rw-r--r--src/multimedia/qmediaplaylistsourcecontrol.h82
-rw-r--r--src/multimedia/qmediapluginloader.cpp213
-rw-r--r--src/multimedia/qmediapluginloader_p.h99
-rw-r--r--src/multimedia/qmediarecorder.cpp904
-rw-r--r--src/multimedia/qmediarecorder.h197
-rw-r--r--src/multimedia/qmediarecordercontrol.cpp209
-rw-r--r--src/multimedia/qmediarecordercontrol.h101
-rw-r--r--src/multimedia/qmediaresource.cpp440
-rw-r--r--src/multimedia/qmediaresource.h134
-rw-r--r--src/multimedia/qmediaservice.cpp151
-rw-r--r--src/multimedia/qmediaservice.h97
-rw-r--r--src/multimedia/qmediaservice_p.h80
-rw-r--r--src/multimedia/qmediaserviceprovider.cpp783
-rw-r--r--src/multimedia/qmediaserviceprovider.h186
-rw-r--r--src/multimedia/qmediaserviceproviderplugin.h129
-rw-r--r--src/multimedia/qmediastreamscontrol.cpp161
-rw-r--r--src/multimedia/qmediastreamscontrol.h95
-rw-r--r--src/multimedia/qmediatimerange.cpp759
-rw-r--r--src/multimedia/qmediatimerange.h140
-rw-r--r--src/multimedia/qmetadatareadercontrol.cpp163
-rw-r--r--src/multimedia/qmetadatareadercontrol.h92
-rw-r--r--src/multimedia/qmetadatawritercontrol.cpp195
-rw-r--r--src/multimedia/qmetadatawritercontrol.h97
-rw-r--r--src/multimedia/qradiotuner.cpp614
-rw-r--r--src/multimedia/qradiotuner.h158
-rw-r--r--src/multimedia/qradiotunercontrol.cpp364
-rw-r--r--src/multimedia/qradiotunercontrol.h123
-rw-r--r--src/multimedia/qtmedianamespace.h339
-rw-r--r--src/multimedia/qtmedianamespace.qdoc208
-rw-r--r--src/multimedia/qtmultimediadefs.h90
-rw-r--r--src/multimedia/qvideodevicecontrol.cpp159
-rw-r--r--src/multimedia/qvideodevicecontrol.h88
-rw-r--r--src/multimedia/qvideoencodercontrol.cpp190
-rw-r--r--src/multimedia/qvideoencodercontrol.h98
-rw-r--r--src/multimedia/qvideorenderercontrol.cpp114
-rw-r--r--src/multimedia/qvideorenderercontrol.h81
-rw-r--r--src/multimedia/qvideosurfaceoutput.cpp100
-rw-r--r--src/multimedia/qvideosurfaceoutput_p.h86
-rw-r--r--src/multimedia/video/qabstractvideobuffer.cpp202
-rw-r--r--src/multimedia/video/qabstractvideobuffer.h112
-rw-r--r--src/multimedia/video/qabstractvideobuffer_p.h88
-rw-r--r--src/multimedia/video/qabstractvideosurface.cpp340
-rw-r--r--src/multimedia/video/qabstractvideosurface.h115
-rw-r--r--src/multimedia/video/qimagevideobuffer.cpp106
-rw-r--r--src/multimedia/video/qimagevideobuffer_p.h87
-rw-r--r--src/multimedia/video/qmemoryvideobuffer.cpp132
-rw-r--r--src/multimedia/video/qmemoryvideobuffer_p.h89
-rw-r--r--src/multimedia/video/qvideoframe.cpp776
-rw-r--r--src/multimedia/video/qvideoframe.h174
-rw-r--r--src/multimedia/video/qvideosurfaceformat.cpp707
-rw-r--r--src/multimedia/video/qvideosurfaceformat.h148
-rw-r--r--src/multimedia/video/video.pri22
184 files changed, 44005 insertions, 0 deletions
diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri
new file mode 100644
index 000000000..4bedbd4d5
--- /dev/null
+++ b/src/multimedia/audio/audio.pri
@@ -0,0 +1,60 @@
+INCLUDEPATH += audio
+
+PUBLIC_HEADERS += audio/qaudio.h \
+ audio/qaudioformat.h \
+ audio/qaudioinput.h \
+ audio/qaudiooutput.h \
+ audio/qaudiodeviceinfo.h \
+ audio/qaudiosystemplugin.h \
+ audio/qaudiosystem.h
+
+PRIVATE_HEADERS += audio/qaudiodevicefactory_p.h audio/qaudiopluginloader_p.h
+
+
+SOURCES += audio/qaudio.cpp \
+ audio/qaudioformat.cpp \
+ audio/qaudiodeviceinfo.cpp \
+ audio/qaudiooutput.cpp \
+ audio/qaudioinput.cpp \
+ audio/qaudiosystemplugin.cpp \
+ audio/qaudiosystem.cpp \
+ audio/qaudiodevicefactory.cpp \
+ audio/qaudiopluginloader.cpp
+
+mac {
+ PRIVATE_HEADERS += audio/qaudioinput_mac_p.h \
+ audio/qaudiooutput_mac_p.h \
+ audio/qaudiodeviceinfo_mac_p.h \
+ audio/qaudio_mac_p.h
+
+ SOURCES += audio/qaudiodeviceinfo_mac_p.cpp \
+ audio/qaudiooutput_mac_p.cpp \
+ audio/qaudioinput_mac_p.cpp \
+ audio/qaudio_mac.cpp
+
+ LIBS += -framework ApplicationServices -framework CoreAudio -framework AudioUnit -framework AudioToolbox
+}
+
+win32 {
+ PRIVATE_HEADERS += audio/qaudioinput_win32_p.h audio/qaudiooutput_win32_p.h audio/qaudiodeviceinfo_win32_p.h
+ SOURCES += audio/qaudiodeviceinfo_win32_p.cpp \
+ audio/qaudiooutput_win32_p.cpp \
+ audio/qaudioinput_win32_p.cpp
+ LIBS += -lwinmm -lstrmiids -lole32 -loleaut32
+}
+
+unix:!mac {
+ contains(config_test_pulseaudio, yes) {
+ DEFINES += QT_NO_AUDIO_BACKEND
+ }
+ else:contains(QT_CONFIG, alsa) {
+ linux-*|freebsd-*|openbsd-* {
+ DEFINES += HAS_ALSA
+ PRIVATE_HEADERS += audio/qaudiooutput_alsa_p.h audio/qaudioinput_alsa_p.h audio/qaudiodeviceinfo_alsa_p.h
+ SOURCES += audio/qaudiodeviceinfo_alsa_p.cpp \
+ audio/qaudiooutput_alsa_p.cpp \
+ audio/qaudioinput_alsa_p.cpp
+ LIBS_PRIVATE += -lasound
+ }
+ }
+}
diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp
new file mode 100644
index 000000000..bb18f8448
--- /dev/null
+++ b/src/multimedia/audio/qaudio.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qaudio.h>
+
+
+QT_BEGIN_NAMESPACE
+
+namespace QAudio
+{
+
+class RegisterMetaTypes
+{
+public:
+ RegisterMetaTypes()
+ {
+ qRegisterMetaType<QAudio::Error>();
+ qRegisterMetaType<QAudio::State>();
+ qRegisterMetaType<QAudio::Mode>();
+ }
+
+} _register;
+
+}
+
+/*
+ \namespace QAudio
+ \brief The QAudio namespace contains enums used by the audio classes.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+*/
+
+/*
+ \enum QAudio::Error
+
+ \value NoError No errors have occurred
+ \value OpenError An error occurred opening the audio device
+ \value IOError An error occurred during read/write of audio device
+ \value UnderrunError Audio data is not being fed to the audio device at a fast enough rate
+ \value FatalError A non-recoverable error has occurred, the audio device is not usable at this time.
+*/
+
+/*
+ \enum QAudio::State
+
+ \value ActiveState Audio data is being processed, this state is set after start() is called
+ and while audio data is available to be processed.
+ \value SuspendedState The audio device is in a suspended state, this state will only be entered
+ after suspend() is called.
+ \value StoppedState The audio device is closed, and is not processing any audio data
+ \value IdleState The QIODevice passed in has no data and audio system's buffer is empty, this state
+ is set after start() is called and while no audio data is available to be processed.
+*/
+
+/*
+ \enum QAudio::Mode
+
+ \value AudioOutput audio output device
+ \value AudioInput audio input device
+*/
+
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h
new file mode 100644
index 000000000..fff1094c0
--- /dev/null
+++ b/src/multimedia/audio/qaudio.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIO_H
+#define QAUDIO_H
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+//QTM_SYNC_HEADER_EXPORT QAudio
+
+namespace QAudio
+{
+ enum Error { NoError, OpenError, IOError, UnderrunError, FatalError };
+ enum State { ActiveState, SuspendedState, StoppedState, IdleState };
+ enum Mode { AudioInput, AudioOutput };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+Q_DECLARE_METATYPE(QAudio::Error)
+Q_DECLARE_METATYPE(QAudio::State)
+Q_DECLARE_METATYPE(QAudio::Mode)
+
+#endif // QAUDIO_H
diff --git a/src/multimedia/audio/qaudio_mac.cpp b/src/multimedia/audio/qaudio_mac.cpp
new file mode 100644
index 000000000..461508304
--- /dev/null
+++ b/src/multimedia/audio/qaudio_mac.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qaudio_mac_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// Debugging
+QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat)
+{
+ dbg.nospace() << "QAudioFormat(" <<
+ audioFormat.frequency() << "," <<
+ audioFormat.channels() << "," <<
+ audioFormat.sampleSize()<< "," <<
+ audioFormat.codec() << "," <<
+ audioFormat.byteOrder() << "," <<
+ audioFormat.sampleType() << ")";
+
+ return dbg.space();
+}
+
+
+// Conversion
+QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf)
+{
+ QAudioFormat audioFormat;
+
+ audioFormat.setFrequency(sf.mSampleRate);
+ audioFormat.setChannels(sf.mChannelsPerFrame);
+ audioFormat.setSampleSize(sf.mBitsPerChannel);
+ audioFormat.setCodec(QString::fromLatin1("audio/pcm"));
+ audioFormat.setByteOrder((sf.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0 ? QAudioFormat::BigEndian : QAudioFormat::LittleEndian);
+ QAudioFormat::SampleType type = QAudioFormat::UnSignedInt;
+ if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
+ type = QAudioFormat::SignedInt;
+ else if ((sf.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
+ type = QAudioFormat::Float;
+ audioFormat.setSampleType(type);
+
+ return audioFormat;
+}
+
+AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat)
+{
+ AudioStreamBasicDescription sf;
+
+ sf.mFormatFlags = kAudioFormatFlagIsPacked;
+ sf.mSampleRate = audioFormat.frequency();
+ sf.mFramesPerPacket = 1;
+ sf.mChannelsPerFrame = audioFormat.channels();
+ sf.mBitsPerChannel = audioFormat.sampleSize();
+ sf.mBytesPerFrame = sf.mChannelsPerFrame * (sf.mBitsPerChannel / 8);
+ sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame;
+ sf.mFormatID = kAudioFormatLinearPCM;
+
+ switch (audioFormat.sampleType()) {
+ case QAudioFormat::SignedInt: sf.mFormatFlags |= kAudioFormatFlagIsSignedInteger; break;
+ case QAudioFormat::UnSignedInt: /* default */ break;
+ case QAudioFormat::Float: sf.mFormatFlags |= kAudioFormatFlagIsFloat; break;
+ case QAudioFormat::Unknown: default: break;
+ }
+
+ if (audioFormat.byteOrder() == QAudioFormat::BigEndian)
+ sf.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+
+ return sf;
+}
+
+// QAudioRingBuffer
+QAudioRingBuffer::QAudioRingBuffer(int bufferSize):
+ m_bufferSize(bufferSize)
+{
+ m_buffer = new char[m_bufferSize];
+ reset();
+}
+
+QAudioRingBuffer::~QAudioRingBuffer()
+{
+ delete m_buffer;
+}
+
+int QAudioRingBuffer::used() const
+{
+ return m_bufferUsed;
+}
+
+int QAudioRingBuffer::free() const
+{
+ return m_bufferSize - m_bufferUsed;
+}
+
+int QAudioRingBuffer::size() const
+{
+ return m_bufferSize;
+}
+
+void QAudioRingBuffer::reset()
+{
+ m_readPos = 0;
+ m_writePos = 0;
+ m_bufferUsed = 0;
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/multimedia/audio/qaudio_mac_p.h b/src/multimedia/audio/qaudio_mac_p.h
new file mode 100644
index 000000000..06ce43010
--- /dev/null
+++ b/src/multimedia/audio/qaudio_mac_p.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QAUDIO_MAC_P_H
+#define QAUDIO_MAC_P_H
+
+#include <CoreAudio/CoreAudio.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qatomic.h>
+
+#include <qaudioformat.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+extern QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat);
+
+extern QAudioFormat toQAudioFormat(const AudioStreamBasicDescription& streamFormat);
+extern AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat);
+
+class QAudioRingBuffer
+{
+public:
+ typedef QPair<char*, int> Region;
+
+ QAudioRingBuffer(int bufferSize);
+ ~QAudioRingBuffer();
+
+ Region acquireReadRegion(int size)
+ {
+ const int used = m_bufferUsed.fetchAndAddAcquire(0);
+
+ if (used > 0) {
+ const int readSize = qMin(size, qMin(m_bufferSize - m_readPos, used));
+
+ return readSize > 0 ? Region(m_buffer + m_readPos, readSize) : Region(0, 0);
+ }
+
+ return Region(0, 0);
+ }
+
+ void releaseReadRegion(Region const& region)
+ {
+ m_readPos = (m_readPos + region.second) % m_bufferSize;
+
+ m_bufferUsed.fetchAndAddRelease(-region.second);
+ }
+
+ Region acquireWriteRegion(int size)
+ {
+ const int free = m_bufferSize - m_bufferUsed.fetchAndAddAcquire(0);
+
+ if (free > 0) {
+ const int writeSize = qMin(size, qMin(m_bufferSize - m_writePos, free));
+
+ return writeSize > 0 ? Region(m_buffer + m_writePos, writeSize) : Region(0, 0);
+ }
+
+ return Region(0, 0);
+ }
+
+ void releaseWriteRegion(Region const& region)
+ {
+ m_writePos = (m_writePos + region.second) % m_bufferSize;
+
+ m_bufferUsed.fetchAndAddRelease(region.second);
+ }
+
+ int used() const;
+ int free() const;
+ int size() const;
+
+ void reset();
+
+private:
+ int m_bufferSize;
+ int m_readPos;
+ int m_writePos;
+ char* m_buffer;
+ QAtomicInt m_bufferUsed;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIO_MAC_P_H
+
+
diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp
new file mode 100644
index 000000000..19071e78f
--- /dev/null
+++ b/src/multimedia/audio/qaudiodevicefactory.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+
+#include "qaudiosystem.h"
+#include "qaudiosystemplugin.h"
+
+#include "qaudiopluginloader_p.h"
+#include "qaudiodevicefactory_p.h"
+
+#ifndef QT_NO_AUDIO_BACKEND
+#if defined(Q_OS_WIN)
+#include "qaudiodeviceinfo_win32_p.h"
+#include "qaudiooutput_win32_p.h"
+#include "qaudioinput_win32_p.h"
+#elif defined(Q_OS_MAC)
+#include "qaudiodeviceinfo_mac_p.h"
+#include "qaudiooutput_mac_p.h"
+#include "qaudioinput_mac_p.h"
+#elif defined(HAS_ALSA)
+#include "qaudiodeviceinfo_alsa_p.h"
+#include "qaudiooutput_alsa_p.h"
+#include "qaudioinput_alsa_p.h"
+#endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+Q_GLOBAL_STATIC_WITH_ARGS(QAudioPluginLoader, audioLoader,
+ (QAudioSystemFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive))
+#endif
+
+class QNullDeviceInfo : public QAbstractAudioDeviceInfo
+{
+public:
+ QAudioFormat preferredFormat() const { qWarning()<<"using null deviceinfo, none available"; return QAudioFormat(); }
+ bool isFormatSupported(const QAudioFormat& ) const { return false; }
+ QAudioFormat nearestFormat(const QAudioFormat& ) const { return QAudioFormat(); }
+ QString deviceName() const { return QString(); }
+ QStringList supportedCodecs() { return QStringList(); }
+ QList<int> supportedSampleRates() { return QList<int>(); }
+ QList<int> supportedChannelCounts() { return QList<int>(); }
+ QList<int> supportedSampleSizes() { return QList<int>(); }
+ QList<QAudioFormat::Endian> supportedByteOrders() { return QList<QAudioFormat::Endian>(); }
+ QList<QAudioFormat::SampleType> supportedSampleTypes() { return QList<QAudioFormat::SampleType>(); }
+};
+
+class QNullInputDevice : public QAbstractAudioInput
+{
+public:
+ void start(QIODevice*) { qWarning()<<"using null input device, none available";}
+ QIODevice* start() { qWarning()<<"using null input device, none available"; return 0; }
+ void stop() {}
+ void reset() {}
+ void suspend() {}
+ void resume() {}
+ int bytesReady() const { return 0; }
+ int periodSize() const { return 0; }
+ void setBufferSize(int ) {}
+ int bufferSize() const { return 0; }
+ void setNotifyInterval(int ) {}
+ int notifyInterval() const { return 0; }
+ qint64 processedUSecs() const { return 0; }
+ qint64 elapsedUSecs() const { return 0; }
+ QAudio::Error error() const { return QAudio::OpenError; }
+ QAudio::State state() const { return QAudio::StoppedState; }
+ void setFormat(const QAudioFormat&) {}
+ QAudioFormat format() const { return QAudioFormat(); }
+};
+
+class QNullOutputDevice : public QAbstractAudioOutput
+{
+public:
+ void start(QIODevice*) {qWarning()<<"using null output device, none available";}
+ QIODevice* start() { qWarning()<<"using null output device, none available"; return 0; }
+ void stop() {}
+ void reset() {}
+ void suspend() {}
+ void resume() {}
+ int bytesFree() const { return 0; }
+ int periodSize() const { return 0; }
+ void setBufferSize(int ) {}
+ int bufferSize() const { return 0; }
+ void setNotifyInterval(int ) {}
+ int notifyInterval() const { return 0; }
+ qint64 processedUSecs() const { return 0; }
+ qint64 elapsedUSecs() const { return 0; }
+ QAudio::Error error() const { return QAudio::OpenError; }
+ QAudio::State state() const { return QAudio::StoppedState; }
+ void setFormat(const QAudioFormat&) {}
+ QAudioFormat format() const { return QAudioFormat(); }
+};
+
+QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
+{
+ QList<QAudioDeviceInfo> devices;
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ foreach (const QByteArray &handle, QAudioDeviceInfoInternal::availableDevices(mode))
+ devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode);
+#endif
+#endif
+
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioPluginLoader* l = audioLoader();
+ foreach (const QString& key, l->keys()) {
+ QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(l->instance(key));
+ if (plugin) {
+ foreach (QByteArray const& handle, plugin->availableDevices(mode))
+ devices << QAudioDeviceInfo(key, handle, mode);
+ }
+
+ delete plugin;
+ }
+#endif
+
+ return devices;
+}
+
+QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
+{
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(QLatin1String("default")));
+
+ if (plugin) {
+ QList<QByteArray> list = plugin->availableDevices(QAudio::AudioInput);
+ if (list.size() > 0)
+ return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioInput);
+ }
+#endif
+
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultInputDevice(), QAudio::AudioInput);
+#endif
+#endif
+ return QAudioDeviceInfo();
+}
+
+QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice()
+{
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(QLatin1String("default")));
+
+ if (plugin) {
+ QList<QByteArray> list = plugin->availableDevices(QAudio::AudioOutput);
+ if (list.size() > 0)
+ return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioOutput);
+ }
+#endif
+
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ return QAudioDeviceInfo(QLatin1String("builtin"), QAudioDeviceInfoInternal::defaultOutputDevice(), QAudio::AudioOutput);
+#endif
+#endif
+ return QAudioDeviceInfo();
+}
+
+QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode)
+{
+ QAbstractAudioDeviceInfo *rc = 0;
+
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ if (realm == QLatin1String("builtin"))
+ return new QAudioDeviceInfoInternal(handle, mode);
+#endif
+#endif
+
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioSystemFactoryInterface* plugin =
+ qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(realm));
+
+ if (plugin)
+ rc = plugin->createDeviceInfo(handle, mode);
+#endif
+
+ return rc == 0 ? new QNullDeviceInfo() : rc;
+}
+
+QAbstractAudioInput* QAudioDeviceFactory::createDefaultInputDevice(QAudioFormat const &format)
+{
+ return createInputDevice(defaultInputDevice(), format);
+}
+
+QAbstractAudioOutput* QAudioDeviceFactory::createDefaultOutputDevice(QAudioFormat const &format)
+{
+ return createOutputDevice(defaultOutputDevice(), format);
+}
+
+QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format)
+{
+ if (deviceInfo.isNull())
+ return new QNullInputDevice();
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ if (deviceInfo.realm() == QLatin1String("builtin")) {
+ QAbstractAudioInput* p = new QAudioInputPrivate(deviceInfo.handle());
+ if (p) p->setFormat(format);
+ return p;
+ }
+#endif
+#endif
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioSystemFactoryInterface* plugin =
+ qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(deviceInfo.realm()));
+
+ if (plugin) {
+ QAbstractAudioInput* p = plugin->createInput(deviceInfo.handle());
+ if (p) p->setFormat(format);
+ return p;
+ }
+#endif
+
+ return new QNullInputDevice();
+}
+
+QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format)
+{
+ if (deviceInfo.isNull())
+ return new QNullOutputDevice();
+#ifndef QT_NO_AUDIO_BACKEND
+#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(HAS_ALSA))
+ if (deviceInfo.realm() == QLatin1String("builtin")) {
+ QAbstractAudioOutput* p = new QAudioOutputPrivate(deviceInfo.handle());
+ if (p) p->setFormat(format);
+ return p;
+ }
+#endif
+#endif
+
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QAudioSystemFactoryInterface* plugin =
+ qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(deviceInfo.realm()));
+
+ if (plugin) {
+ QAbstractAudioOutput* p = plugin->createOutput(deviceInfo.handle());
+ if (p) p->setFormat(format);
+ return p;
+ }
+#endif
+
+ return new QNullOutputDevice();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudiodevicefactory_p.h b/src/multimedia/audio/qaudiodevicefactory_p.h
new file mode 100644
index 000000000..26b3a48e5
--- /dev/null
+++ b/src/multimedia/audio/qaudiodevicefactory_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIODEVICEFACTORY_P_H
+#define QAUDIODEVICEFACTORY_P_H
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qlist.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include "qaudiodeviceinfo.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractAudioInput;
+class QAbstractAudioOutput;
+class QAbstractAudioDeviceInfo;
+
+class QAudioDeviceFactory
+{
+public:
+ static QList<QAudioDeviceInfo> availableDevices(QAudio::Mode mode);
+
+ static QAudioDeviceInfo defaultInputDevice();
+ static QAudioDeviceInfo defaultOutputDevice();
+
+ static QAbstractAudioDeviceInfo* audioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode);
+
+ static QAbstractAudioInput* createDefaultInputDevice(QAudioFormat const &format);
+ static QAbstractAudioOutput* createDefaultOutputDevice(QAudioFormat const &format);
+
+ static QAbstractAudioInput* createInputDevice(QAudioDeviceInfo const &device, QAudioFormat const &format);
+ static QAbstractAudioOutput* createOutputDevice(QAudioDeviceInfo const &device, QAudioFormat const &format);
+
+ static QAbstractAudioInput* createNullInput();
+ static QAbstractAudioOutput* createNullOutput();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIODEVICEFACTORY_P_H
+
diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp
new file mode 100644
index 000000000..f45805dbc
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo.cpp
@@ -0,0 +1,483 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudiodevicefactory_p.h"
+#include "qaudiosystem.h"
+#include "qaudiodeviceinfo.h"
+
+#include <QtCore/qmap.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAudioDeviceInfoPrivate : public QSharedData
+{
+public:
+ QAudioDeviceInfoPrivate():info(0) {}
+ QAudioDeviceInfoPrivate(const QString &r, const QByteArray &h, QAudio::Mode m):
+ realm(r), handle(h), mode(m)
+ {
+ if (!handle.isEmpty())
+ info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+ else
+ info = NULL;
+ }
+
+ QAudioDeviceInfoPrivate(const QAudioDeviceInfoPrivate &other):
+ QSharedData(other),
+ realm(other.realm), handle(other.handle), mode(other.mode)
+ {
+ info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+ }
+
+ QAudioDeviceInfoPrivate& operator=(const QAudioDeviceInfoPrivate &other)
+ {
+ delete info;
+
+ realm = other.realm;
+ handle = other.handle;
+ mode = other.mode;
+ info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+ return *this;
+ }
+
+ ~QAudioDeviceInfoPrivate()
+ {
+ delete info;
+ }
+
+ QString realm;
+ QByteArray handle;
+ QAudio::Mode mode;
+ QAbstractAudioDeviceInfo* info;
+};
+
+
+/*!
+ \class QAudioDeviceInfo
+ \brief The QAudioDeviceInfo class provides an interface to query audio devices and their functionality.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+
+ QAudioDeviceInfo lets you query for audio devices--such as sound
+ cards and USB headsets--that are currently available on the system.
+ The audio devices available are dependent on the platform or audio plugins installed.
+
+ A QAudioDeviceInfo is used by Qt to construct
+ classes that communicate with the device--such as
+ QAudioInput, and QAudioOutput.
+
+ You can also query each device for the formats it supports. A
+ format in this context is a set consisting of a specific byte
+ order, channel, codec, frequency, sample rate, and sample type. A
+ format is represented by the QAudioFormat class.
+
+ The values supported by the the device for each of these
+ parameters can be fetched with
+ supportedByteOrders(), supportedChannelCounts(), supportedCodecs(),
+ supportedSampleRates(), supportedSampleSizes(), and
+ supportedSampleTypes(). The combinations supported are dependent on the platform,
+ audio plugins installed and the audio device capabilities. If you need a
+ specific format, you can check if
+ the device supports it with isFormatSupported(), or fetch a
+ supported format that is as close as possible to the format with
+ nearestFormat(). For instance:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Setting audio format
+
+ The static
+ functions defaultInputDevice(), defaultOutputDevice(), and
+ availableDevices() let you get a list of all available
+ devices. Devices are fetched according to the value of mode
+ this is specified by the \l {QAudio}::Mode enum.
+ The QAudioDeviceInfo returned are only valid for the \l {QAudio}::Mode.
+
+ For instance:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Dumping audio formats
+
+ In this code sample, we loop through all devices that are able to output
+ sound, i.e., play an audio stream in a supported format. For each device we
+ find, we simply print the deviceName().
+
+ \sa QAudioOutput, QAudioInput
+*/
+
+/*!
+ Constructs an empty QAudioDeviceInfo object.
+*/
+QAudioDeviceInfo::QAudioDeviceInfo():
+ d(new QAudioDeviceInfoPrivate)
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+ \since 1.0
+*/
+QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceInfo& other):
+ d(other.d)
+{
+}
+
+/*!
+ Destroy this audio device info.
+*/
+QAudioDeviceInfo::~QAudioDeviceInfo()
+{
+}
+
+/*!
+ Sets the QAudioDeviceInfo object to be equal to \a other.
+ \since 1.0
+*/
+QAudioDeviceInfo& QAudioDeviceInfo::operator=(const QAudioDeviceInfo &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns whether this QAudioDeviceInfo object holds a device definition.
+ \since 1.0
+*/
+bool QAudioDeviceInfo::isNull() const
+{
+ return d->info == 0;
+}
+
+/*!
+ Returns the human readable name of the audio device.
+
+ Device names vary depending on the platform/audio plugin being used.
+
+ They are a unique string identifier for the audio device.
+
+ eg. default, Intel, U0x46d0x9a4
+ \since 1.0
+*/
+QString QAudioDeviceInfo::deviceName() const
+{
+ return isNull() ? QString() : d->info->deviceName();
+}
+
+/*!
+ Returns true if the supplied \a settings are supported by the audio
+ device described by this QAudioDeviceInfo.
+ \since 1.0
+*/
+bool QAudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const
+{
+ return isNull() ? false : d->info->isFormatSupported(settings);
+}
+
+/*!
+ Returns the default audio format settings for this device.
+
+ These settings are provided by the platform/audio plugin being used.
+
+ They are also dependent on the \l {QAudio}::Mode being used.
+
+ A typical audio system would provide something like:
+ \list
+ \o Input settings: 8000Hz mono 8 bit.
+ \o Output settings: 44100Hz stereo 16 bit little endian.
+ \endlist
+ \since 1.0
+*/
+QAudioFormat QAudioDeviceInfo::preferredFormat() const
+{
+ return isNull() ? QAudioFormat() : d->info->preferredFormat();
+}
+
+/*!
+ Returns the closest QAudioFormat to the supplied \a settings that the system supports.
+
+ These settings are provided by the platform/audio plugin being used.
+
+ They are also dependent on the \l {QAudio}::Mode being used.
+ \since 1.0
+*/
+QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const
+{
+ if (isFormatSupported(settings))
+ return settings;
+
+ QAudioFormat nearest = settings;
+
+ QList<QString> testCodecs = supportedCodecs();
+ QList<int> testChannels = supportedChannels();
+ QList<QAudioFormat::Endian> testByteOrders = supportedByteOrders();
+ QList<QAudioFormat::SampleType> testSampleTypes;
+ QList<QAudioFormat::SampleType> sampleTypesAvailable = supportedSampleTypes();
+ QMap<int,int> testFrequencies;
+ QList<int> frequenciesAvailable = supportedFrequencies();
+ QMap<int,int> testSampleSizes;
+ QList<int> sampleSizesAvailable = supportedSampleSizes();
+
+ // Get sorted lists for checking
+ if (testCodecs.contains(settings.codec())) {
+ testCodecs.removeAll(settings.codec());
+ testCodecs.insert(0, settings.codec());
+ }
+ testChannels.removeAll(settings.channels());
+ testChannels.insert(0, settings.channels());
+ testByteOrders.removeAll(settings.byteOrder());
+ testByteOrders.insert(0, settings.byteOrder());
+
+ if (sampleTypesAvailable.contains(settings.sampleType()))
+ testSampleTypes.append(settings.sampleType());
+ if (sampleTypesAvailable.contains(QAudioFormat::SignedInt))
+ testSampleTypes.append(QAudioFormat::SignedInt);
+ if (sampleTypesAvailable.contains(QAudioFormat::UnSignedInt))
+ testSampleTypes.append(QAudioFormat::UnSignedInt);
+ if (sampleTypesAvailable.contains(QAudioFormat::Float))
+ testSampleTypes.append(QAudioFormat::Float);
+
+ if (sampleSizesAvailable.contains(settings.sampleSize()))
+ testSampleSizes.insert(0,settings.sampleSize());
+ sampleSizesAvailable.removeAll(settings.sampleSize());
+ foreach (int size, sampleSizesAvailable) {
+ int larger = (size > settings.sampleSize()) ? size : settings.sampleSize();
+ int smaller = (size > settings.sampleSize()) ? settings.sampleSize() : size;
+ bool isMultiple = ( 0 == (larger % smaller));
+ int diff = larger - smaller;
+ testSampleSizes.insert((isMultiple ? diff : diff+100000), size);
+ }
+ if (frequenciesAvailable.contains(settings.frequency()))
+ testFrequencies.insert(0,settings.frequency());
+ frequenciesAvailable.removeAll(settings.frequency());
+ foreach (int frequency, frequenciesAvailable) {
+ int larger = (frequency > settings.frequency()) ? frequency : settings.frequency();
+ int smaller = (frequency > settings.frequency()) ? settings.frequency() : frequency;
+ bool isMultiple = ( 0 == (larger % smaller));
+ int diff = larger - smaller;
+ testFrequencies.insert((isMultiple ? diff : diff+100000), frequency);
+ }
+
+ // Try to find nearest
+ foreach (QString codec, testCodecs) {
+ nearest.setCodec(codec);
+ foreach (QAudioFormat::Endian order, testByteOrders) {
+ nearest.setByteOrder(order);
+ foreach (QAudioFormat::SampleType sample, testSampleTypes) {
+ nearest.setSampleType(sample);
+ QMapIterator<int, int> sz(testSampleSizes);
+ while (sz.hasNext()) {
+ sz.next();
+ nearest.setSampleSize(sz.value());
+ foreach (int channel, testChannels) {
+ nearest.setChannels(channel);
+ QMapIterator<int, int> i(testFrequencies);
+ while (i.hasNext()) {
+ i.next();
+ nearest.setFrequency(i.value());
+ if (isFormatSupported(nearest))
+ return nearest;
+ }
+ }
+ }
+ }
+ }
+ }
+ //Fallback
+ return preferredFormat();
+}
+
+/*!
+ Returns a list of supported codecs.
+
+ All platform and plugin implementations should provide support for:
+
+ "audio/pcm" - Linear PCM
+
+ For writing plugins to support additional codecs refer to:
+
+ http://www.iana.org/assignments/media-types/audio/
+ \since 1.0
+*/
+QStringList QAudioDeviceInfo::supportedCodecs() const
+{
+ return isNull() ? QStringList() : d->info->supportedCodecs();
+}
+
+/*!
+ Returns a list of supported sample rates (in Hertz).
+
+ \since 1.0
+*/
+QList<int> QAudioDeviceInfo::supportedSampleRates() const
+{
+ return supportedFrequencies();
+}
+
+/*!
+ \obsolete
+
+ Use supportedSampleRates() instead.
+ \since 1.0
+*/
+QList<int> QAudioDeviceInfo::supportedFrequencies() const
+{
+ return isNull() ? QList<int>() : d->info->supportedSampleRates();
+}
+
+/*!
+ Returns a list of supported channel counts.
+
+ This is typically 1 for mono sound, or 2 for stereo sound.
+
+ \since 1.0
+*/
+QList<int> QAudioDeviceInfo::supportedChannelCounts() const
+{
+ return supportedChannels();
+}
+
+/*!
+ \obsolete
+
+ Use supportedChannelCount() instead.
+ \since 1.0
+*/
+QList<int> QAudioDeviceInfo::supportedChannels() const
+{
+ return isNull() ? QList<int>() : d->info->supportedChannelCounts();
+}
+
+/*!
+ Returns a list of supported sample sizes (in bits).
+
+ Typically this will include 8 and 16 bit sample sizes.
+
+ \since 1.0
+*/
+QList<int> QAudioDeviceInfo::supportedSampleSizes() const
+{
+ return isNull() ? QList<int>() : d->info->supportedSampleSizes();
+}
+
+/*!
+ Returns a list of supported byte orders.
+ \since 1.0
+*/
+QList<QAudioFormat::Endian> QAudioDeviceInfo::supportedByteOrders() const
+{
+ return isNull() ? QList<QAudioFormat::Endian>() : d->info->supportedByteOrders();
+}
+
+/*!
+ Returns a list of supported sample types.
+ \since 1.0
+*/
+QList<QAudioFormat::SampleType> QAudioDeviceInfo::supportedSampleTypes() const
+{
+ return isNull() ? QList<QAudioFormat::SampleType>() : d->info->supportedSampleTypes();
+}
+
+/*!
+ Returns the information for the default input audio device.
+ All platform and audio plugin implementations provide a default audio device to use.
+ \since 1.0
+*/
+QAudioDeviceInfo QAudioDeviceInfo::defaultInputDevice()
+{
+ return QAudioDeviceFactory::defaultInputDevice();
+}
+
+/*!
+ Returns the information for the default output audio device.
+ All platform and audio plugin implementations provide a default audio device to use.
+ \since 1.0
+*/
+QAudioDeviceInfo QAudioDeviceInfo::defaultOutputDevice()
+{
+ return QAudioDeviceFactory::defaultOutputDevice();
+}
+
+/*!
+ Returns a list of audio devices that support \a mode.
+ \since 1.0
+*/
+QList<QAudioDeviceInfo> QAudioDeviceInfo::availableDevices(QAudio::Mode mode)
+{
+ return QAudioDeviceFactory::availableDevices(mode);
+}
+
+
+/*!
+ \internal
+ \since 1.0
+*/
+QAudioDeviceInfo::QAudioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode):
+ d(new QAudioDeviceInfoPrivate(realm, handle, mode))
+{
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+QString QAudioDeviceInfo::realm() const
+{
+ return d->realm;
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+QByteArray QAudioDeviceInfo::handle() const
+{
+ return d->handle;
+}
+
+
+/*!
+ \internal
+ \since 1.0
+*/
+QAudio::Mode QAudioDeviceInfo::mode() const
+{
+ return d->mode;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h
new file mode 100644
index 000000000..f16122b4d
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIODEVICEINFO_H
+#define QAUDIODEVICEINFO_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qlist.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include <qaudio.h>
+#include <qaudioformat.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioDeviceFactory;
+
+class QAudioDeviceInfoPrivate;
+class Q_MULTIMEDIA_EXPORT QAudioDeviceInfo
+{
+ friend class QAudioDeviceFactory;
+
+public:
+ QAudioDeviceInfo();
+ QAudioDeviceInfo(const QAudioDeviceInfo& other);
+ ~QAudioDeviceInfo();
+
+ QAudioDeviceInfo& operator=(const QAudioDeviceInfo& other);
+
+ bool isNull() const;
+
+ QString deviceName() const;
+
+ bool isFormatSupported(const QAudioFormat &format) const;
+ QAudioFormat preferredFormat() const;
+ QAudioFormat nearestFormat(const QAudioFormat &format) const;
+
+ QStringList supportedCodecs() const;
+ QList<int> supportedFrequencies() const;
+ QList<int> supportedSampleRates() const;
+ QList<int> supportedChannels() const;
+ QList<int> supportedChannelCounts() const;
+ QList<int> supportedSampleSizes() const;
+ QList<QAudioFormat::Endian> supportedByteOrders() const;
+ QList<QAudioFormat::SampleType> supportedSampleTypes() const;
+
+ static QAudioDeviceInfo defaultInputDevice();
+ static QAudioDeviceInfo defaultOutputDevice();
+
+ static QList<QAudioDeviceInfo> availableDevices(QAudio::Mode mode);
+
+private:
+ QAudioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode);
+ QString realm() const;
+ QByteArray handle() const;
+ QAudio::Mode mode() const;
+
+ QSharedDataPointer<QAudioDeviceInfoPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+Q_DECLARE_METATYPE(QAudioDeviceInfo)
+
+#endif // QAUDIODEVICEINFO_H
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
new file mode 100644
index 000000000..113b330d4
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
@@ -0,0 +1,535 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include "qaudiodeviceinfo_alsa_p.h"
+
+#include <alsa/version.h>
+
+QT_BEGIN_NAMESPACE
+
+QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode mode)
+{
+ handle = 0;
+
+ device = QLatin1String(dev);
+ this->mode = mode;
+
+ checkSurround();
+}
+
+QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal()
+{
+ close();
+}
+
+bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const
+{
+ return testSettings(format);
+}
+
+QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
+{
+ QAudioFormat nearest;
+ if(mode == QAudio::AudioOutput) {
+ nearest.setFrequency(44100);
+ nearest.setChannels(2);
+ nearest.setByteOrder(QAudioFormat::LittleEndian);
+ nearest.setSampleType(QAudioFormat::SignedInt);
+ nearest.setSampleSize(16);
+ nearest.setCodec(QLatin1String("audio/pcm"));
+ } else {
+ nearest.setFrequency(8000);
+ nearest.setChannels(1);
+ nearest.setSampleType(QAudioFormat::UnSignedInt);
+ nearest.setSampleSize(8);
+ nearest.setCodec(QLatin1String("audio/pcm"));
+ if(!testSettings(nearest)) {
+ nearest.setChannels(2);
+ nearest.setSampleSize(16);
+ nearest.setSampleType(QAudioFormat::SignedInt);
+ }
+ }
+ return nearest;
+}
+
+QString QAudioDeviceInfoInternal::deviceName() const
+{
+ return device;
+}
+
+QStringList QAudioDeviceInfoInternal::supportedCodecs()
+{
+ updateLists();
+ return codecz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleRates()
+{
+ updateLists();
+ return freqz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedChannelCounts()
+{
+ updateLists();
+ return channelz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleSizes()
+{
+ updateLists();
+ return sizez;
+}
+
+QList<QAudioFormat::Endian> QAudioDeviceInfoInternal::supportedByteOrders()
+{
+ updateLists();
+ return byteOrderz;
+}
+
+QList<QAudioFormat::SampleType> QAudioDeviceInfoInternal::supportedSampleTypes()
+{
+ updateLists();
+ return typez;
+}
+
+bool QAudioDeviceInfoInternal::open()
+{
+ int err = 0;
+ QString dev = device;
+ QList<QByteArray> devices = availableDevices(mode);
+
+ if(dev.compare(QLatin1String("default")) == 0) {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ if (devices.size() > 0)
+ dev = QLatin1String(devices.first().constData());
+ else
+ return false;
+#else
+ dev = QLatin1String("hw:0,0");
+#endif
+ } else {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ dev = device;
+#else
+ int idx = 0;
+ char *name;
+
+ QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1);
+
+ while(snd_card_get_name(idx,&name) == 0) {
+ if(dev.contains(QLatin1String(name)))
+ break;
+ idx++;
+ }
+ dev = QString(QLatin1String("hw:%1,0")).arg(idx);
+#endif
+ }
+ if(mode == QAudio::AudioOutput) {
+ err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
+ } else {
+ err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
+ }
+ if(err < 0) {
+ handle = 0;
+ return false;
+ }
+ return true;
+}
+
+void QAudioDeviceInfoInternal::close()
+{
+ if(handle)
+ snd_pcm_close(handle);
+ handle = 0;
+}
+
+bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const
+{
+ // Set nearest to closest settings that do work.
+ // See if what is in settings will work (return value).
+ int err = 0;
+ snd_pcm_t* handle;
+ snd_pcm_hw_params_t *params;
+ QString dev = device;
+
+ QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput);
+
+ if(dev.compare(QLatin1String("default")) == 0) {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ dev = QLatin1String(devices.first().constData());
+#else
+ dev = QLatin1String("hw:0,0");
+#endif
+ } else {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ dev = device;
+#else
+ int idx = 0;
+ char *name;
+
+ QString shortName = device.mid(device.indexOf(QLatin1String("="),0)+1);
+
+ while(snd_card_get_name(idx,&name) == 0) {
+ if(shortName.compare(QLatin1String(name)) == 0)
+ break;
+ idx++;
+ }
+ dev = QString(QLatin1String("hw:%1,0")).arg(idx);
+#endif
+ }
+ if(mode == QAudio::AudioOutput) {
+ err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
+ } else {
+ err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
+ }
+ if(err < 0) {
+ handle = 0;
+ return false;
+ }
+
+ bool testChannel = false;
+ bool testCodec = false;
+ bool testFreq = false;
+ bool testType = false;
+ bool testSize = false;
+
+ int dir = 0;
+
+ snd_pcm_nonblock( handle, 0 );
+ snd_pcm_hw_params_alloca( &params );
+ snd_pcm_hw_params_any( handle, params );
+
+ // set the values!
+ snd_pcm_hw_params_set_channels(handle,params,format.channels());
+ snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
+
+ err = -1;
+
+ switch(format.sampleSize()) {
+ case 8:
+ if(format.sampleType() == QAudioFormat::SignedInt)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
+ else if(format.sampleType() == QAudioFormat::UnSignedInt)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
+ break;
+ case 16:
+ if(format.sampleType() == QAudioFormat::SignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
+ } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
+ }
+ break;
+ case 32:
+ if(format.sampleType() == QAudioFormat::SignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
+ } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
+ }
+ }
+
+ // For now, just accept only audio/pcm codec
+ if(!format.codec().startsWith(QLatin1String("audio/pcm"))) {
+ err=-1;
+ } else
+ testCodec = true;
+
+ if(err>=0 && format.channels() != -1) {
+ err = snd_pcm_hw_params_test_channels(handle,params,format.channels());
+ if(err>=0)
+ err = snd_pcm_hw_params_set_channels(handle,params,format.channels());
+ if(err>=0)
+ testChannel = true;
+ }
+
+ if(err>=0 && format.frequency() != -1) {
+ err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0);
+ if(err>=0)
+ err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir);
+ if(err>=0)
+ testFreq = true;
+ }
+
+ if((err>=0 && format.sampleSize() != -1) &&
+ (format.sampleType() != QAudioFormat::Unknown)) {
+ switch(format.sampleSize()) {
+ case 8:
+ if(format.sampleType() == QAudioFormat::SignedInt)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8);
+ else if(format.sampleType() == QAudioFormat::UnSignedInt)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8);
+ break;
+ case 16:
+ if(format.sampleType() == QAudioFormat::SignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
+ } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE);
+ }
+ break;
+ case 32:
+ if(format.sampleType() == QAudioFormat::SignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE);
+ } else if(format.sampleType() == QAudioFormat::UnSignedInt) {
+ if(format.byteOrder() == QAudioFormat::LittleEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE);
+ else if(format.byteOrder() == QAudioFormat::BigEndian)
+ err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE);
+ }
+ }
+ if(err>=0) {
+ testSize = true;
+ testType = true;
+ }
+ }
+ if(err>=0)
+ err = snd_pcm_hw_params(handle, params);
+
+ if(err == 0) {
+ // settings work
+ // close()
+ if(handle)
+ snd_pcm_close(handle);
+ return true;
+ }
+ if(handle)
+ snd_pcm_close(handle);
+
+ return false;
+}
+
+void QAudioDeviceInfoInternal::updateLists()
+{
+ // redo all lists based on current settings
+ freqz.clear();
+ channelz.clear();
+ sizez.clear();
+ byteOrderz.clear();
+ typez.clear();
+ codecz.clear();
+
+ if(!handle)
+ open();
+
+ if(!handle)
+ return;
+
+ for(int i=0; i<(int)MAX_SAMPLE_RATES; i++) {
+ //if(snd_pcm_hw_params_test_rate(handle, params, SAMPLE_RATES[i], dir) == 0)
+ freqz.append(SAMPLE_RATES[i]);
+ }
+ channelz.append(1);
+ channelz.append(2);
+ if (surround40) channelz.append(4);
+ if (surround51) channelz.append(6);
+ if (surround71) channelz.append(8);
+ sizez.append(8);
+ sizez.append(16);
+ sizez.append(32);
+ byteOrderz.append(QAudioFormat::LittleEndian);
+ byteOrderz.append(QAudioFormat::BigEndian);
+ typez.append(QAudioFormat::SignedInt);
+ typez.append(QAudioFormat::UnSignedInt);
+ typez.append(QAudioFormat::Float);
+ codecz.append(QLatin1String("audio/pcm"));
+ close();
+}
+
+QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
+{
+ QList<QByteArray> allDevices;
+ QList<QByteArray> devices;
+ QByteArray filter;
+
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ // Create a list of all current audio devices that support mode
+ void **hints, **n;
+ char *name, *descr, *io;
+
+ if(snd_device_name_hint(-1, "pcm", &hints) < 0) {
+ qWarning() << "no alsa devices available";
+ return devices;
+ }
+ n = hints;
+
+ if(mode == QAudio::AudioInput) {
+ filter = "Input";
+ } else {
+ filter = "Output";
+ }
+
+ while (*n != NULL) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ if (name != 0 && qstrcmp(name, "null") != 0) {
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+
+ if ((descr != NULL) && ((io == NULL) || (io == filter))) {
+ QString deviceName = QLatin1String(name);
+ QString deviceDescription = QLatin1String(descr);
+ allDevices.append(deviceName.toLocal8Bit().constData());
+ if (deviceDescription.contains(QLatin1String("Default Audio Device")))
+ devices.append(deviceName.toLocal8Bit().constData());
+ }
+
+ free(name);
+ if (descr != NULL)
+ free(descr);
+ if (io != NULL)
+ free(io);
+ }
+ ++n;
+ }
+ snd_device_name_free_hint(hints);
+
+ if(devices.size() > 0) {
+ devices.append("default");
+ }
+#else
+ int idx = 0;
+ char* name;
+
+ while(snd_card_get_name(idx,&name) == 0) {
+ devices.append(name);
+ idx++;
+ }
+ if (idx > 0)
+ devices.append("default");
+#endif
+#if !defined(Q_WS_MAEMO_6)
+ if (devices.size() == 0 && allDevices.size() > 0)
+ return allDevices;
+#endif
+
+ return devices;
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultInputDevice()
+{
+ QList<QByteArray> devices = availableDevices(QAudio::AudioInput);
+ if(devices.size() == 0)
+ return QByteArray();
+
+ return devices.first();
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
+{
+ QList<QByteArray> devices = availableDevices(QAudio::AudioOutput);
+ if(devices.size() == 0)
+ return QByteArray();
+
+ return devices.first();
+}
+
+void QAudioDeviceInfoInternal::checkSurround()
+{
+ QList<QByteArray> devices;
+ surround40 = false;
+ surround51 = false;
+ surround71 = false;
+
+ void **hints, **n;
+ char *name, *descr, *io;
+
+ if(snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return;
+
+ n = hints;
+
+ while (*n != NULL) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+ if((name != NULL) && (descr != NULL)) {
+ QString deviceName = QLatin1String(name);
+ if (mode == QAudio::AudioOutput) {
+ if(deviceName.contains(QLatin1String("surround40")))
+ surround40 = true;
+ if(deviceName.contains(QLatin1String("surround51")))
+ surround51 = true;
+ if(deviceName.contains(QLatin1String("surround71")))
+ surround71 = true;
+ }
+ }
+ if(name != NULL)
+ free(name);
+ if(descr != NULL)
+ free(descr);
+ if(io != NULL)
+ free(io);
+ ++n;
+ }
+ snd_device_name_free_hint(hints);
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
new file mode 100644
index 000000000..cf19d2554
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QAUDIODEVICEINFOALSA_H
+#define QAUDIODEVICEINFOALSA_H
+
+#include <alsa/asoundlib.h>
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qdebug.h>
+
+#include "qaudio.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+const unsigned int MAX_SAMPLE_RATES = 5;
+const unsigned int SAMPLE_RATES[] =
+ { 8000, 11025, 22050, 44100, 48000 };
+
+class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo
+{
+ Q_OBJECT
+public:
+ QAudioDeviceInfoInternal(QByteArray dev,QAudio::Mode mode);
+ ~QAudioDeviceInfoInternal();
+
+ bool testSettings(const QAudioFormat& format) const;
+ void updateLists();
+ QAudioFormat preferredFormat() const;
+ bool isFormatSupported(const QAudioFormat& format) const;
+ QString deviceName() const;
+ QStringList supportedCodecs();
+ QList<int> supportedSampleRates();
+ QList<int> supportedChannelCounts();
+ QList<int> supportedSampleSizes();
+ QList<QAudioFormat::Endian> supportedByteOrders();
+ QList<QAudioFormat::SampleType> supportedSampleTypes();
+ static QByteArray defaultInputDevice();
+ static QByteArray defaultOutputDevice();
+ static QList<QByteArray> availableDevices(QAudio::Mode);
+
+private:
+ bool open();
+ void close();
+
+ void checkSurround();
+ bool surround40;
+ bool surround51;
+ bool surround71;
+
+ QString device;
+ QAudio::Mode mode;
+ QAudioFormat nearest;
+ QList<int> freqz;
+ QList<int> channelz;
+ QList<int> sizez;
+ QList<QAudioFormat::Endian> byteOrderz;
+ QStringList codecz;
+ QList<QAudioFormat::SampleType> typez;
+ snd_pcm_t* handle;
+ snd_pcm_hw_params_t *params;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
+
diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp
new file mode 100644
index 000000000..4c7779f91
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdatastream.h>
+#include <QtCore/qdebug.h>
+
+#include <qaudiodeviceinfo.h>
+#include "qaudio_mac_p.h"
+#include "qaudiodeviceinfo_mac_p.h"
+
+
+
+QT_BEGIN_NAMESPACE
+
+// XXX: remove at some future date
+static inline QString cfStringToQString(CFStringRef str)
+{
+ CFIndex length = CFStringGetLength(str);
+ const UniChar *chars = CFStringGetCharactersPtr(str);
+ if (chars)
+ return QString(reinterpret_cast<const QChar *>(chars), length);
+
+ UniChar buffer[length];
+ CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
+ return QString(reinterpret_cast<const QChar *>(buffer), length);
+}
+
+QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAudio::Mode)
+{
+ QDataStream ds(handle);
+ quint32 did, tm;
+
+ ds >> did >> tm >> name;
+ deviceId = AudioDeviceID(did);
+ mode = QAudio::Mode(tm);
+}
+
+bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const
+{
+ QAudioDeviceInfoInternal *self = const_cast<QAudioDeviceInfoInternal*>(this);
+
+ return format.isValid()
+ && format.codec() == QString::fromLatin1("audio/pcm")
+ && self->supportedSampleRates().contains(format.sampleRate())
+ && self->supportedChannelCounts().contains(format.channelCount())
+ && self->supportedSampleSizes().contains(format.sampleSize());
+}
+
+QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
+{
+ QAudioFormat rc;
+
+ UInt32 propSize = 0;
+
+ if (AudioDeviceGetPropertyInfo(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyStreams,
+ &propSize,
+ 0) == noErr) {
+
+ const int sc = propSize / sizeof(AudioStreamID);
+
+ if (sc > 0) {
+ AudioStreamID* streams = new AudioStreamID[sc];
+
+ if (AudioDeviceGetProperty(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyStreams,
+ &propSize,
+ streams) == noErr) {
+
+ for (int i = 0; i < sc; ++i) {
+ if (AudioStreamGetPropertyInfo(streams[i],
+ 0,
+ kAudioStreamPropertyPhysicalFormat,
+ &propSize,
+ 0) == noErr) {
+
+ AudioStreamBasicDescription sf;
+
+ if (AudioStreamGetProperty(streams[i],
+ 0,
+ kAudioStreamPropertyPhysicalFormat,
+ &propSize,
+ &sf) == noErr) {
+ rc = toQAudioFormat(sf);
+ break;
+ }
+ }
+ }
+ }
+
+ delete streams;
+ }
+ }
+
+ return rc;
+}
+
+QString QAudioDeviceInfoInternal::deviceName() const
+{
+ return name;
+}
+
+QStringList QAudioDeviceInfoInternal::supportedCodecs()
+{
+ return QStringList() << QString::fromLatin1("audio/pcm");
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleRates()
+{
+ QSet<int> rc;
+
+ // Add some common frequencies
+ rc << 8000 << 11025 << 22050 << 44100;
+
+ //
+ UInt32 propSize = 0;
+
+ if (AudioDeviceGetPropertyInfo(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyAvailableNominalSampleRates,
+ &propSize,
+ 0) == noErr) {
+
+ const int pc = propSize / sizeof(AudioValueRange);
+
+ if (pc > 0) {
+ AudioValueRange* vr = new AudioValueRange[pc];
+
+ if (AudioDeviceGetProperty(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyAvailableNominalSampleRates,
+ &propSize,
+ vr) == noErr) {
+
+ for (int i = 0; i < pc; ++i)
+ rc << vr[i].mMaximum;
+ }
+
+ delete vr;
+ }
+ }
+
+ return rc.toList();
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedChannelCounts()
+{
+ QList<int> rc;
+
+ // Can mix down to 1 channel
+ rc << 1;
+
+ UInt32 propSize = 0;
+ int channels = 0;
+
+ if (AudioDeviceGetPropertyInfo(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyStreamConfiguration,
+ &propSize,
+ 0) == noErr) {
+
+ AudioBufferList* audioBufferList = static_cast<AudioBufferList*>(qMalloc(propSize));
+
+ if (audioBufferList != 0) {
+ if (AudioDeviceGetProperty(deviceId,
+ 0,
+ mode == QAudio::AudioInput,
+ kAudioDevicePropertyStreamConfiguration,
+ &propSize,
+ audioBufferList) == noErr) {
+
+ for (int i = 0; i < int(audioBufferList->mNumberBuffers); ++i) {
+ channels += audioBufferList->mBuffers[i].mNumberChannels;
+ rc << channels;
+ }
+ }
+
+ qFree(audioBufferList);
+ }
+ }
+
+ return rc;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleSizes()
+{
+ return QList<int>() << 8 << 16 << 24 << 32 << 64;
+}
+
+QList<QAudioFormat::Endian> QAudioDeviceInfoInternal::supportedByteOrders()
+{
+ return QList<QAudioFormat::Endian>() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian;
+}
+
+QList<QAudioFormat::SampleType> QAudioDeviceInfoInternal::supportedSampleTypes()
+{
+ return QList<QAudioFormat::SampleType>() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float;
+}
+
+static QByteArray get_device_info(AudioDeviceID audioDevice, QAudio::Mode mode)
+{
+ UInt32 size;
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ AudioStreamBasicDescription sf;
+ CFStringRef name;
+ Boolean isInput = mode == QAudio::AudioInput;
+
+ // Id
+ ds << quint32(audioDevice);
+
+ // Mode
+ size = sizeof(AudioStreamBasicDescription);
+ if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioDevicePropertyStreamFormat,
+ &size, &sf) != noErr) {
+ return QByteArray();
+ }
+ ds << quint32(mode);
+
+ // Name
+ size = sizeof(CFStringRef);
+ if (AudioDeviceGetProperty(audioDevice, 0, isInput, kAudioObjectPropertyName,
+ &size, &name) != noErr) {
+ qWarning() << "QAudioDeviceInfo: Unable to find device name";
+ return QByteArray();
+ }
+ ds << cfStringToQString(name);
+
+ CFRelease(name);
+
+ return device;
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultInputDevice()
+{
+ AudioDeviceID audioDevice;
+ UInt32 size = sizeof(audioDevice);
+
+ if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size,
+ &audioDevice) != noErr) {
+ qWarning() << "QAudioDeviceInfo: Unable to find default input device";
+ return QByteArray();
+ }
+
+ return get_device_info(audioDevice, QAudio::AudioInput);
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
+{
+ AudioDeviceID audioDevice;
+ UInt32 size = sizeof(audioDevice);
+
+ if (AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size,
+ &audioDevice) != noErr) {
+ qWarning() << "QAudioDeviceInfo: Unable to find default output device";
+ return QByteArray();
+ }
+
+ return get_device_info(audioDevice, QAudio::AudioOutput);
+}
+
+QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
+{
+ QList<QByteArray> devices;
+
+ UInt32 propSize = 0;
+
+ if (AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propSize, 0) == noErr) {
+
+ const int dc = propSize / sizeof(AudioDeviceID);
+
+ if (dc > 0) {
+ AudioDeviceID* audioDevices = new AudioDeviceID[dc];
+
+ if (AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propSize, audioDevices) == noErr) {
+ for (int i = 0; i < dc; ++i) {
+ QByteArray info = get_device_info(audioDevices[i], mode);
+ if (!info.isNull())
+ devices << info;
+ }
+ }
+
+ delete audioDevices;
+ }
+ }
+
+ return devices;
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.h b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h
new file mode 100644
index 000000000..3b9ca4676
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QDEVICEINFO_MAC_P_H
+#define QDEVICEINFO_MAC_P_H
+
+#include <CoreAudio/CoreAudio.h>
+
+#include <qaudiosystem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo
+{
+public:
+ AudioDeviceID deviceId;
+ QString name;
+ QAudio::Mode mode;
+
+ QAudioDeviceInfoInternal(QByteArray const& handle, QAudio::Mode mode);
+
+ bool isFormatSupported(const QAudioFormat& format) const;
+ QAudioFormat preferredFormat() const;
+
+ QString deviceName() const;
+
+ QStringList supportedCodecs();
+ QList<int> supportedSampleRates();
+ QList<int> supportedChannelCounts();
+ QList<int> supportedSampleSizes();
+ QList<QAudioFormat::Endian> supportedByteOrders();
+ QList<QAudioFormat::SampleType> supportedSampleTypes();
+
+ static QByteArray defaultInputDevice();
+ static QByteArray defaultOutputDevice();
+
+ static QList<QByteArray> availableDevices(QAudio::Mode mode);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDEVICEINFO_MAC_P_H
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
new file mode 100644
index 000000000..10b9b777d
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+
+#include <windows.h>
+#include <mmsystem.h>
+#include "qaudiodeviceinfo_win32_p.h"
+#include <dshow.h>
+
+#if defined(Q_CC_MINGW)
+
+extern GUID CLSID_AudioInputDeviceCategory;
+
+#ifndef __IErrorLog_INTERFACE_DEFINED__
+#define __IErrorLog_INTERFACE_DEFINED__
+
+DECLARE_INTERFACE_(IErrorLog, IUnknown)
+{
+ STDMETHOD(AddError)(THIS_ LPCOLESTR, EXCEPINFO *) PURE;
+};
+
+#endif /* __IErrorLog_INTERFACE_DEFINED__ */
+
+#ifndef __IPropertyBag_INTERFACE_DEFINED__
+#define __IPropertyBag_INTERFACE_DEFINED__
+
+const GUID IID_IPropertyBag = {0x55272A00, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}};
+
+DECLARE_INTERFACE_(IPropertyBag, IUnknown)
+{
+ STDMETHOD(Read)(THIS_ LPCOLESTR, VARIANT *, IErrorLog *) PURE;
+ STDMETHOD(Write)(THIS_ LPCOLESTR, VARIANT *) PURE;
+};
+
+#endif /* __IPropertyBag_INTERFACE_DEFINED__ */
+
+#endif//Q_CC_MINGW
+
+QT_BEGIN_NAMESPACE
+
+// For mingw toolchain mmsystem.h only defines half the defines, so add if needed.
+#ifndef WAVE_FORMAT_44M08
+#define WAVE_FORMAT_44M08 0x00000100
+#define WAVE_FORMAT_44S08 0x00000200
+#define WAVE_FORMAT_44M16 0x00000400
+#define WAVE_FORMAT_44S16 0x00000800
+#define WAVE_FORMAT_48M08 0x00001000
+#define WAVE_FORMAT_48S08 0x00002000
+#define WAVE_FORMAT_48M16 0x00004000
+#define WAVE_FORMAT_48S16 0x00008000
+#define WAVE_FORMAT_96M08 0x00010000
+#define WAVE_FORMAT_96S08 0x00020000
+#define WAVE_FORMAT_96M16 0x00040000
+#define WAVE_FORMAT_96S16 0x00080000
+#endif
+
+
+QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode mode)
+{
+ QDataStream ds(&dev, QIODevice::ReadOnly);
+ ds >> devId >> device;
+ this->mode = mode;
+
+ updateLists();
+}
+
+QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal()
+{
+ close();
+}
+
+bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const
+{
+ return testSettings(format);
+}
+
+QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const
+{
+ QAudioFormat nearest;
+ if(mode == QAudio::AudioOutput) {
+ nearest.setFrequency(44100);
+ nearest.setChannelCount(2);
+ nearest.setByteOrder(QAudioFormat::LittleEndian);
+ nearest.setSampleType(QAudioFormat::SignedInt);
+ nearest.setSampleSize(16);
+ nearest.setCodec(QLatin1String("audio/pcm"));
+ } else {
+ nearest.setFrequency(11025);
+ nearest.setChannelCount(1);
+ nearest.setByteOrder(QAudioFormat::LittleEndian);
+ nearest.setSampleType(QAudioFormat::SignedInt);
+ nearest.setSampleSize(8);
+ nearest.setCodec(QLatin1String("audio/pcm"));
+ }
+ return nearest;
+}
+
+QString QAudioDeviceInfoInternal::deviceName() const
+{
+ return device;
+}
+
+QStringList QAudioDeviceInfoInternal::supportedCodecs()
+{
+ updateLists();
+ return codecz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleRates()
+{
+ updateLists();
+ return freqz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedChannelCounts()
+{
+ updateLists();
+ return channelz;
+}
+
+QList<int> QAudioDeviceInfoInternal::supportedSampleSizes()
+{
+ updateLists();
+ return sizez;
+}
+
+QList<QAudioFormat::Endian> QAudioDeviceInfoInternal::supportedByteOrders()
+{
+ updateLists();
+ return byteOrderz;
+}
+
+QList<QAudioFormat::SampleType> QAudioDeviceInfoInternal::supportedSampleTypes()
+{
+ updateLists();
+ return typez;
+}
+
+
+bool QAudioDeviceInfoInternal::open()
+{
+ return true;
+}
+
+void QAudioDeviceInfoInternal::close()
+{
+}
+
+bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const
+{
+ // Set nearest to closest settings that do work.
+ // See if what is in settings will work (return value).
+
+ bool failed = false;
+ bool match = false;
+
+ // check codec
+ for( int i = 0; i < codecz.count(); i++) {
+ if (format.codec() == codecz.at(i))
+ match = true;
+ }
+ if (!match) failed = true;
+
+ // check channel
+ match = false;
+ if (!failed) {
+ for( int i = 0; i < channelz.count(); i++) {
+ if (format.channels() == channelz.at(i)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ failed = true;
+ }
+
+ // check frequency
+ match = false;
+ if (!failed) {
+ for( int i = 0; i < freqz.count(); i++) {
+ if (format.frequency() == freqz.at(i)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ failed = true;
+ }
+
+ // check sample size
+ match = false;
+ if (!failed) {
+ for( int i = 0; i < sizez.count(); i++) {
+ if (format.sampleSize() == sizez.at(i)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ failed = true;
+ }
+
+ // check byte order
+ match = false;
+ if (!failed) {
+ for( int i = 0; i < byteOrderz.count(); i++) {
+ if (format.byteOrder() == byteOrderz.at(i)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ failed = true;
+ }
+
+ // check sample type
+ match = false;
+ if (!failed) {
+ for( int i = 0; i < typez.count(); i++) {
+ if (format.sampleType() == typez.at(i)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ failed = true;
+ }
+
+ if(!failed) {
+ // settings work
+ return true;
+ }
+ return false;
+}
+
+void QAudioDeviceInfoInternal::updateLists()
+{
+ // redo all lists based on current settings
+ bool match = false;
+ DWORD fmt = NULL;
+
+ if(mode == QAudio::AudioOutput) {
+ WAVEOUTCAPS woc;
+ if (waveOutGetDevCaps(devId, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR) {
+ match = true;
+ fmt = woc.dwFormats;
+ }
+ } else {
+ WAVEINCAPS woc;
+ if (waveInGetDevCaps(devId, &woc, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) {
+ match = true;
+ fmt = woc.dwFormats;
+ }
+ }
+ sizez.clear();
+ freqz.clear();
+ channelz.clear();
+ byteOrderz.clear();
+ typez.clear();
+ codecz.clear();
+
+ if(match) {
+ if((fmt && WAVE_FORMAT_1M08)
+ || (fmt && WAVE_FORMAT_1S08)
+ || (fmt && WAVE_FORMAT_2M08)
+ || (fmt && WAVE_FORMAT_2S08)
+ || (fmt && WAVE_FORMAT_4M08)
+ || (fmt && WAVE_FORMAT_4S08)
+ || (fmt && WAVE_FORMAT_48M08)
+ || (fmt && WAVE_FORMAT_48S08)
+ || (fmt && WAVE_FORMAT_96M08)
+ || (fmt && WAVE_FORMAT_96S08)
+ ) {
+ sizez.append(8);
+ }
+ if((fmt && WAVE_FORMAT_1M16)
+ || (fmt && WAVE_FORMAT_1S16)
+ || (fmt && WAVE_FORMAT_2M16)
+ || (fmt && WAVE_FORMAT_2S16)
+ || (fmt && WAVE_FORMAT_4M16)
+ || (fmt && WAVE_FORMAT_4S16)
+ || (fmt && WAVE_FORMAT_48M16)
+ || (fmt && WAVE_FORMAT_48S16)
+ || (fmt && WAVE_FORMAT_96M16)
+ || (fmt && WAVE_FORMAT_96S16)
+ ) {
+ sizez.append(16);
+ }
+ if((fmt && WAVE_FORMAT_1M08)
+ || (fmt && WAVE_FORMAT_1S08)
+ || (fmt && WAVE_FORMAT_1M16)
+ || (fmt && WAVE_FORMAT_1S16)) {
+ freqz.append(11025);
+ }
+ if((fmt && WAVE_FORMAT_2M08)
+ || (fmt && WAVE_FORMAT_2S08)
+ || (fmt && WAVE_FORMAT_2M16)
+ || (fmt && WAVE_FORMAT_2S16)) {
+ freqz.append(22050);
+ }
+ if((fmt && WAVE_FORMAT_4M08)
+ || (fmt && WAVE_FORMAT_4S08)
+ || (fmt && WAVE_FORMAT_4M16)
+ || (fmt && WAVE_FORMAT_4S16)) {
+ freqz.append(44100);
+ }
+ if((fmt && WAVE_FORMAT_48M08)
+ || (fmt && WAVE_FORMAT_48S08)
+ || (fmt && WAVE_FORMAT_48M16)
+ || (fmt && WAVE_FORMAT_48S16)) {
+ freqz.append(48000);
+ }
+ if((fmt && WAVE_FORMAT_96M08)
+ || (fmt && WAVE_FORMAT_96S08)
+ || (fmt && WAVE_FORMAT_96M16)
+ || (fmt && WAVE_FORMAT_96S16)) {
+ freqz.append(96000);
+ }
+ channelz.append(1);
+ channelz.append(2);
+ if (mode == QAudio::AudioOutput) {
+ channelz.append(4);
+ channelz.append(6);
+ channelz.append(8);
+ }
+
+ byteOrderz.append(QAudioFormat::LittleEndian);
+
+ typez.append(QAudioFormat::SignedInt);
+ typez.append(QAudioFormat::UnSignedInt);
+
+ codecz.append(QLatin1String("audio/pcm"));
+ }
+ if (freqz.count() > 0)
+ freqz.prepend(8000);
+}
+
+QList<QByteArray> QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode)
+{
+ Q_UNUSED(mode)
+
+ QList<QByteArray> devices;
+ //enumerate device fullnames through directshow api
+ CoInitialize(NULL);
+ ICreateDevEnum *pDevEnum = NULL;
+ IEnumMoniker *pEnum = NULL;
+ // Create the System device enumerator
+ HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
+ CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
+ reinterpret_cast<void **>(&pDevEnum));
+
+ unsigned long iNumDevs = mode == QAudio::AudioOutput ? waveOutGetNumDevs() : waveInGetNumDevs();
+ if (SUCCEEDED(hr)) {
+ // Create the enumerator for the audio input/output category
+ if (pDevEnum->CreateClassEnumerator(
+ mode == QAudio::AudioOutput ? CLSID_AudioRendererCategory : CLSID_AudioInputDeviceCategory,
+ &pEnum, 0) == S_OK) {
+ pEnum->Reset();
+ // go through and find all audio devices
+ IMoniker *pMoniker = NULL;
+ while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
+ IPropertyBag *pPropBag;
+ hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,
+ reinterpret_cast<void **>(&pPropBag));
+ if (FAILED(hr)) {
+ pMoniker->Release();
+ continue; // skip this one
+ }
+ // Find if it is a wave device
+ VARIANT var;
+ VariantInit(&var);
+ hr = pPropBag->Read(mode == QAudio::AudioOutput ? L"WaveOutID" : L"WaveInID", &var, 0);
+ if (SUCCEEDED(hr)) {
+ LONG waveID = var.lVal;
+ if (waveID >= 0 && waveID < LONG(iNumDevs)) {
+ VariantClear(&var);
+ // Find the description
+ hr = pPropBag->Read(L"FriendlyName", &var, 0);
+ if (SUCCEEDED(hr)) {
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ ds << quint32(waveID) << QString::fromWCharArray(var.bstrVal);
+ devices.append(device);
+ }
+ }
+ }
+
+ pPropBag->Release();
+ pMoniker->Release();
+ }
+ }
+ }
+ CoUninitialize();
+
+ return devices;
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
+{
+ QList<QByteArray> list = availableDevices(QAudio::AudioOutput);
+ if (list.size() > 0)
+ return list.at(0);
+ else
+ return QByteArray();
+}
+
+QByteArray QAudioDeviceInfoInternal::defaultInputDevice()
+{
+ QList<QByteArray> list = availableDevices(QAudio::AudioInput);
+ if (list.size() > 0)
+ return list.at(0);
+ else
+ return QByteArray();
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.h b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h
new file mode 100644
index 000000000..2d4e27106
--- /dev/null
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QAUDIODEVICEINFOWIN_H
+#define QAUDIODEVICEINFOWIN_H
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qdebug.h>
+
+#include <qaudiodeviceinfo.h>
+#include <qaudiosystem.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+const unsigned int MAX_SAMPLE_RATES = 5;
+const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 };
+
+class QAudioDeviceInfoInternal : public QAbstractAudioDeviceInfo
+{
+ Q_OBJECT
+
+public:
+ QAudioDeviceInfoInternal(QByteArray dev,QAudio::Mode mode);
+ ~QAudioDeviceInfoInternal();
+
+ bool open();
+ void close();
+
+ bool testSettings(const QAudioFormat& format) const;
+ void updateLists();
+ QAudioFormat preferredFormat() const;
+ bool isFormatSupported(const QAudioFormat& format) const;
+ QString deviceName() const;
+ QStringList supportedCodecs();
+ QList<int> supportedSampleRates();
+ QList<int> supportedChannelCounts();
+ QList<int> supportedSampleSizes();
+ QList<QAudioFormat::Endian> supportedByteOrders();
+ QList<QAudioFormat::SampleType> supportedSampleTypes();
+ static QByteArray defaultInputDevice();
+ static QByteArray defaultOutputDevice();
+ static QList<QByteArray> availableDevices(QAudio::Mode);
+
+private:
+ QAudio::Mode mode;
+ QString device;
+ quint32 devId;
+ QAudioFormat nearest;
+ QList<int> freqz;
+ QList<int> channelz;
+ QList<int> sizez;
+ QList<QAudioFormat::Endian> byteOrderz;
+ QStringList codecz;
+ QList<QAudioFormat::SampleType> typez;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp
new file mode 100644
index 000000000..6ed72516c
--- /dev/null
+++ b/src/multimedia/audio/qaudioformat.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QDebug>
+#include <qaudioformat.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+class QAudioFormatPrivate : public QSharedData
+{
+public:
+ QAudioFormatPrivate()
+ {
+ frequency = -1;
+ channels = -1;
+ sampleSize = -1;
+ byteOrder = QAudioFormat::Endian(QSysInfo::ByteOrder);
+ sampleType = QAudioFormat::Unknown;
+ }
+
+ QAudioFormatPrivate(const QAudioFormatPrivate &other):
+ QSharedData(other),
+ codec(other.codec),
+ byteOrder(other.byteOrder),
+ sampleType(other.sampleType),
+ frequency(other.frequency),
+ channels(other.channels),
+ sampleSize(other.sampleSize)
+ {
+ }
+
+ QAudioFormatPrivate& operator=(const QAudioFormatPrivate &other)
+ {
+ codec = other.codec;
+ byteOrder = other.byteOrder;
+ sampleType = other.sampleType;
+ frequency = other.frequency;
+ channels = other.channels;
+ sampleSize = other.sampleSize;
+
+ return *this;
+ }
+
+ QString codec;
+ QAudioFormat::Endian byteOrder;
+ QAudioFormat::SampleType sampleType;
+ int frequency;
+ int channels;
+ int sampleSize;
+};
+
+/*!
+ \class QAudioFormat
+ \brief The QAudioFormat class stores audio stream parameter information.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ An audio format specifies how data in an audio stream is arranged,
+ i.e, how the stream is to be interpreted. The encoding itself is
+ specified by the codec() used for the stream.
+
+ In addition to the encoding, QAudioFormat contains other
+ parameters that further specify how the audio sample data is arranged.
+ These are the frequency, the number of channels, the sample size,
+ the sample type, and the byte order. The following table describes
+ these in more detail.
+
+ \table
+ \header
+ \o Parameter
+ \o Description
+ \row
+ \o Sample Rate
+ \o Samples per second of audio data in Hertz.
+ \row
+ \o Number of channels
+ \o The number of audio channels (typically one for mono
+ or two for stereo)
+ \row
+ \o Sample size
+ \o How much data is stored in each sample (typically 8
+ or 16 bits)
+ \row
+ \o Sample type
+ \o Numerical representation of sample (typically signed integer,
+ unsigned integer or float)
+ \row
+ \o Byte order
+ \o Byte ordering of sample (typically little endian, big endian)
+ \endtable
+
+ This class is typically used in conjunction with QAudioInput or
+ QAudioOutput to allow you to specify the parameters of the audio
+ stream being read or written.
+
+ You can obtain audio formats compatible with the audio device used
+ through functions in QAudioDeviceInfo. This class also lets you
+ query available parameter values for a device, so that you can set
+ the parameters yourself. See the \l QAudioDeviceInfo class
+ description for details. You need to know the format of the audio
+ streams you wish to play or record.
+*/
+
+/*!
+ Construct a new audio format.
+
+ Values are initialized as follows:
+ \list
+ \o sampleRate() = -1
+ \o channelCount() = -1
+ \o sampleSize() = -1
+ \o byteOrder() = QAudioFormat::Endian(QSysInfo::ByteOrder)
+ \o sampleType() = QAudioFormat::Unknown
+ \c codec() = ""
+ \endlist
+*/
+QAudioFormat::QAudioFormat():
+ d(new QAudioFormatPrivate)
+{
+}
+
+/*!
+ Construct a new audio format using \a other.
+ \since 1.0
+*/
+QAudioFormat::QAudioFormat(const QAudioFormat &other):
+ d(other.d)
+{
+}
+
+/*!
+ Destroy this audio format.
+*/
+QAudioFormat::~QAudioFormat()
+{
+}
+
+/*!
+ Assigns \a other to this QAudioFormat implementation.
+ \since 1.0
+*/
+QAudioFormat& QAudioFormat::operator=(const QAudioFormat &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns true if this QAudioFormat is equal to the \a other
+ QAudioFormat; otherwise returns false.
+
+ All elements of QAudioFormat are used for the comparison.
+ \since 1.0
+*/
+bool QAudioFormat::operator==(const QAudioFormat &other) const
+{
+ return d->frequency == other.d->frequency &&
+ d->channels == other.d->channels &&
+ d->sampleSize == other.d->sampleSize &&
+ d->byteOrder == other.d->byteOrder &&
+ d->codec == other.d->codec &&
+ d->sampleType == other.d->sampleType;
+}
+
+/*!
+ Returns true if this QAudioFormat is not equal to the \a other
+ QAudioFormat; otherwise returns false.
+
+ All elements of QAudioFormat are used for the comparison.
+ \since 1.0
+*/
+bool QAudioFormat::operator!=(const QAudioFormat& other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Returns true if all of the parameters are valid.
+ \since 1.0
+*/
+bool QAudioFormat::isValid() const
+{
+ return d->frequency != -1 && d->channels != -1 && d->sampleSize != -1 &&
+ d->sampleType != QAudioFormat::Unknown && !d->codec.isEmpty();
+}
+
+/*!
+ Sets the sample rate to \a samplerate Hertz.
+
+ \since 1.0
+*/
+void QAudioFormat::setSampleRate(int samplerate)
+{
+ d->frequency = samplerate;
+}
+
+/*!
+ \obsolete
+
+ Use setSampleRate() instead.
+*/
+void QAudioFormat::setFrequency(int frequency)
+{
+ d->frequency = frequency;
+}
+
+/*!
+ Returns the current sample rate in Hertz.
+
+ \since 1.0
+*/
+int QAudioFormat::sampleRate() const
+{
+ return d->frequency;
+}
+
+/*!
+ \obsolete
+
+ Use sampleRate() instead.
+*/
+int QAudioFormat::frequency() const
+{
+ return d->frequency;
+}
+
+/*!
+ Sets the channel count to \a channels.
+
+ \since 1.0
+*/
+void QAudioFormat::setChannelCount(int channels)
+{
+ d->channels = channels;
+}
+
+/*!
+ \obsolete
+
+ Use setChannelCount() instead.
+*/
+void QAudioFormat::setChannels(int channels)
+{
+ d->channels = channels;
+}
+
+/*!
+ Returns the current channel count value.
+
+ \since 1.0
+*/
+int QAudioFormat::channelCount() const
+{
+ return d->channels;
+}
+
+/*!
+ \obsolete
+
+ Use channelCount() instead.
+*/
+int QAudioFormat::channels() const
+{
+ return d->channels;
+}
+
+/*!
+ Sets the sample size to the \a sampleSize specified, in bits.
+
+ This is typically 8 or 16, but some systems may support higher sample sizes.
+ \since 1.0
+*/
+void QAudioFormat::setSampleSize(int sampleSize)
+{
+ d->sampleSize = sampleSize;
+}
+
+/*!
+ Returns the current sample size value, in bits.
+ \since 1.0
+*/
+int QAudioFormat::sampleSize() const
+{
+ return d->sampleSize;
+}
+
+/*!
+ Sets the codec to \a codec.
+
+ The parameter to this function should be one of the types
+ reported by the QAudioDeviceInfo::supportedCodecs() function
+ for the audio device you are working with.
+
+ \since 1.0
+ \sa QAudioDeviceInfo::supportedCodecs()
+*/
+void QAudioFormat::setCodec(const QString &codec)
+{
+ d->codec = codec;
+}
+
+/*!
+ Returns the current codec identifier.
+
+ \since 1.0
+ \sa QAudioDeviceInfo::supportedCodecs()
+*/
+QString QAudioFormat::codec() const
+{
+ return d->codec;
+}
+
+/*!
+ Sets the byteOrder to \a byteOrder.
+ \since 1.0
+*/
+void QAudioFormat::setByteOrder(QAudioFormat::Endian byteOrder)
+{
+ d->byteOrder = byteOrder;
+}
+
+/*!
+ Returns the current byteOrder value.
+ \since 1.0
+*/
+QAudioFormat::Endian QAudioFormat::byteOrder() const
+{
+ return d->byteOrder;
+}
+
+/*!
+ Sets the sampleType to \a sampleType.
+ \since 1.0
+*/
+void QAudioFormat::setSampleType(QAudioFormat::SampleType sampleType)
+{
+ d->sampleType = sampleType;
+}
+
+/*!
+ Returns the current SampleType value.
+ \since 1.0
+*/
+QAudioFormat::SampleType QAudioFormat::sampleType() const
+{
+ return d->sampleType;
+}
+
+/*!
+ \enum QAudioFormat::SampleType
+
+ \value Unknown Not Set
+ \value SignedInt Samples are signed integers
+ \value UnSignedInt Samples are unsigned intergers
+ \value Float Samples are floats
+*/
+
+/*!
+ \enum QAudioFormat::Endian
+
+ \value BigEndian Samples are big endian byte order
+ \value LittleEndian Samples are little endian byte order
+*/
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h
new file mode 100644
index 000000000..087a16a9d
--- /dev/null
+++ b/src/multimedia/audio/qaudioformat.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIOFORMAT_H
+#define QAUDIOFORMAT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QAudioFormatPrivate;
+
+class Q_MULTIMEDIA_EXPORT QAudioFormat
+{
+public:
+ enum SampleType { Unknown, SignedInt, UnSignedInt, Float };
+ enum Endian { BigEndian = QSysInfo::BigEndian, LittleEndian = QSysInfo::LittleEndian };
+
+ QAudioFormat();
+ QAudioFormat(const QAudioFormat &other);
+ ~QAudioFormat();
+
+ QAudioFormat& operator=(const QAudioFormat &other);
+ bool operator==(const QAudioFormat &other) const;
+ bool operator!=(const QAudioFormat &other) const;
+
+ bool isValid() const;
+
+ void setFrequency(int frequency);
+ int frequency() const;
+ void setSampleRate(int sampleRate);
+ int sampleRate() const;
+
+ void setChannels(int channels);
+ int channels() const;
+ void setChannelCount(int channelCount);
+ int channelCount() const;
+
+ void setSampleSize(int sampleSize);
+ int sampleSize() const;
+
+ void setCodec(const QString &codec);
+ QString codec() const;
+
+ void setByteOrder(QAudioFormat::Endian byteOrder);
+ QAudioFormat::Endian byteOrder() const;
+
+ void setSampleType(QAudioFormat::SampleType sampleType);
+ QAudioFormat::SampleType sampleType() const;
+
+private:
+ QSharedDataPointer<QAudioFormatPrivate> d;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOFORMAT_H
diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp
new file mode 100644
index 000000000..2a5cefcc5
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput.cpp
@@ -0,0 +1,402 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qaudio.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+#include "qaudioinput.h"
+
+#include "qaudiodevicefactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAudioInput
+ \brief The QAudioInput class provides an interface for receiving audio data from an audio input device.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ You can construct an audio input with the system's
+ \l{QAudioDeviceInfo::defaultInputDevice()}{default audio input
+ device}. It is also possible to create QAudioInput with a
+ specific QAudioDeviceInfo. When you create the audio input, you
+ should also send in the QAudioFormat to be used for the recording
+ (see the QAudioFormat class description for details).
+
+ To record to a file:
+
+ QAudioInput lets you record audio with an audio input device. The
+ default constructor of this class will use the systems default
+ audio device, but you can also specify a QAudioDeviceInfo for a
+ specific device. You also need to pass in the QAudioFormat in
+ which you wish to record.
+
+ Starting up the QAudioInput is simply a matter of calling start()
+ with a QIODevice opened for writing. For instance, to record to a
+ file, you can:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio input class members
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio input setup
+
+ This will start recording if the format specified is supported by
+ the input device (you can check this with
+ QAudioDeviceInfo::isFormatSupported(). In case there are any
+ snags, use the error() function to check what went wrong. We stop
+ recording in the \c stopRecording() slot.
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio input stop recording
+
+ At any point in time, QAudioInput will be in one of four states:
+ active, suspended, stopped, or idle. These states are specified by
+ the QAudio::State enum. You can request a state change directly through
+ suspend(), resume(), stop(), reset(), and start(). The current
+ state is reported by state(). QAudioOutput will also signal you
+ when the state changes (stateChanged()).
+
+ QAudioInput provides several ways of measuring the time that has
+ passed since the start() of the recording. The \c processedUSecs()
+ function returns the length of the stream in microseconds written,
+ i.e., it leaves out the times the audio input was suspended or idle.
+ The elapsedUSecs() function returns the time elapsed since start() was called regardless of
+ which states the QAudioInput has been in.
+
+ If an error should occur, you can fetch its reason with error().
+ The possible error reasons are described by the QAudio::Error
+ enum. The QAudioInput will enter the \l{QAudio::}{StoppedState} when
+ an error is encountered. Connect to the stateChanged() signal to
+ handle the error:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio input state changed
+
+ \sa QAudioOutput, QAudioDeviceInfo
+*/
+
+/*!
+ Construct a new audio input and attach it to \a parent.
+ The default audio input device is used with the output
+ \a format parameters.
+ \since 1.0
+*/
+
+QAudioInput::QAudioInput(const QAudioFormat &format, QObject *parent):
+ QObject(parent)
+{
+ d = QAudioDeviceFactory::createDefaultInputDevice(format);
+ connect(d, SIGNAL(notify()), SIGNAL(notify()));
+ connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
+}
+
+/*!
+ Construct a new audio input and attach it to \a parent.
+ The device referenced by \a audioDevice is used with the input
+ \a format parameters.
+ \since 1.0
+*/
+
+QAudioInput::QAudioInput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent):
+ QObject(parent)
+{
+ d = QAudioDeviceFactory::createInputDevice(audioDevice, format);
+ connect(d, SIGNAL(notify()), SIGNAL(notify()));
+ connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
+}
+
+/*!
+ Destroy this audio input.
+*/
+
+QAudioInput::~QAudioInput()
+{
+ delete d;
+}
+
+/*!
+ Uses the \a device as the QIODevice to transfer data.
+ Passing a QIODevice allows the data to be transferred without any extra code.
+ All that is required is to open the QIODevice.
+
+ If able to successfully get audio data from the systems audio device the
+ state() is set to either QAudio::ActiveState or QAudio::IdleState,
+ error() is set to QAudio::NoError and the stateChanged() signal is emitted.
+
+ If a problem occurs during this process the error() is set to QAudio::OpenError,
+ state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+ \since 1.0
+ \sa QIODevice
+*/
+
+void QAudioInput::start(QIODevice* device)
+{
+ d->start(device);
+}
+
+/*!
+ Returns a pointer to the QIODevice being used to handle the data
+ transfer. This QIODevice can be used to read() audio data
+ directly.
+
+ If able to access the systems audio device the state() is set to
+ QAudio::IdleState, error() is set to QAudio::NoError
+ and the stateChanged() signal is emitted.
+
+ If a problem occurs during this process the error() is set to QAudio::OpenError,
+ state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+ \since 1.0
+ \sa QIODevice
+*/
+
+QIODevice* QAudioInput::start()
+{
+ return d->start();
+}
+
+/*!
+ Returns the QAudioFormat being used.
+ \since 1.0
+*/
+
+QAudioFormat QAudioInput::format() const
+{
+ return d->format();
+}
+
+/*!
+ Stops the audio input, detaching from the system resource.
+
+ Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
+ emit stateChanged() signal.
+ \since 1.0
+*/
+
+void QAudioInput::stop()
+{
+ d->stop();
+}
+
+/*!
+ Drops all audio data in the buffers, resets buffers to zero.
+ \since 1.0
+*/
+
+void QAudioInput::reset()
+{
+ d->reset();
+}
+
+/*!
+ Stops processing audio data, preserving buffered audio data.
+
+ Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
+ emit stateChanged() signal.
+ \since 1.0
+*/
+
+void QAudioInput::suspend()
+{
+ d->suspend();
+}
+
+/*!
+ Resumes processing audio data after a suspend().
+
+ Sets error() to QAudio::NoError.
+ Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
+ Sets state() to QAudio::IdleState if you previously called start().
+ emits stateChanged() signal.
+ \since 1.0
+*/
+
+void QAudioInput::resume()
+{
+ d->resume();
+}
+
+/*!
+ Sets the audio buffer size to \a value milliseconds.
+
+ Note: This function can be called anytime before start(), calls to this
+ are ignored after start(). It should not be assumed that the buffer size
+ set is the actual buffer size used, calling bufferSize() anytime after start()
+ will return the actual buffer size being used.
+
+ \since 1.0
+*/
+
+void QAudioInput::setBufferSize(int value)
+{
+ d->setBufferSize(value);
+}
+
+/*!
+ Returns the audio buffer size in milliseconds.
+
+ If called before start(), returns platform default value.
+ If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
+ If called after start(), returns the actual buffer size being used. This may not be what was set previously
+ by setBufferSize().
+
+ \since 1.0
+*/
+
+int QAudioInput::bufferSize() const
+{
+ return d->bufferSize();
+}
+
+/*!
+ Returns the amount of audio data available to read in bytes.
+
+ NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
+ state, otherwise returns zero.
+ \since 1.0
+*/
+
+int QAudioInput::bytesReady() const
+{
+ /*
+ -If not ActiveState|IdleState, return 0
+ -return amount of audio data available to read
+ */
+ return d->bytesReady();
+}
+
+/*!
+ Returns the period size in bytes.
+
+ Note: This is the recommended read size in bytes.
+ \since 1.0
+*/
+
+int QAudioInput::periodSize() const
+{
+ return d->periodSize();
+}
+
+/*!
+ Sets the interval for notify() signal to be emitted.
+ This is based on the \a ms of audio data processed
+ not on actual real-time.
+ The minimum resolution of the timer is platform specific and values
+ should be checked with notifyInterval() to confirm actual value
+ being used.
+ \since 1.0
+*/
+
+void QAudioInput::setNotifyInterval(int ms)
+{
+ d->setNotifyInterval(ms);
+}
+
+/*!
+ Returns the notify interval in milliseconds.
+ \since 1.0
+*/
+
+int QAudioInput::notifyInterval() const
+{
+ return d->notifyInterval();
+}
+
+/*!
+ Returns the amount of audio data processed since start()
+ was called in microseconds.
+ \since 1.0
+*/
+
+qint64 QAudioInput::processedUSecs() const
+{
+ return d->processedUSecs();
+}
+
+/*!
+ Returns the microseconds since start() was called, including time in Idle and
+ Suspend states.
+ \since 1.0
+*/
+
+qint64 QAudioInput::elapsedUSecs() const
+{
+ return d->elapsedUSecs();
+}
+
+/*!
+ Returns the error state.
+ \since 1.0
+*/
+
+QAudio::Error QAudioInput::error() const
+{
+ return d->error();
+}
+
+/*!
+ Returns the state of audio processing.
+ \since 1.0
+*/
+
+QAudio::State QAudioInput::state() const
+{
+ return d->state();
+}
+
+/*!
+ \fn QAudioInput::stateChanged(QAudio::State state)
+ This signal is emitted when the device \a state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioInput::notify()
+ This signal is emitted when x ms of audio data has been processed
+ the interval set by setNotifyInterval(x).
+ \since 1.0
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qaudioinput.cpp"
+
diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h
new file mode 100644
index 000000000..9c893ce95
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIOINPUT_H
+#define QAUDIOINPUT_H
+
+#include <QtCore/qiodevice.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include <qaudio.h>
+#include <qaudioformat.h>
+#include <qaudiodeviceinfo.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QAbstractAudioInput;
+
+class Q_MULTIMEDIA_EXPORT QAudioInput : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0);
+ explicit QAudioInput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0);
+ ~QAudioInput();
+
+ QAudioFormat format() const;
+
+ void start(QIODevice *device);
+ QIODevice* start();
+
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+
+ void setBufferSize(int bytes);
+ int bufferSize() const;
+
+ int bytesReady() const;
+ int periodSize() const;
+
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+Q_SIGNALS:
+ void stateChanged(QAudio::State);
+ void notify();
+
+private:
+ Q_DISABLE_COPY(QAudioInput)
+
+ QAbstractAudioInput* d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOINPUT_H
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp
new file mode 100644
index 000000000..044458cd0
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp
@@ -0,0 +1,867 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include "qaudioinput_alsa_p.h"
+#include "qaudiodeviceinfo_alsa_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_AUDIO 1
+
+QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device)
+{
+ bytesAvailable = 0;
+ handle = 0;
+ ahandler = 0;
+ access = SND_PCM_ACCESS_RW_INTERLEAVED;
+ pcmformat = SND_PCM_FORMAT_S16;
+ buffer_size = 0;
+ period_size = 0;
+ buffer_time = 100000;
+ period_time = 20000;
+ totalTimeValue = 0;
+ intervalTime = 1000;
+ errorState = QAudio::NoError;
+ deviceState = QAudio::StoppedState;
+ audioSource = 0;
+ pullMode = true;
+ resuming = false;
+
+ m_device = device;
+
+ timer = new QTimer(this);
+ connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
+}
+
+QAudioInputPrivate::~QAudioInputPrivate()
+{
+ close();
+ disconnect(timer, SIGNAL(timeout()));
+ QCoreApplication::processEvents();
+ delete timer;
+}
+
+QAudio::Error QAudioInputPrivate::error() const
+{
+ return errorState;
+}
+
+QAudio::State QAudioInputPrivate::state() const
+{
+ return deviceState;
+}
+
+void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (deviceState == QAudio::StoppedState)
+ settings = fmt;
+}
+
+QAudioFormat QAudioInputPrivate::format() const
+{
+ return settings;
+}
+
+int QAudioInputPrivate::xrun_recovery(int err)
+{
+ int count = 0;
+ bool reset = false;
+
+ if(err == -EPIPE) {
+ errorState = QAudio::UnderrunError;
+ err = snd_pcm_prepare(handle);
+ if(err < 0)
+ reset = true;
+ else {
+ bytesAvailable = checkBytesReady();
+ if (bytesAvailable <= 0)
+ reset = true;
+ }
+
+ } else if((err == -ESTRPIPE)||(err == -EIO)) {
+ errorState = QAudio::IOError;
+ while((err = snd_pcm_resume(handle)) == -EAGAIN){
+ usleep(100);
+ count++;
+ if(count > 5) {
+ reset = true;
+ break;
+ }
+ }
+ if(err < 0) {
+ err = snd_pcm_prepare(handle);
+ if(err < 0)
+ reset = true;
+ }
+ }
+ if(reset) {
+ close();
+ open();
+ snd_pcm_prepare(handle);
+ return 0;
+ }
+ return err;
+}
+
+int QAudioInputPrivate::setFormat()
+{
+ snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
+
+ if(settings.sampleSize() == 8) {
+ format = SND_PCM_FORMAT_U8;
+ } else if(settings.sampleSize() == 16) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_S16_LE;
+ else
+ format = SND_PCM_FORMAT_S16_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_U16_LE;
+ else
+ format = SND_PCM_FORMAT_U16_BE;
+ }
+ } else if(settings.sampleSize() == 24) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_S24_LE;
+ else
+ format = SND_PCM_FORMAT_S24_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_U24_LE;
+ else
+ format = SND_PCM_FORMAT_U24_BE;
+ }
+ } else if(settings.sampleSize() == 32) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_S32_LE;
+ else
+ format = SND_PCM_FORMAT_S32_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_U32_LE;
+ else
+ format = SND_PCM_FORMAT_U32_BE;
+ } else if(settings.sampleType() == QAudioFormat::Float) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_FLOAT_LE;
+ else
+ format = SND_PCM_FORMAT_FLOAT_BE;
+ }
+ } else if(settings.sampleSize() == 64) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ format = SND_PCM_FORMAT_FLOAT64_LE;
+ else
+ format = SND_PCM_FORMAT_FLOAT64_BE;
+ }
+
+ return format != SND_PCM_FORMAT_UNKNOWN
+ ? snd_pcm_hw_params_set_format( handle, hwparams, format)
+ : -1;
+}
+
+void QAudioInputPrivate::start(QIODevice* device)
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = true;
+ audioSource = device;
+
+ deviceState = QAudio::ActiveState;
+
+ if( !open() )
+ return;
+
+ emit stateChanged(deviceState);
+}
+
+QIODevice* QAudioInputPrivate::start()
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = false;
+ audioSource = new InputPrivate(this);
+ audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ deviceState = QAudio::IdleState;
+
+ if( !open() )
+ return 0;
+
+ emit stateChanged(deviceState);
+
+ return audioSource;
+}
+
+void QAudioInputPrivate::stop()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+
+ deviceState = QAudio::StoppedState;
+
+ close();
+ emit stateChanged(deviceState);
+}
+
+bool QAudioInputPrivate::open()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
+#endif
+ clockStamp.restart();
+ timeStamp.restart();
+ elapsedTimeOffset = 0;
+
+ int dir;
+ int err = 0;
+ int count=0;
+ unsigned int freakuency=settings.frequency();
+
+ if (!settings.isValid()) {
+ qWarning("QAudioOutput: open error, invalid format.");
+ } else if (settings.sampleRate() <= 0) {
+ qWarning("QAudioOutput: open error, invalid sample rate (%d).",
+ settings.sampleRate());
+ } else {
+ err = -1;
+ }
+
+ if (err == 0) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit errorChanged(errorState);
+ return false;
+ }
+
+
+ QString dev = QString(QLatin1String(m_device.constData()));
+ QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput);
+ if(dev.compare(QLatin1String("default")) == 0) {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ if (devices.size() > 0)
+ dev = QLatin1String(devices.first());
+ else
+ return false;
+#else
+ dev = QLatin1String("hw:0,0");
+#endif
+ } else {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ dev = QLatin1String(m_device);
+#else
+ int idx = 0;
+ char *name;
+
+ QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());
+
+ while(snd_card_get_name(idx,&name) == 0) {
+ if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
+ break;
+ idx++;
+ }
+ dev = QString(QLatin1String("hw:%1,0")).arg(idx);
+#endif
+ }
+
+ // Step 1: try and open the device
+ while((count < 5) && (err < 0)) {
+ err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
+ if(err < 0)
+ count++;
+ }
+ if (( err < 0)||(handle == 0)) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+ snd_pcm_nonblock( handle, 0 );
+
+ // Step 2: Set the desired HW parameters.
+ snd_pcm_hw_params_alloca( &hwparams );
+
+ bool fatal = false;
+ QString errMessage;
+ unsigned int chunks = 8;
+
+ err = snd_pcm_hw_params_any( handle, hwparams );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_any: err = %1").arg(err);
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_access( handle, hwparams, access );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_access: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = setFormat();
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_format: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params(handle, hwparams);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params: err = %1").arg(err);
+ }
+ }
+ if( err < 0) {
+ qWarning()<<errMessage;
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+ snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
+ buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
+ snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
+ period_size = snd_pcm_frames_to_bytes(handle,period_frames);
+ snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
+ snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
+
+ // Step 3: Set the desired SW parameters.
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_sw_params_alloca(&swparams);
+ snd_pcm_sw_params_current(handle, swparams);
+ snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
+ snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
+ snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
+ snd_pcm_sw_params(handle, swparams);
+
+ // Step 4: Prepare audio
+ ringBuffer.resize(buffer_size);
+ snd_pcm_prepare( handle );
+ snd_pcm_start(handle);
+
+ // Step 5: Setup timer
+ bytesAvailable = checkBytesReady();
+
+ if(pullMode)
+ connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));
+
+ // Step 6: Start audio processing
+ chunks = buffer_size/period_size;
+ timer->start(period_time*chunks/2000);
+
+ errorState = QAudio::NoError;
+
+ totalTimeValue = 0;
+
+ return true;
+}
+
+void QAudioInputPrivate::close()
+{
+ timer->stop();
+
+ if ( handle ) {
+ snd_pcm_drop( handle );
+ snd_pcm_close( handle );
+ handle = 0;
+ }
+}
+
+int QAudioInputPrivate::checkBytesReady()
+{
+ if(resuming)
+ bytesAvailable = period_size;
+ else if(deviceState != QAudio::ActiveState
+ && deviceState != QAudio::IdleState)
+ bytesAvailable = 0;
+ else {
+ int frames = snd_pcm_avail_update(handle);
+ if (frames < 0) {
+ bytesAvailable = frames;
+ } else {
+ if((int)frames > (int)buffer_frames)
+ frames = buffer_frames;
+ bytesAvailable = snd_pcm_frames_to_bytes(handle, frames);
+ }
+ }
+ return bytesAvailable;
+}
+
+int QAudioInputPrivate::bytesReady() const
+{
+ return qMax(bytesAvailable, 0);
+}
+
+qint64 QAudioInputPrivate::read(char* data, qint64 len)
+{
+ // Read in some audio data and write it to QIODevice, pull mode
+ if ( !handle )
+ return 0;
+
+ int bytesRead = 0;
+ int bytesInRingbufferBeforeRead = ringBuffer.bytesOfDataInBuffer();
+
+ if (ringBuffer.bytesOfDataInBuffer() < len) {
+
+ // bytesAvaiable is saved as a side effect of checkBytesReady().
+ int bytesToRead = checkBytesReady();
+
+ if (bytesToRead < 0) {
+ // bytesAvailable as negative is error code, try to recover from it.
+ xrun_recovery(bytesToRead);
+ bytesToRead = checkBytesReady();
+ if (bytesToRead < 0) {
+ // recovery failed must stop and set error.
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return 0;
+ }
+ }
+
+ bytesToRead = qMin<qint64>(len, bytesToRead);
+ bytesToRead = qMin<qint64>(ringBuffer.freeBytes(), bytesToRead);
+ bytesToRead -= bytesToRead % period_size;
+
+ int count=0;
+ int err = 0;
+ while(count < 5 && bytesToRead > 0) {
+ char buffer[bytesToRead];
+ int chunks = bytesToRead / period_size;
+ int frames = chunks * period_frames;
+ if (frames > (int)buffer_frames)
+ frames = buffer_frames;
+
+ int readFrames = snd_pcm_readi(handle, buffer, frames);
+
+ if (readFrames >= 0) {
+ bytesRead = snd_pcm_frames_to_bytes(handle, readFrames);
+ ringBuffer.write(buffer, bytesRead);
+#ifdef DEBUG_AUDIO
+ qDebug() << QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(bytesRead).arg(readFrames).toLatin1().constData();
+#endif
+ break;
+ } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
+ errorState = QAudio::IOError;
+ err = 0;
+ break;
+ } else {
+ if(readFrames == -EPIPE) {
+ errorState = QAudio::UnderrunError;
+ err = snd_pcm_prepare(handle);
+ } else if(readFrames == -ESTRPIPE) {
+ err = snd_pcm_prepare(handle);
+ }
+ if(err != 0) break;
+ }
+ count++;
+ }
+
+ }
+
+ bytesRead += bytesInRingbufferBeforeRead;
+
+ if (bytesRead > 0) {
+ // got some send it onward
+#ifdef DEBUG_AUDIO
+ qDebug() << "frames to write to QIODevice = " <<
+ snd_pcm_bytes_to_frames( handle, (int)bytesRead ) << " (" << bytesRead << ") bytes";
+#endif
+ if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+ return 0;
+
+ if (pullMode) {
+ qint64 l = 0;
+ qint64 bytesWritten = 0;
+ while (ringBuffer.bytesOfDataInBuffer() > 0) {
+ l = audioSource->write(ringBuffer.availableData(), ringBuffer.availableDataBlockSize());
+ if (l > 0) {
+ ringBuffer.readBytes(l);
+ bytesWritten += l;
+ } else {
+ break;
+ }
+ }
+
+ if (l < 0) {
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ } else if (l == 0 && bytesWritten == 0) {
+ if (deviceState != QAudio::IdleState) {
+ errorState = QAudio::NoError;
+ deviceState = QAudio::IdleState;
+ emit stateChanged(deviceState);
+ }
+ } else {
+ bytesAvailable -= bytesWritten;
+ totalTimeValue += bytesWritten;
+ resuming = false;
+ if (deviceState != QAudio::ActiveState) {
+ errorState = QAudio::NoError;
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ }
+
+ return bytesWritten;
+ } else {
+ while (ringBuffer.bytesOfDataInBuffer() > 0) {
+ int size = ringBuffer.availableDataBlockSize();
+ memcpy(data, ringBuffer.availableData(), size);
+ data += size;
+ ringBuffer.readBytes(size);
+ }
+
+ bytesAvailable -= bytesRead;
+ totalTimeValue += bytesRead;
+ resuming = false;
+ if (deviceState != QAudio::ActiveState) {
+ errorState = QAudio::NoError;
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+
+ return bytesRead;
+ }
+ }
+
+ return 0;
+}
+
+void QAudioInputPrivate::resume()
+{
+ if(deviceState == QAudio::SuspendedState) {
+ int err = 0;
+
+ if(handle) {
+ err = snd_pcm_prepare( handle );
+ if(err < 0)
+ xrun_recovery(err);
+
+ err = snd_pcm_start(handle);
+ if(err < 0)
+ xrun_recovery(err);
+
+ bytesAvailable = buffer_size;
+ }
+ resuming = true;
+ deviceState = QAudio::ActiveState;
+ int chunks = buffer_size/period_size;
+ timer->start(period_time*chunks/2000);
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioInputPrivate::setBufferSize(int value)
+{
+ buffer_size = value;
+}
+
+int QAudioInputPrivate::bufferSize() const
+{
+ return buffer_size;
+}
+
+int QAudioInputPrivate::periodSize() const
+{
+ return period_size;
+}
+
+void QAudioInputPrivate::setNotifyInterval(int ms)
+{
+ intervalTime = qMax(0, ms);
+}
+
+int QAudioInputPrivate::notifyInterval() const
+{
+ return intervalTime;
+}
+
+qint64 QAudioInputPrivate::processedUSecs() const
+{
+ qint64 result = qint64(1000000) * totalTimeValue /
+ (settings.channels()*(settings.sampleSize()/8)) /
+ settings.frequency();
+
+ return result;
+}
+
+void QAudioInputPrivate::suspend()
+{
+ if(deviceState == QAudio::ActiveState||resuming) {
+ timer->stop();
+ deviceState = QAudio::SuspendedState;
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioInputPrivate::userFeed()
+{
+ if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
+ return;
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() IN";
+#endif
+ deviceReady();
+}
+
+bool QAudioInputPrivate::deviceReady()
+{
+ if(pullMode) {
+ // reads some audio data and writes it to QIODevice
+ read(0, buffer_size);
+ } else {
+ // emits readyRead() so user will call read() on QIODevice to get some audio data
+ InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
+ a->trigger();
+ }
+ bytesAvailable = checkBytesReady();
+
+ if(deviceState != QAudio::ActiveState)
+ return true;
+
+ if (bytesAvailable < 0) {
+ // bytesAvailable as negative is error code, try to recover from it.
+ xrun_recovery(bytesAvailable);
+ bytesAvailable = checkBytesReady();
+ if (bytesAvailable < 0) {
+ // recovery failed must stop and set error.
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return 0;
+ }
+ }
+
+ if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+ emit notify();
+ elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
+ timeStamp.restart();
+ }
+ return true;
+}
+
+qint64 QAudioInputPrivate::elapsedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+
+ return clockStamp.elapsed()*1000;
+}
+
+void QAudioInputPrivate::reset()
+{
+ if(handle)
+ snd_pcm_reset(handle);
+ stop();
+ bytesAvailable = 0;
+}
+
+void QAudioInputPrivate::drain()
+{
+ if(handle)
+ snd_pcm_drain(handle);
+}
+
+InputPrivate::InputPrivate(QAudioInputPrivate* audio)
+{
+ audioDevice = qobject_cast<QAudioInputPrivate*>(audio);
+}
+
+InputPrivate::~InputPrivate()
+{
+}
+
+qint64 InputPrivate::readData( char* data, qint64 len)
+{
+ return audioDevice->read(data,len);
+}
+
+qint64 InputPrivate::writeData(const char* data, qint64 len)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(len)
+ return 0;
+}
+
+void InputPrivate::trigger()
+{
+ emit readyRead();
+}
+
+RingBuffer::RingBuffer() :
+ m_head(0),
+ m_tail(0)
+{
+}
+
+void RingBuffer::resize(int size)
+{
+ m_data.resize(size);
+}
+
+int RingBuffer::bytesOfDataInBuffer() const
+{
+ if (m_head < m_tail)
+ return m_tail - m_head;
+ else if (m_tail < m_head)
+ return m_data.size() + m_tail - m_head;
+ else
+ return 0;
+}
+
+int RingBuffer::freeBytes() const
+{
+ if (m_head > m_tail)
+ return m_head - m_tail - 1;
+ else if (m_tail > m_head)
+ return m_data.size() - m_tail + m_head - 1;
+ else
+ return m_data.size() - 1;
+}
+
+const char *RingBuffer::availableData() const
+{
+ return (m_data.constData() + m_head);
+}
+
+int RingBuffer::availableDataBlockSize() const
+{
+ if (m_head > m_tail)
+ return m_data.size() - m_head;
+ else if (m_tail > m_head)
+ return m_tail - m_head;
+ else
+ return 0;
+}
+
+void RingBuffer::readBytes(int bytes)
+{
+ m_head = (m_head + bytes) % m_data.size();
+}
+
+void RingBuffer::write(char *data, int len)
+{
+ if (m_tail + len < m_data.size()) {
+ memcpy(m_data.data() + m_tail, data, len);
+ m_tail += len;
+ } else {
+ int bytesUntilEnd = m_data.size() - m_tail;
+ memcpy(m_data.data() + m_tail, data, bytesUntilEnd);
+ if (len - bytesUntilEnd > 0)
+ memcpy(m_data.data(), data + bytesUntilEnd, len - bytesUntilEnd);
+ m_tail = len - bytesUntilEnd;
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qaudioinput_alsa_p.cpp"
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h
new file mode 100644
index 000000000..a05f6954d
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_alsa_p.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QAUDIOINPUTALSA_H
+#define QAUDIOINPUTALSA_H
+
+#include <alsa/asoundlib.h>
+
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdatetime.h>
+
+#include "qaudio.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class InputPrivate;
+
+class RingBuffer
+{
+public:
+ RingBuffer();
+
+ void resize(int size);
+
+ int bytesOfDataInBuffer() const;
+ int freeBytes() const;
+
+ const char *availableData() const;
+ int availableDataBlockSize() const;
+ void readBytes(int bytes);
+
+ void write(char *data, int len);
+
+private:
+ int m_head;
+ int m_tail;
+
+ QByteArray m_data;
+};
+
+class QAudioInputPrivate : public QAbstractAudioInput
+{
+ Q_OBJECT
+public:
+ QAudioInputPrivate(const QByteArray &device);
+ ~QAudioInputPrivate();
+
+ qint64 read(char* data, qint64 len);
+
+ void start(QIODevice* device);
+ QIODevice* start();
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+ int bytesReady() const;
+ int periodSize() const;
+ void setBufferSize(int value);
+ int bufferSize() const;
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+ QAudio::Error error() const;
+ QAudio::State state() const;
+ void setFormat(const QAudioFormat& fmt);
+ QAudioFormat format() const;
+ bool resuming;
+ snd_pcm_t* handle;
+ qint64 totalTimeValue;
+ QIODevice* audioSource;
+ QAudioFormat settings;
+ QAudio::Error errorState;
+ QAudio::State deviceState;
+
+private slots:
+ void userFeed();
+ bool deviceReady();
+
+private:
+ int checkBytesReady();
+ int xrun_recovery(int err);
+ int setFormat();
+ bool open();
+ void close();
+ void drain();
+
+ QTimer* timer;
+ QTime timeStamp;
+ QTime clockStamp;
+ qint64 elapsedTimeOffset;
+ int intervalTime;
+ RingBuffer ringBuffer;
+ int bytesAvailable;
+ QByteArray m_device;
+ bool pullMode;
+ int buffer_size;
+ int period_size;
+ unsigned int buffer_time;
+ unsigned int period_time;
+ snd_pcm_uframes_t buffer_frames;
+ snd_pcm_uframes_t period_frames;
+ snd_async_handler_t* ahandler;
+ snd_pcm_access_t access;
+ snd_pcm_format_t pcmformat;
+ snd_timestamp_t* timestamp;
+ snd_pcm_hw_params_t *hwparams;
+};
+
+class InputPrivate : public QIODevice
+{
+ Q_OBJECT
+public:
+ InputPrivate(QAudioInputPrivate* audio);
+ ~InputPrivate();
+
+ qint64 readData( char* data, qint64 len);
+ qint64 writeData(const char* data, qint64 len);
+
+ void trigger();
+private:
+ QAudioInputPrivate *audioDevice;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp
new file mode 100644
index 000000000..184935add
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_mac_p.cpp
@@ -0,0 +1,989 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <QtCore/qendian.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+
+#include <qaudioinput.h>
+
+#include "qaudio_mac_p.h"
+#include "qaudioinput_mac_p.h"
+#include "qaudiodeviceinfo_mac_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+namespace QtMultimediaInternal
+{
+
+static const int default_buffer_size = 4 * 1024;
+
+class QAudioBufferList
+{
+public:
+ QAudioBufferList(AudioStreamBasicDescription const& streamFormat):
+ owner(false),
+ sf(streamFormat)
+ {
+ const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+ const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame;
+
+ dataSize = 0;
+
+ bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) +
+ (sizeof(AudioBuffer) * numberOfBuffers)));
+
+ bfs->mNumberBuffers = numberOfBuffers;
+ for (int i = 0; i < numberOfBuffers; ++i) {
+ bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
+ bfs->mBuffers[i].mDataByteSize = 0;
+ bfs->mBuffers[i].mData = 0;
+ }
+ }
+
+ QAudioBufferList(AudioStreamBasicDescription const& streamFormat, char* buffer, int bufferSize):
+ owner(false),
+ sf(streamFormat),
+ bfs(0)
+ {
+ dataSize = bufferSize;
+
+ bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) + sizeof(AudioBuffer)));
+
+ bfs->mNumberBuffers = 1;
+ bfs->mBuffers[0].mNumberChannels = 1;
+ bfs->mBuffers[0].mDataByteSize = dataSize;
+ bfs->mBuffers[0].mData = buffer;
+ }
+
+ QAudioBufferList(AudioStreamBasicDescription const& streamFormat, int framesToBuffer):
+ owner(true),
+ sf(streamFormat),
+ bfs(0)
+ {
+ const bool isInterleaved = (sf.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
+ const int numberOfBuffers = isInterleaved ? 1 : sf.mChannelsPerFrame;
+
+ dataSize = framesToBuffer * sf.mBytesPerFrame;
+
+ bfs = reinterpret_cast<AudioBufferList*>(qMalloc(sizeof(AudioBufferList) +
+ (sizeof(AudioBuffer) * numberOfBuffers)));
+ bfs->mNumberBuffers = numberOfBuffers;
+ for (int i = 0; i < numberOfBuffers; ++i) {
+ bfs->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
+ bfs->mBuffers[i].mDataByteSize = dataSize;
+ bfs->mBuffers[i].mData = qMalloc(dataSize);
+ }
+ }
+
+ ~QAudioBufferList()
+ {
+ if (owner) {
+ for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i)
+ qFree(bfs->mBuffers[i].mData);
+ }
+
+ qFree(bfs);
+ }
+
+ AudioBufferList* audioBufferList() const
+ {
+ return bfs;
+ }
+
+ char* data(int buffer = 0) const
+ {
+ return static_cast<char*>(bfs->mBuffers[buffer].mData);
+ }
+
+ qint64 bufferSize(int buffer = 0) const
+ {
+ return bfs->mBuffers[buffer].mDataByteSize;
+ }
+
+ int frameCount(int buffer = 0) const
+ {
+ return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerFrame;
+ }
+
+ int packetCount(int buffer = 0) const
+ {
+ return bfs->mBuffers[buffer].mDataByteSize / sf.mBytesPerPacket;
+ }
+
+ int packetSize() const
+ {
+ return sf.mBytesPerPacket;
+ }
+
+ void reset()
+ {
+ for (UInt32 i = 0; i < bfs->mNumberBuffers; ++i) {
+ bfs->mBuffers[i].mDataByteSize = dataSize;
+ bfs->mBuffers[i].mData = 0;
+ }
+ }
+
+private:
+ bool owner;
+ int dataSize;
+ AudioStreamBasicDescription sf;
+ AudioBufferList* bfs;
+};
+
+class QAudioPacketFeeder
+{
+public:
+ QAudioPacketFeeder(QAudioBufferList* abl):
+ audioBufferList(abl)
+ {
+ totalPackets = audioBufferList->packetCount();
+ position = 0;
+ }
+
+ bool feed(AudioBufferList& dst, UInt32& packetCount)
+ {
+ if (position == totalPackets) {
+ dst.mBuffers[0].mDataByteSize = 0;
+ packetCount = 0;
+ return false;
+ }
+
+ if (totalPackets - position < packetCount)
+ packetCount = totalPackets - position;
+
+ dst.mBuffers[0].mDataByteSize = packetCount * audioBufferList->packetSize();
+ dst.mBuffers[0].mData = audioBufferList->data() + (position * audioBufferList->packetSize());
+
+ position += packetCount;
+
+ return true;
+ }
+
+ bool empty() const
+ {
+ return position == totalPackets;
+ }
+
+private:
+ UInt32 totalPackets;
+ UInt32 position;
+ QAudioBufferList* audioBufferList;
+};
+
+class QAudioInputBuffer : public QObject
+{
+ Q_OBJECT
+
+public:
+ QAudioInputBuffer(int bufferSize,
+ int maxPeriodSize,
+ AudioStreamBasicDescription const& inputFormat,
+ AudioStreamBasicDescription const& outputFormat,
+ QObject* parent):
+ QObject(parent),
+ m_deviceError(false),
+ m_audioConverter(0),
+ m_inputFormat(inputFormat),
+ m_outputFormat(outputFormat)
+ {
+ m_maxPeriodSize = maxPeriodSize;
+ m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate;
+ m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
+ m_inputBufferList = new QAudioBufferList(m_inputFormat);
+
+ m_flushTimer = new QTimer(this);
+ connect(m_flushTimer, SIGNAL(timeout()), SLOT(flushBuffer()));
+
+ if (toQAudioFormat(inputFormat) != toQAudioFormat(outputFormat)) {
+ if (AudioConverterNew(&m_inputFormat, &m_outputFormat, &m_audioConverter) != noErr) {
+ qWarning() << "QAudioInput: Unable to create an Audio Converter";
+ m_audioConverter = 0;
+ }
+ }
+ }
+
+ ~QAudioInputBuffer()
+ {
+ delete m_buffer;
+ }
+
+ qint64 renderFromDevice(AudioUnit audioUnit,
+ AudioUnitRenderActionFlags* ioActionFlags,
+ const AudioTimeStamp* inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames)
+ {
+ const bool pullMode = m_device == 0;
+
+ OSStatus err;
+ qint64 framesRendered = 0;
+
+ m_inputBufferList->reset();
+ err = AudioUnitRender(audioUnit,
+ ioActionFlags,
+ inTimeStamp,
+ inBusNumber,
+ inNumberFrames,
+ m_inputBufferList->audioBufferList());
+
+ if (m_audioConverter != 0) {
+ QAudioPacketFeeder feeder(m_inputBufferList);
+
+ int copied = 0;
+ const int available = m_buffer->free();
+
+ while (err == noErr && !feeder.empty()) {
+ QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available);
+
+ if (region.second == 0)
+ break;
+
+ AudioBufferList output;
+ output.mNumberBuffers = 1;
+ output.mBuffers[0].mNumberChannels = 1;
+ output.mBuffers[0].mDataByteSize = region.second;
+ output.mBuffers[0].mData = region.first;
+
+ UInt32 packetSize = region.second / m_outputFormat.mBytesPerPacket;
+ err = AudioConverterFillComplexBuffer(m_audioConverter,
+ converterCallback,
+ &feeder,
+ &packetSize,
+ &output,
+ 0);
+ region.second = output.mBuffers[0].mDataByteSize;
+ copied += region.second;
+
+ m_buffer->releaseWriteRegion(region);
+ }
+
+ framesRendered += copied / m_outputFormat.mBytesPerFrame;
+ }
+ else {
+ const int available = m_inputBufferList->bufferSize();
+ bool wecan = true;
+ int copied = 0;
+
+ while (wecan && copied < available) {
+ QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied);
+
+ if (region.second > 0) {
+ memcpy(region.first, m_inputBufferList->data() + copied, region.second);
+ copied += region.second;
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseWriteRegion(region);
+ }
+
+ framesRendered = copied / m_outputFormat.mBytesPerFrame;
+ }
+
+ if (pullMode && framesRendered > 0)
+ emit readyRead();
+
+ return framesRendered;
+ }
+
+ qint64 readBytes(char* data, qint64 len)
+ {
+ bool wecan = true;
+ qint64 bytesCopied = 0;
+
+ len -= len % m_maxPeriodSize;
+ while (wecan && bytesCopied < len) {
+ QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(len - bytesCopied);
+
+ if (region.second > 0) {
+ memcpy(data + bytesCopied, region.first, region.second);
+ bytesCopied += region.second;
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseReadRegion(region);
+ }
+
+ return bytesCopied;
+ }
+
+ void setFlushDevice(QIODevice* device)
+ {
+ if (m_device != device)
+ m_device = device;
+ }
+
+ void startFlushTimer()
+ {
+ if (m_device != 0) {
+ m_flushTimer->start((m_buffer->size() - (m_maxPeriodSize * 2)) / m_maxPeriodSize * m_periodTime);
+ }
+ }
+
+ void stopFlushTimer()
+ {
+ m_flushTimer->stop();
+ }
+
+ void flush(bool all = false)
+ {
+ if (m_device == 0)
+ return;
+
+ const int used = m_buffer->used();
+ const int readSize = all ? used : used - (used % m_maxPeriodSize);
+
+ if (readSize > 0) {
+ bool wecan = true;
+ int flushed = 0;
+
+ while (!m_deviceError && wecan && flushed < readSize) {
+ QAudioRingBuffer::Region region = m_buffer->acquireReadRegion(readSize - flushed);
+
+ if (region.second > 0) {
+ int bytesWritten = m_device->write(region.first, region.second);
+ if (bytesWritten < 0) {
+ stopFlushTimer();
+ m_deviceError = true;
+ }
+ else {
+ region.second = bytesWritten;
+ flushed += bytesWritten;
+ wecan = bytesWritten != 0;
+ }
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseReadRegion(region);
+ }
+ }
+ }
+
+ void reset()
+ {
+ m_buffer->reset();
+ m_deviceError = false;
+ }
+
+ int available() const
+ {
+ return m_buffer->free();
+ }
+
+ int used() const
+ {
+ return m_buffer->used();
+ }
+
+signals:
+ void readyRead();
+
+private slots:
+ void flushBuffer()
+ {
+ flush();
+ }
+
+private:
+ bool m_deviceError;
+ int m_maxPeriodSize;
+ int m_periodTime;
+ QIODevice* m_device;
+ QTimer* m_flushTimer;
+ QAudioRingBuffer* m_buffer;
+ QAudioBufferList* m_inputBufferList;
+ AudioConverterRef m_audioConverter;
+ AudioStreamBasicDescription m_inputFormat;
+ AudioStreamBasicDescription m_outputFormat;
+
+ const static OSStatus as_empty = 'qtem';
+
+ // Converter callback
+ static OSStatus converterCallback(AudioConverterRef inAudioConverter,
+ UInt32* ioNumberDataPackets,
+ AudioBufferList* ioData,
+ AudioStreamPacketDescription** outDataPacketDescription,
+ void* inUserData)
+ {
+ Q_UNUSED(inAudioConverter);
+ Q_UNUSED(outDataPacketDescription);
+
+ QAudioPacketFeeder* feeder = static_cast<QAudioPacketFeeder*>(inUserData);
+
+ if (!feeder->feed(*ioData, *ioNumberDataPackets))
+ return as_empty;
+
+ return noErr;
+ }
+};
+
+
+class MacInputDevice : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ MacInputDevice(QAudioInputBuffer* audioBuffer, QObject* parent):
+ QIODevice(parent),
+ m_audioBuffer(audioBuffer)
+ {
+ open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ connect(m_audioBuffer, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ }
+
+ qint64 readData(char* data, qint64 len)
+ {
+ return m_audioBuffer->readBytes(data, len);
+ }
+
+ qint64 writeData(const char* data, qint64 len)
+ {
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return 0;
+ }
+
+ bool isSequential() const
+ {
+ return true;
+ }
+
+private:
+ QAudioInputBuffer* m_audioBuffer;
+};
+
+}
+
+
+QAudioInputPrivate::QAudioInputPrivate(const QByteArray& device)
+{
+ QDataStream ds(device);
+ quint32 did, mode;
+
+ ds >> did >> mode;
+
+ if (QAudio::Mode(mode) == QAudio::AudioOutput)
+ errorCode = QAudio::OpenError;
+ else {
+ audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioInput);
+ isOpen = false;
+ audioDeviceId = AudioDeviceID(did);
+ audioUnit = 0;
+ startTime = 0;
+ totalFrames = 0;
+ audioBuffer = 0;
+ internalBufferSize = QtMultimediaInternal::default_buffer_size;
+ clockFrequency = AudioGetHostClockFrequency() / 1000;
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::StoppedState;
+
+ intervalTimer = new QTimer(this);
+ intervalTimer->setInterval(1000);
+ connect(intervalTimer, SIGNAL(timeout()), SIGNAL(notify()));
+ }
+}
+
+QAudioInputPrivate::~QAudioInputPrivate()
+{
+ close();
+ delete audioDeviceInfo;
+}
+
+bool QAudioInputPrivate::open()
+{
+ UInt32 size = 0;
+
+ if (isOpen)
+ return true;
+
+ ComponentDescription cd;
+ cd.componentType = kAudioUnitType_Output;
+ cd.componentSubType = kAudioUnitSubType_HALOutput;
+ cd.componentManufacturer = kAudioUnitManufacturer_Apple;
+ cd.componentFlags = 0;
+ cd.componentFlagsMask = 0;
+
+ // Open
+ Component cp = FindNextComponent(NULL, &cd);
+ if (cp == 0) {
+ qWarning() << "QAudioInput: Failed to find HAL Output component";
+ return false;
+ }
+
+ if (OpenAComponent(cp, &audioUnit) != noErr) {
+ qWarning() << "QAudioInput: Unable to Open Output Component";
+ return false;
+ }
+
+ // Set mode
+ // switch to input mode
+ UInt32 enable = 1;
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Input,
+ 1,
+ &enable,
+ sizeof(enable)) != noErr) {
+ qWarning() << "QAudioInput: Unable to switch to input mode (Enable Input)";
+ return false;
+ }
+
+ enable = 0;
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Output,
+ 0,
+ &enable,
+ sizeof(enable)) != noErr) {
+ qWarning() << "QAudioInput: Unable to switch to input mode (Disable output)";
+ return false;
+ }
+
+ // register callback
+ AURenderCallbackStruct cb;
+ cb.inputProc = inputCallback;
+ cb.inputProcRefCon = this;
+
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioOutputUnitProperty_SetInputCallback,
+ kAudioUnitScope_Global,
+ 0,
+ &cb,
+ sizeof(cb)) != noErr) {
+ qWarning() << "QAudioInput: Failed to set AudioUnit callback";
+ return false;
+ }
+
+ // Set Audio Device
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioOutputUnitProperty_CurrentDevice,
+ kAudioUnitScope_Global,
+ 0,
+ &audioDeviceId,
+ sizeof(audioDeviceId)) != noErr) {
+ qWarning() << "QAudioInput: Unable to use configured device";
+ return false;
+ }
+
+ // Set format
+ // Wanted
+ streamFormat = toAudioStreamBasicDescription(audioFormat);
+
+ // Required on unit
+ if (audioFormat == audioDeviceInfo->preferredFormat()) {
+ deviceFormat = streamFormat;
+ AudioUnitSetProperty(audioUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Output,
+ 1,
+ &deviceFormat,
+ sizeof(deviceFormat));
+ }
+ else {
+ size = sizeof(deviceFormat);
+ if (AudioUnitGetProperty(audioUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input,
+ 1,
+ &deviceFormat,
+ &size) != noErr) {
+ qWarning() << "QAudioInput: Unable to retrieve device format";
+ return false;
+ }
+
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Output,
+ 1,
+ &deviceFormat,
+ sizeof(deviceFormat)) != noErr) {
+ qWarning() << "QAudioInput: Unable to set device format";
+ return false;
+ }
+ }
+
+ // Setup buffers
+ UInt32 numberOfFrames;
+ size = sizeof(UInt32);
+ if (AudioUnitGetProperty(audioUnit,
+ kAudioDevicePropertyBufferFrameSize,
+ kAudioUnitScope_Global,
+ 0,
+ &numberOfFrames,
+ &size) != noErr) {
+ qWarning() << "QAudioInput: Failed to get audio period size";
+ return false;
+ }
+
+ // Allocate buffer
+ periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame;
+
+ if (internalBufferSize < periodSizeBytes * 2)
+ internalBufferSize = periodSizeBytes * 2;
+ else
+ internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame;
+
+ audioBuffer = new QtMultimediaInternal::QAudioInputBuffer(internalBufferSize,
+ periodSizeBytes,
+ deviceFormat,
+ streamFormat,
+ this);
+
+ audioIO = new QtMultimediaInternal::MacInputDevice(audioBuffer, this);
+
+ // Init
+ if (AudioUnitInitialize(audioUnit) != noErr) {
+ qWarning() << "QAudioInput: Failed to initialize AudioUnit";
+ return false;
+ }
+
+ isOpen = true;
+
+ return isOpen;
+}
+
+void QAudioInputPrivate::close()
+{
+ if (audioUnit != 0) {
+ AudioOutputUnitStop(audioUnit);
+ AudioUnitUninitialize(audioUnit);
+ CloseComponent(audioUnit);
+ }
+
+ delete audioBuffer;
+}
+
+QAudioFormat QAudioInputPrivate::format() const
+{
+ return audioFormat;
+}
+
+void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (stateCode == QAudio::StoppedState)
+ audioFormat = fmt;
+}
+
+void QAudioInputPrivate::start(QIODevice* device)
+{
+ QIODevice* op = device;
+
+ if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::OpenError;
+ return;
+ }
+
+ reset();
+ audioBuffer->reset();
+ audioBuffer->setFlushDevice(op);
+
+ if (op == 0)
+ op = audioIO;
+
+ // Start
+ startTime = AudioGetCurrentHostTime();
+ totalFrames = 0;
+
+ audioThreadStart();
+
+ stateCode = QAudio::ActiveState;
+ errorCode = QAudio::NoError;
+ emit stateChanged(stateCode);
+}
+
+QIODevice* QAudioInputPrivate::start()
+{
+ QIODevice* op = 0;
+
+ if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::OpenError;
+ return audioIO;
+ }
+
+ reset();
+ audioBuffer->reset();
+ audioBuffer->setFlushDevice(op);
+
+ if (op == 0)
+ op = audioIO;
+
+ // Start
+ startTime = AudioGetCurrentHostTime();
+ totalFrames = 0;
+
+ audioThreadStart();
+
+ stateCode = QAudio::ActiveState;
+ errorCode = QAudio::NoError;
+ emit stateChanged(stateCode);
+
+ return op;
+}
+
+void QAudioInputPrivate::stop()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode != QAudio::StoppedState) {
+ audioThreadStop();
+ audioBuffer->flush(true);
+
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::StoppedState;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioInputPrivate::reset()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode != QAudio::StoppedState) {
+ audioThreadStop();
+
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::StoppedState;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioInputPrivate::suspend()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState || stateCode == QAudio::IdleState) {
+ audioThreadStop();
+
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::SuspendedState;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioInputPrivate::resume()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::SuspendedState) {
+ audioThreadStart();
+
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::ActiveState;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+int QAudioInputPrivate::bytesReady() const
+{
+ return audioBuffer->used();
+}
+
+int QAudioInputPrivate::periodSize() const
+{
+ return periodSizeBytes;
+}
+
+void QAudioInputPrivate::setBufferSize(int bs)
+{
+ internalBufferSize = bs;
+}
+
+int QAudioInputPrivate::bufferSize() const
+{
+ return internalBufferSize;
+}
+
+void QAudioInputPrivate::setNotifyInterval(int milliSeconds)
+{
+ if (intervalTimer->interval() == milliSeconds)
+ return;
+
+ if (milliSeconds <= 0)
+ milliSeconds = 0;
+
+ intervalTimer->setInterval(milliSeconds);
+}
+
+int QAudioInputPrivate::notifyInterval() const
+{
+ return intervalTimer->interval();
+}
+
+qint64 QAudioInputPrivate::processedUSecs() const
+{
+ return totalFrames * 1000000 / audioFormat.frequency();
+}
+
+qint64 QAudioInputPrivate::elapsedUSecs() const
+{
+ if (stateCode == QAudio::StoppedState)
+ return 0;
+
+ return (AudioGetCurrentHostTime() - startTime) / (clockFrequency / 1000);
+}
+
+QAudio::Error QAudioInputPrivate::error() const
+{
+ return errorCode;
+}
+
+QAudio::State QAudioInputPrivate::state() const
+{
+ return stateCode;
+}
+
+void QAudioInputPrivate::audioThreadStop()
+{
+ stopTimers();
+ if (audioThreadState.testAndSetAcquire(Running, Stopped))
+ threadFinished.wait(&mutex);
+}
+
+void QAudioInputPrivate::audioThreadStart()
+{
+ startTimers();
+ audioThreadState = Running;
+ AudioOutputUnitStart(audioUnit);
+}
+
+void QAudioInputPrivate::audioDeviceStop()
+{
+ AudioOutputUnitStop(audioUnit);
+ audioThreadState = Stopped;
+ threadFinished.wakeOne();
+}
+
+void QAudioInputPrivate::audioDeviceFull()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState) {
+ audioDeviceStop();
+
+ errorCode = QAudio::UnderrunError;
+ stateCode = QAudio::IdleState;
+ QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
+ }
+}
+
+void QAudioInputPrivate::audioDeviceError()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState) {
+ audioDeviceStop();
+
+ errorCode = QAudio::IOError;
+ stateCode = QAudio::StoppedState;
+ QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
+ }
+}
+
+void QAudioInputPrivate::startTimers()
+{
+ audioBuffer->startFlushTimer();
+ if (intervalTimer->interval() > 0)
+ intervalTimer->start();
+}
+
+void QAudioInputPrivate::stopTimers()
+{
+ audioBuffer->stopFlushTimer();
+ intervalTimer->stop();
+}
+
+void QAudioInputPrivate::deviceStopped()
+{
+ stopTimers();
+ emit stateChanged(stateCode);
+}
+
+// Input callback
+OSStatus QAudioInputPrivate::inputCallback(void* inRefCon,
+ AudioUnitRenderActionFlags* ioActionFlags,
+ const AudioTimeStamp* inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData)
+{
+ Q_UNUSED(ioData);
+
+ QAudioInputPrivate* d = static_cast<QAudioInputPrivate*>(inRefCon);
+
+ const int threadState = d->audioThreadState.fetchAndAddAcquire(0);
+ if (threadState == Stopped)
+ d->audioDeviceStop();
+ else {
+ qint64 framesWritten;
+
+ framesWritten = d->audioBuffer->renderFromDevice(d->audioUnit,
+ ioActionFlags,
+ inTimeStamp,
+ inBusNumber,
+ inNumberFrames);
+
+ if (framesWritten > 0)
+ d->totalFrames += framesWritten;
+ else if (framesWritten == 0)
+ d->audioDeviceFull();
+ else if (framesWritten < 0)
+ d->audioDeviceError();
+ }
+
+ return noErr;
+}
+
+
+QT_END_NAMESPACE
+
+#include "qaudioinput_mac_p.moc"
diff --git a/src/multimedia/audio/qaudioinput_mac_p.h b/src/multimedia/audio/qaudioinput_mac_p.h
new file mode 100644
index 000000000..99aaba978
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_mac_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QAUDIOINPUT_MAC_P_H
+#define QAUDIOINPUT_MAC_P_H
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+#include <QtCore/qatomic.h>
+
+#include <qaudio.h>
+#include <qaudioformat.h>
+#include <qaudiosystem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QTimer;
+class QIODevice;
+class QAbstractAudioDeviceInfo;
+
+namespace QtMultimediaInternal
+{
+class QAudioInputBuffer;
+}
+
+class QAudioInputPrivate : public QAbstractAudioInput
+{
+ Q_OBJECT
+
+public:
+ bool isOpen;
+ int periodSizeBytes;
+ int internalBufferSize;
+ qint64 totalFrames;
+ QAudioFormat audioFormat;
+ QIODevice* audioIO;
+ AudioUnit audioUnit;
+ AudioDeviceID audioDeviceId;
+ Float64 clockFrequency;
+ UInt64 startTime;
+ QAudio::Error errorCode;
+ QAudio::State stateCode;
+ QtMultimediaInternal::QAudioInputBuffer* audioBuffer;
+ QMutex mutex;
+ QWaitCondition threadFinished;
+ QAtomicInt audioThreadState;
+ QTimer* intervalTimer;
+ AudioStreamBasicDescription streamFormat;
+ AudioStreamBasicDescription deviceFormat;
+ QAbstractAudioDeviceInfo *audioDeviceInfo;
+
+ QAudioInputPrivate(const QByteArray& device);
+ ~QAudioInputPrivate();
+
+ bool open();
+ void close();
+
+ QAudioFormat format() const;
+ void setFormat(const QAudioFormat& fmt);
+
+ QIODevice* start();
+ void start(QIODevice* device);
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+ void idle();
+
+ int bytesReady() const;
+ int periodSize() const;
+
+ void setBufferSize(int value);
+ int bufferSize() const;
+
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+ void audioThreadStart();
+ void audioThreadStop();
+
+ void audioDeviceStop();
+ void audioDeviceFull();
+ void audioDeviceError();
+
+ void startTimers();
+ void stopTimers();
+
+private slots:
+ void deviceStopped();
+
+private:
+ enum { Running, Stopped };
+
+ // Input callback
+ static OSStatus inputCallback(void* inRefCon,
+ AudioUnitRenderActionFlags* ioActionFlags,
+ const AudioTimeStamp* inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOINPUT_MAC_P_H
diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp
new file mode 100644
index 000000000..718656ba3
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_win32_p.cpp
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+
+#include "qaudioinput_win32_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_AUDIO 1
+
+QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device)
+{
+ bytesAvailable = 0;
+ buffer_size = 0;
+ period_size = 0;
+ m_device = device;
+ totalTimeValue = 0;
+ intervalTime = 1000;
+ errorState = QAudio::NoError;
+ deviceState = QAudio::StoppedState;
+ audioSource = 0;
+ pullMode = true;
+ resuming = false;
+ finished = false;
+ waveBlockOffset = 0;
+}
+
+QAudioInputPrivate::~QAudioInputPrivate()
+{
+ stop();
+}
+
+void QT_WIN_CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg,
+ DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
+{
+ Q_UNUSED(dwParam1)
+ Q_UNUSED(dwParam2)
+ Q_UNUSED(hWaveIn)
+
+ QAudioInputPrivate* qAudio;
+ qAudio = (QAudioInputPrivate*)(dwInstance);
+ if(!qAudio)
+ return;
+
+ QMutexLocker(&qAudio->mutex);
+
+ switch(uMsg) {
+ case WIM_OPEN:
+ break;
+ case WIM_DATA:
+ if(qAudio->waveFreeBlockCount > 0)
+ qAudio->waveFreeBlockCount--;
+ qAudio->feedback();
+ break;
+ case WIM_CLOSE:
+ qAudio->finished = true;
+ break;
+ default:
+ return;
+ }
+}
+
+WAVEHDR* QAudioInputPrivate::allocateBlocks(int size, int count)
+{
+ int i;
+ unsigned char* buffer;
+ WAVEHDR* blocks;
+ DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count;
+
+ if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ totalBufferSize)) == 0) {
+ qWarning("QAudioInput: Memory allocation error");
+ return 0;
+ }
+ blocks = (WAVEHDR*)buffer;
+ buffer += sizeof(WAVEHDR)*count;
+ for(i = 0; i < count; i++) {
+ blocks[i].dwBufferLength = size;
+ blocks[i].lpData = (LPSTR)buffer;
+ blocks[i].dwBytesRecorded=0;
+ blocks[i].dwUser = 0L;
+ blocks[i].dwFlags = 0L;
+ blocks[i].dwLoops = 0L;
+ result = waveInPrepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR));
+ if(result != MMSYSERR_NOERROR) {
+ qWarning("QAudioInput: Can't prepare block %d",i);
+ return 0;
+ }
+ buffer += size;
+ }
+ return blocks;
+}
+
+void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
+{
+ WAVEHDR* blocks = blockArray;
+
+ int count = buffer_size/period_size;
+
+ for(int i = 0; i < count; i++) {
+ waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR));
+ blocks++;
+ }
+ HeapFree(GetProcessHeap(), 0, blockArray);
+}
+
+QAudio::Error QAudioInputPrivate::error() const
+{
+ return errorState;
+}
+
+QAudio::State QAudioInputPrivate::state() const
+{
+ return deviceState;
+}
+
+void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (deviceState == QAudio::StoppedState)
+ settings = fmt;
+}
+
+QAudioFormat QAudioInputPrivate::format() const
+{
+ return settings;
+}
+
+void QAudioInputPrivate::start(QIODevice* device)
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = true;
+ audioSource = device;
+
+ deviceState = QAudio::ActiveState;
+
+ if(!open())
+ return;
+
+ emit stateChanged(deviceState);
+}
+
+QIODevice* QAudioInputPrivate::start()
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = false;
+ audioSource = new InputPrivate(this);
+ audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ deviceState = QAudio::IdleState;
+
+ if(!open())
+ return 0;
+
+ emit stateChanged(deviceState);
+
+ return audioSource;
+}
+
+void QAudioInputPrivate::stop()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+
+ close();
+ emit stateChanged(deviceState);
+}
+
+bool QAudioInputPrivate::open()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
+#endif
+ header = 0;
+
+ period_size = 0;
+
+ if (!settings.isValid()) {
+ qWarning("QAudioInput: open error, invalid format.");
+ } else if (settings.channelCount() <= 0) {
+ qWarning("QAudioInput: open error, invalid number of channels (%d).",
+ settings.channelCount());
+ } else if (settings.sampleSize() <= 0) {
+ qWarning("QAudioInput: open error, invalid sample size (%d).",
+ settings.sampleSize());
+ } else if (settings.frequency() < 8000 || settings.frequency() > 48000) {
+ qWarning("QAudioInput: open error, frequency out of range (%d).", settings.frequency());
+ } else if (buffer_size == 0) {
+
+ buffer_size
+ = (settings.frequency()
+ * settings.channelCount()
+ * settings.sampleSize()
+ + 39) / 40;
+ period_size = buffer_size / 5;
+ } else {
+ period_size = buffer_size / 5;
+ }
+
+ if (period_size == 0) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+
+ timeStamp.restart();
+ elapsedTimeOffset = 0;
+ wfx.nSamplesPerSec = settings.frequency();
+ wfx.wBitsPerSample = settings.sampleSize();
+ wfx.nChannels = settings.channels();
+ wfx.cbSize = 0;
+
+ wfx.wFormatTag = WAVE_FORMAT_PCM;
+ wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
+ wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
+
+ QDataStream ds(&m_device, QIODevice::ReadOnly);
+ quint32 deviceId;
+ ds >> deviceId;
+
+ if (waveInOpen(&hWaveIn, UINT_PTR(deviceId), &wfx,
+ (DWORD_PTR)&waveInProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioInput: failed to open audio device");
+ return false;
+ }
+ waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
+ waveBlockOffset = 0;
+
+ if(waveBlocks == 0) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioInput: failed to allocate blocks. open failed");
+ return false;
+ }
+
+ mutex.lock();
+ waveFreeBlockCount = buffer_size/period_size;
+ mutex.unlock();
+
+ for(int i=0; i<buffer_size/period_size; i++) {
+ result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
+ if(result != MMSYSERR_NOERROR) {
+ qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+ }
+ result = waveInStart(hWaveIn);
+ if(result) {
+ qWarning("QAudioInput: failed to start audio input");
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+ timeStampOpened.restart();
+ elapsedTimeOffset = 0;
+ totalTimeValue = 0;
+ errorState = QAudio::NoError;
+ return true;
+}
+
+void QAudioInputPrivate::close()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+
+ deviceState = QAudio::StoppedState;
+ waveInReset(hWaveIn);
+ waveInClose(hWaveIn);
+
+ int count = 0;
+ while(!finished && count < 500) {
+ count++;
+ Sleep(10);
+ }
+
+ mutex.lock();
+ for(int i=0; i<waveFreeBlockCount; i++)
+ waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR));
+ freeBlocks(waveBlocks);
+ mutex.unlock();
+}
+
+int QAudioInputPrivate::bytesReady() const
+{
+ if(period_size == 0 || buffer_size == 0)
+ return 0;
+
+ int buf = ((buffer_size/period_size)-waveFreeBlockCount)*period_size;
+ if(buf < 0)
+ buf = 0;
+ return buf;
+}
+
+qint64 QAudioInputPrivate::read(char* data, qint64 len)
+{
+ bool done = false;
+
+ char* p = data;
+ qint64 l = 0;
+ qint64 written = 0;
+ while(!done) {
+ // Read in some audio data
+ if(waveBlocks[header].dwBytesRecorded > 0 && waveBlocks[header].dwFlags & WHDR_DONE) {
+ if(pullMode) {
+ l = audioSource->write(waveBlocks[header].lpData + waveBlockOffset,
+ waveBlocks[header].dwBytesRecorded - waveBlockOffset);
+#ifdef DEBUG_AUDIO
+ qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
+#endif
+ if(l < 0) {
+ // error
+ qWarning("QAudioInput: IOError");
+ errorState = QAudio::IOError;
+
+ } else if(l == 0) {
+ // cant write to IODevice
+ qWarning("QAudioInput: IOError, can't write to QIODevice");
+ errorState = QAudio::IOError;
+
+ } else {
+ totalTimeValue += l;
+ errorState = QAudio::NoError;
+ if (deviceState != QAudio::ActiveState) {
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ resuming = false;
+ }
+ } else {
+ l = qMin<qint64>(len, waveBlocks[header].dwBytesRecorded - waveBlockOffset);
+ // push mode
+ memcpy(p, waveBlocks[header].lpData + waveBlockOffset, l);
+
+ len -= l;
+
+#ifdef DEBUG_AUDIO
+ qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
+#endif
+ totalTimeValue += l;
+ errorState = QAudio::NoError;
+ if (deviceState != QAudio::ActiveState) {
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ resuming = false;
+ }
+ } else {
+ //no data, not ready yet, next time
+ break;
+ }
+
+ if (l < waveBlocks[header].dwBytesRecorded - waveBlockOffset) {
+ waveBlockOffset += l;
+ done = true;
+ } else {
+ waveBlockOffset = 0;
+
+ waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
+
+ mutex.lock();
+ waveFreeBlockCount++;
+ mutex.unlock();
+
+ waveBlocks[header].dwBytesRecorded=0;
+ waveBlocks[header].dwFlags = 0L;
+ result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
+ if(result != MMSYSERR_NOERROR) {
+ result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
+ qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result);
+ errorState = QAudio::IOError;
+
+ mutex.lock();
+ waveFreeBlockCount--;
+ mutex.unlock();
+
+ return 0;
+ }
+ result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR));
+ if(result != MMSYSERR_NOERROR) {
+ qWarning("QAudioInput: failed to setup block %d,err=%d",header,result);
+ errorState = QAudio::IOError;
+
+ mutex.lock();
+ waveFreeBlockCount--;
+ mutex.unlock();
+
+ return 0;
+ }
+ header++;
+ if(header >= buffer_size/period_size)
+ header = 0;
+ p+=l;
+
+ mutex.lock();
+ if(!pullMode) {
+ if(len < period_size || waveFreeBlockCount == buffer_size/period_size)
+ done = true;
+ } else {
+ if(waveFreeBlockCount == buffer_size/period_size)
+ done = true;
+ }
+ mutex.unlock();
+ }
+
+ written+=l;
+ }
+#ifdef DEBUG_AUDIO
+ qDebug()<<"read in len="<<written;
+#endif
+ return written;
+}
+
+void QAudioInputPrivate::resume()
+{
+ if(deviceState == QAudio::SuspendedState) {
+ deviceState = QAudio::ActiveState;
+ for(int i=0; i<buffer_size/period_size; i++) {
+ result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
+ if(result != MMSYSERR_NOERROR) {
+ qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return;
+ }
+ }
+
+ mutex.lock();
+ waveFreeBlockCount = buffer_size/period_size;
+ mutex.unlock();
+
+ header = 0;
+ resuming = true;
+ waveBlockOffset = 0;
+ waveInStart(hWaveIn);
+ QTimer::singleShot(20,this,SLOT(feedback()));
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioInputPrivate::setBufferSize(int value)
+{
+ buffer_size = value;
+}
+
+int QAudioInputPrivate::bufferSize() const
+{
+ return buffer_size;
+}
+
+int QAudioInputPrivate::periodSize() const
+{
+ return period_size;
+}
+
+void QAudioInputPrivate::setNotifyInterval(int ms)
+{
+ intervalTime = qMax(0, ms);
+}
+
+int QAudioInputPrivate::notifyInterval() const
+{
+ return intervalTime;
+}
+
+qint64 QAudioInputPrivate::processedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+ qint64 result = qint64(1000000) * totalTimeValue /
+ (settings.channels()*(settings.sampleSize()/8)) /
+ settings.frequency();
+
+ return result;
+}
+
+void QAudioInputPrivate::suspend()
+{
+ if(deviceState == QAudio::ActiveState) {
+ waveInReset(hWaveIn);
+ deviceState = QAudio::SuspendedState;
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioInputPrivate::feedback()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this;
+#endif
+ if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState))
+ QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection);
+}
+
+bool QAudioInputPrivate::deviceReady()
+{
+ bytesAvailable = bytesReady();
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT";
+#endif
+ if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+ return true;
+
+ if(pullMode) {
+ // reads some audio data and writes it to QIODevice
+ read(0, buffer_size);
+ } else {
+ // emits readyRead() so user will call read() on QIODevice to get some audio data
+ InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
+ a->trigger();
+ }
+
+ if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+ emit notify();
+ elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
+ timeStamp.restart();
+ }
+ return true;
+}
+
+qint64 QAudioInputPrivate::elapsedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+
+ return timeStampOpened.elapsed()*1000;
+}
+
+void QAudioInputPrivate::reset()
+{
+ stop();
+ if (period_size > 0)
+ waveFreeBlockCount = buffer_size / period_size;
+}
+
+InputPrivate::InputPrivate(QAudioInputPrivate* audio)
+{
+ audioDevice = qobject_cast<QAudioInputPrivate*>(audio);
+}
+
+InputPrivate::~InputPrivate() {}
+
+qint64 InputPrivate::readData( char* data, qint64 len)
+{
+ // push mode, user read() called
+ if(audioDevice->deviceState != QAudio::ActiveState &&
+ audioDevice->deviceState != QAudio::IdleState)
+ return 0;
+ // Read in some audio data
+ return audioDevice->read(data,len);
+}
+
+qint64 InputPrivate::writeData(const char* data, qint64 len)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(len)
+
+ emit readyRead();
+ return 0;
+}
+
+void InputPrivate::trigger()
+{
+ emit readyRead();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qaudioinput_win32_p.cpp"
+
diff --git a/src/multimedia/audio/qaudioinput_win32_p.h b/src/multimedia/audio/qaudioinput_win32_p.h
new file mode 100644
index 000000000..10d41a552
--- /dev/null
+++ b/src/multimedia/audio/qaudioinput_win32_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOINPUTWIN_H
+#define QAUDIOINPUTWIN_H
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qmutex.h>
+
+#include <qaudio.h>
+#include <qaudiodeviceinfo.h>
+#include <qaudiosystem.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+// For compat with 4.6
+#if !defined(QT_WIN_CALLBACK)
+# if defined(Q_CC_MINGW)
+# define QT_WIN_CALLBACK CALLBACK __attribute__ ((force_align_arg_pointer))
+# else
+# define QT_WIN_CALLBACK CALLBACK
+# endif
+#endif
+
+class QAudioInputPrivate : public QAbstractAudioInput
+{
+ Q_OBJECT
+public:
+ QAudioInputPrivate(const QByteArray &device);
+ ~QAudioInputPrivate();
+
+ qint64 read(char* data, qint64 len);
+
+ void setFormat(const QAudioFormat& fmt);
+ QAudioFormat format() const;
+ QIODevice* start();
+ void start(QIODevice* device);
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+ int bytesReady() const;
+ int periodSize() const;
+ void setBufferSize(int value);
+ int bufferSize() const;
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+ QIODevice* audioSource;
+ QAudioFormat settings;
+ QAudio::Error errorState;
+ QAudio::State deviceState;
+
+private:
+ qint32 buffer_size;
+ qint32 period_size;
+ qint32 header;
+ QByteArray m_device;
+ int bytesAvailable;
+ int intervalTime;
+ QTime timeStamp;
+ qint64 elapsedTimeOffset;
+ QTime timeStampOpened;
+ qint64 totalTimeValue;
+ bool pullMode;
+ bool resuming;
+ WAVEFORMATEX wfx;
+ HWAVEIN hWaveIn;
+ MMRESULT result;
+ WAVEHDR* waveBlocks;
+ volatile bool finished;
+ volatile int waveFreeBlockCount;
+ int waveBlockOffset;
+
+ QMutex mutex;
+ static void QT_WIN_CALLBACK waveInProc( HWAVEIN hWaveIn, UINT uMsg,
+ DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
+
+ WAVEHDR* allocateBlocks(int size, int count);
+ void freeBlocks(WAVEHDR* blockArray);
+ bool open();
+ void close();
+
+private slots:
+ void feedback();
+ bool deviceReady();
+
+signals:
+ void processMore();
+};
+
+class InputPrivate : public QIODevice
+{
+ Q_OBJECT
+public:
+ InputPrivate(QAudioInputPrivate* audio);
+ ~InputPrivate();
+
+ qint64 readData( char* data, qint64 len);
+ qint64 writeData(const char* data, qint64 len);
+
+ void trigger();
+private:
+ QAudioInputPrivate *audioDevice;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp
new file mode 100644
index 000000000..05db98bd6
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput.cpp
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qaudio.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+#include "qaudiooutput.h"
+
+#include "qaudiodevicefactory_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAudioOutput
+ \brief The QAudioOutput class provides an interface for sending audio data to an audio output device.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ You can construct an audio output with the system's
+ \l{QAudioDeviceInfo::defaultOutputDevice()}{default audio output
+ device}. It is also possible to create QAudioOutput with a
+ specific QAudioDeviceInfo. When you create the audio output, you
+ should also send in the QAudioFormat to be used for the playback
+ (see the QAudioFormat class description for details).
+
+ To play a file:
+
+ Starting to play an audio stream is simply a matter of calling
+ start() with a QIODevice. QAudioOutput will then fetch the data it
+ needs from the io device. So playing back an audio file is as
+ simple as:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio output class members
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio output setup
+
+ The file will start playing assuming that the audio system and
+ output device support it. If you run out of luck, check what's
+ up with the error() function.
+
+ After the file has finished playing, we need to stop the device:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio output state changed
+
+ At any given time, the QAudioOutput will be in one of four states:
+ active, suspended, stopped, or idle. These states are described
+ by the QAudio::State enum.
+ State changes are reported through the stateChanged() signal. You
+ can use this signal to, for instance, update the GUI of the
+ application; the mundane example here being changing the state of
+ a \c { play/pause } button. You request a state change directly
+ with suspend(), stop(), reset(), resume(), and start().
+
+ While the stream is playing, you can set a notify interval in
+ milliseconds with setNotifyInterval(). This interval specifies the
+ time between two emissions of the notify() signal. This is
+ relative to the position in the stream, i.e., if the QAudioOutput
+ is in the SuspendedState or the IdleState, the notify() signal is
+ not emitted. A typical use-case would be to update a
+ \l{QSlider}{slider} that allows seeking in the stream.
+ If you want the time since playback started regardless of which
+ states the audio output has been in, elapsedUSecs() is the function for you.
+
+ If an error occurs, you can fetch the \l{QAudio::Error}{error
+ type} with the error() function. Please see the QAudio::Error enum
+ for a description of the possible errors that are reported. When
+ an error is encountered, the state changes to QAudio::StoppedState.
+ You can check for errors by connecting to the stateChanged()
+ signal:
+
+ \snippet doc/src/snippets/multimedia-snippets/audio.cpp Audio output state changed
+
+ \sa QAudioInput, QAudioDeviceInfo
+*/
+
+/*!
+ Construct a new audio output and attach it to \a parent.
+ The default audio output device is used with the output
+ \a format parameters.
+ \since 1.0
+*/
+QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent):
+ QObject(parent)
+{
+ d = QAudioDeviceFactory::createDefaultOutputDevice(format);
+ connect(d, SIGNAL(notify()), SIGNAL(notify()));
+ connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
+}
+
+/*!
+ Construct a new audio output and attach it to \a parent.
+ The device referenced by \a audioDevice is used with the output
+ \a format parameters.
+ \since 1.0
+*/
+QAudioOutput::QAudioOutput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent):
+ QObject(parent)
+{
+ d = QAudioDeviceFactory::createOutputDevice(audioDevice, format);
+ connect(d, SIGNAL(notify()), SIGNAL(notify()));
+ connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
+}
+
+/*!
+ Destroys this audio output.
+
+ This will release any system resources used and free any buffers.
+*/
+QAudioOutput::~QAudioOutput()
+{
+ delete d;
+}
+
+/*!
+ Returns the QAudioFormat being used.
+
+ \since 1.0
+*/
+QAudioFormat QAudioOutput::format() const
+{
+ return d->format();
+}
+
+/*!
+ Uses the \a device as the QIODevice to transfer data.
+ Passing a QIODevice allows the data to be transferred without any extra code.
+ All that is required is to open the QIODevice.
+
+ If able to successfully output audio data to the systems audio device the
+ state() is set to QAudio::ActiveState, error() is set to QAudio::NoError
+ and the stateChanged() signal is emitted.
+
+ If a problem occurs during this process the error() is set to QAudio::OpenError,
+ state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+ \since 1.0
+ \sa QIODevice
+*/
+void QAudioOutput::start(QIODevice* device)
+{
+ d->start(device);
+}
+
+/*!
+ Returns a pointer to the QIODevice being used to handle the data
+ transfer. This QIODevice can be used to write() audio data directly.
+
+ If able to access the systems audio device the state() is set to
+ QAudio::IdleState, error() is set to QAudio::NoError
+ and the stateChanged() signal is emitted.
+
+ If a problem occurs during this process the error() is set to QAudio::OpenError,
+ state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
+
+ \since 1.0
+ \sa QIODevice
+*/
+QIODevice* QAudioOutput::start()
+{
+ return d->start();
+}
+
+/*!
+ Stops the audio output, detaching from the system resource.
+
+ Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
+ emit stateChanged() signal.
+ \since 1.0
+*/
+void QAudioOutput::stop()
+{
+ d->stop();
+}
+
+/*!
+ Drops all audio data in the buffers, resets buffers to zero.
+
+ \since 1.0
+*/
+void QAudioOutput::reset()
+{
+ d->reset();
+}
+
+/*!
+ Stops processing audio data, preserving buffered audio data.
+
+ Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
+ emits stateChanged() signal.
+ \since 1.0
+*/
+void QAudioOutput::suspend()
+{
+ d->suspend();
+}
+
+/*!
+ Resumes processing audio data after a suspend().
+
+ Sets error() to QAudio::NoError.
+ Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
+ Sets state() to QAudio::IdleState if you previously called start().
+ emits stateChanged() signal.
+ \since 1.0
+*/
+void QAudioOutput::resume()
+{
+ d->resume();
+}
+
+/*!
+ Returns the number of free bytes available in the audio buffer.
+
+ \note The returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
+ state, otherwise returns zero.
+ \since 1.0
+*/
+int QAudioOutput::bytesFree() const
+{
+ return d->bytesFree();
+}
+
+/*!
+ Returns the period size in bytes. This is the amount of data required each period
+ to prevent buffer underrun, and to ensure uninterrupted playback.
+
+ \note It is recommended to provide at least enough data for a full period with each
+ write operation.
+ \since 1.0
+*/
+int QAudioOutput::periodSize() const
+{
+ return d->periodSize();
+}
+
+/*!
+ Sets the audio buffer size to \a value in bytes.
+
+ \note This function can be called anytime before start(). Calls to this
+ are ignored after start(). It should not be assumed that the buffer size
+ set is the actual buffer size used - call bufferSize() anytime after start()
+ to return the actual buffer size being used.
+ \since 1.0
+*/
+void QAudioOutput::setBufferSize(int value)
+{
+ d->setBufferSize(value);
+}
+
+/*!
+ Returns the audio buffer size in bytes.
+
+ If called before start(), returns platform default value.
+ If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
+ If called after start(), returns the actual buffer size being used. This may not be what was set previously
+ by setBufferSize().
+
+ \since 1.0
+*/
+int QAudioOutput::bufferSize() const
+{
+ return d->bufferSize();
+}
+
+/*!
+ Sets the interval for notify() signal to be emitted.
+ This is based on the \a ms of audio data processed,
+ not on wall clock time.
+ The minimum resolution of the timer is platform specific and values
+ should be checked with notifyInterval() to confirm the actual value
+ being used.
+ \since 1.0
+*/
+void QAudioOutput::setNotifyInterval(int ms)
+{
+ d->setNotifyInterval(ms);
+}
+
+/*!
+ Returns the notify interval in milliseconds.
+ \since 1.0
+*/
+int QAudioOutput::notifyInterval() const
+{
+ return d->notifyInterval();
+}
+
+/*!
+ Returns the amount of audio data processed since start()
+ was called (in microseconds).
+ \since 1.0
+*/
+qint64 QAudioOutput::processedUSecs() const
+{
+ return d->processedUSecs();
+}
+
+/*!
+ Returns the microseconds since start() was called, including time in Idle and
+ Suspend states.
+ \since 1.0
+*/
+qint64 QAudioOutput::elapsedUSecs() const
+{
+ return d->elapsedUSecs();
+}
+
+/*!
+ Returns the error state.
+ \since 1.0
+*/
+QAudio::Error QAudioOutput::error() const
+{
+ return d->error();
+}
+
+/*!
+ Returns the state of audio processing.
+ \since 1.0
+*/
+QAudio::State QAudioOutput::state() const
+{
+ return d->state();
+}
+
+/*!
+ Sets the volume.
+ Where \a volume is between 0.0 and 1.0 inclusive.
+ \since 5.0
+*/
+void QAudioOutput::setVolume(qreal volume)
+{
+ d->setVolume(volume);
+}
+
+/*!
+ Returns the volume between 0.0 and 1.0 inclusive.
+ \since 5.0
+*/
+qreal QAudioOutput::volume() const
+{
+ return d->volume();
+}
+
+/*!
+ \fn QAudioOutput::stateChanged(QAudio::State state)
+ This signal is emitted when the device \a state has changed.
+ This is the current state of the audio output.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioOutput::notify()
+ This signal is emitted when a certain interval of milliseconds
+ of audio data has been processed. The interval is set by
+ setNotifyInterval().
+ \since 1.0
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qaudiooutput.cpp"
diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h
new file mode 100644
index 000000000..3edec1b4a
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIOOUTPUT_H
+#define QAUDIOOUTPUT_H
+
+#include <QtCore/qiodevice.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include <qaudio.h>
+#include <qaudioformat.h>
+#include <qaudiodeviceinfo.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QAbstractAudioOutput;
+
+class Q_MULTIMEDIA_EXPORT QAudioOutput : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QAudioOutput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0);
+ explicit QAudioOutput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0);
+ ~QAudioOutput();
+
+ QAudioFormat format() const;
+
+ void start(QIODevice *device);
+ QIODevice* start();
+
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+
+ void setBufferSize(int bytes);
+ int bufferSize() const;
+
+ int bytesFree() const;
+ int periodSize() const;
+
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+ void setVolume(qreal);
+ qreal volume() const;
+
+Q_SIGNALS:
+ void stateChanged(QAudio::State);
+ void notify();
+
+private:
+ Q_DISABLE_COPY(QAudioOutput)
+
+ QAbstractAudioOutput* d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOOUTPUT_H
diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp
new file mode 100644
index 000000000..8ef4e2819
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp
@@ -0,0 +1,834 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include "qaudiooutput_alsa_p.h"
+#include "qaudiodeviceinfo_alsa_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_AUDIO 1
+
+QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device)
+{
+ bytesAvailable = 0;
+ handle = 0;
+ ahandler = 0;
+ access = SND_PCM_ACCESS_RW_INTERLEAVED;
+ pcmformat = SND_PCM_FORMAT_S16;
+ buffer_frames = 0;
+ period_frames = 0;
+ buffer_size = 0;
+ period_size = 0;
+ buffer_time = 100000;
+ period_time = 20000;
+ totalTimeValue = 0;
+ intervalTime = 1000;
+ audioBuffer = 0;
+ errorState = QAudio::NoError;
+ deviceState = QAudio::StoppedState;
+ audioSource = 0;
+ pullMode = true;
+ resuming = false;
+ opened = false;
+
+ m_device = device;
+
+ timer = new QTimer(this);
+ connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
+}
+
+QAudioOutputPrivate::~QAudioOutputPrivate()
+{
+ close();
+ disconnect(timer, SIGNAL(timeout()));
+ QCoreApplication::processEvents();
+ delete timer;
+}
+
+QAudio::Error QAudioOutputPrivate::error() const
+{
+ return errorState;
+}
+
+QAudio::State QAudioOutputPrivate::state() const
+{
+ return deviceState;
+}
+
+void QAudioOutputPrivate::async_callback(snd_async_handler_t *ahandler)
+{
+ QAudioOutputPrivate* audioOut;
+
+ audioOut = static_cast<QAudioOutputPrivate*>
+ (snd_async_handler_get_callback_private(ahandler));
+
+ if((audioOut->deviceState==QAudio::ActiveState)||(audioOut->resuming))
+ audioOut->feedback();
+}
+
+int QAudioOutputPrivate::xrun_recovery(int err)
+{
+ int count = 0;
+ bool reset = false;
+
+ if(err == -EPIPE) {
+ errorState = QAudio::UnderrunError;
+ emit errorChanged(errorState);
+ err = snd_pcm_prepare(handle);
+ if(err < 0)
+ reset = true;
+
+ } else if((err == -ESTRPIPE)||(err == -EIO)) {
+ errorState = QAudio::IOError;
+ emit errorChanged(errorState);
+ while((err = snd_pcm_resume(handle)) == -EAGAIN){
+ usleep(100);
+ count++;
+ if(count > 5) {
+ reset = true;
+ break;
+ }
+ }
+ if(err < 0) {
+ err = snd_pcm_prepare(handle);
+ if(err < 0)
+ reset = true;
+ }
+ }
+ if(reset) {
+ close();
+ open();
+ snd_pcm_prepare(handle);
+ return 0;
+ }
+ return err;
+}
+
+int QAudioOutputPrivate::setFormat()
+{
+ snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN;
+
+ if(settings.sampleSize() == 8) {
+ pcmformat = SND_PCM_FORMAT_U8;
+
+ } else if(settings.sampleSize() == 16) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_S16_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_S16_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_U16_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_U16_BE;
+ }
+ } else if(settings.sampleSize() == 24) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_S24_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_S24_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_U24_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_U24_BE;
+ }
+ } else if(settings.sampleSize() == 32) {
+ if(settings.sampleType() == QAudioFormat::SignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_S32_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_S32_BE;
+ } else if(settings.sampleType() == QAudioFormat::UnSignedInt) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_U32_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_U32_BE;
+ } else if(settings.sampleType() == QAudioFormat::Float) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_FLOAT_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_FLOAT_BE;
+ }
+ } else if(settings.sampleSize() == 64) {
+ if(settings.byteOrder() == QAudioFormat::LittleEndian)
+ pcmformat = SND_PCM_FORMAT_FLOAT64_LE;
+ else
+ pcmformat = SND_PCM_FORMAT_FLOAT64_BE;
+ }
+
+ return pcmformat != SND_PCM_FORMAT_UNKNOWN
+ ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat)
+ : -1;
+}
+
+void QAudioOutputPrivate::start(QIODevice* device)
+{
+ if(deviceState != QAudio::StoppedState)
+ deviceState = QAudio::StoppedState;
+
+ errorState = QAudio::NoError;
+
+ // Handle change of mode
+ if(audioSource && !pullMode) {
+ delete audioSource;
+ audioSource = 0;
+ }
+
+ close();
+
+ pullMode = true;
+ audioSource = device;
+
+ deviceState = QAudio::ActiveState;
+
+ open();
+
+ emit stateChanged(deviceState);
+}
+
+QIODevice* QAudioOutputPrivate::start()
+{
+ if(deviceState != QAudio::StoppedState)
+ deviceState = QAudio::StoppedState;
+
+ errorState = QAudio::NoError;
+
+ // Handle change of mode
+ if(audioSource && !pullMode) {
+ delete audioSource;
+ audioSource = 0;
+ }
+
+ close();
+
+ audioSource = new OutputPrivate(this);
+ audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
+ pullMode = false;
+
+ deviceState = QAudio::IdleState;
+
+ open();
+
+ emit stateChanged(deviceState);
+
+ return audioSource;
+}
+
+void QAudioOutputPrivate::stop()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+ errorState = QAudio::NoError;
+ deviceState = QAudio::StoppedState;
+ close();
+ emit stateChanged(deviceState);
+}
+
+bool QAudioOutputPrivate::open()
+{
+ if(opened)
+ return true;
+
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
+#endif
+ timeStamp.restart();
+ elapsedTimeOffset = 0;
+
+ int dir;
+ int err = 0;
+ int count=0;
+ unsigned int freakuency=settings.frequency();
+
+ if (!settings.isValid()) {
+ qWarning("QAudioOutput: open error, invalid format.");
+ } else if (settings.sampleRate() <= 0) {
+ qWarning("QAudioOutput: open error, invalid sample rate (%d).",
+ settings.sampleRate());
+ } else {
+ err = -1;
+ }
+
+ if (err == 0) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit errorChanged(errorState);
+ return false;
+ }
+
+ QString dev = QString(QLatin1String(m_device.constData()));
+ QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput);
+ if(dev.compare(QLatin1String("default")) == 0) {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ if (devices.size() > 0)
+ dev = QLatin1String(devices.first());
+ else
+ return false;
+#else
+ dev = QLatin1String("hw:0,0");
+#endif
+ } else {
+#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
+ dev = QLatin1String(m_device);
+#else
+ int idx = 0;
+ char *name;
+
+ QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());
+
+ while(snd_card_get_name(idx,&name) == 0) {
+ if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
+ break;
+ idx++;
+ }
+ dev = QString(QLatin1String("hw:%1,0")).arg(idx);
+#endif
+ }
+
+ // Step 1: try and open the device
+ while((count < 5) && (err < 0)) {
+ err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);
+ if(err < 0)
+ count++;
+ }
+ if (( err < 0)||(handle == 0)) {
+ errorState = QAudio::OpenError;
+ emit errorChanged(errorState);
+ deviceState = QAudio::StoppedState;
+ return false;
+ }
+ snd_pcm_nonblock( handle, 0 );
+
+ // Step 2: Set the desired HW parameters.
+ snd_pcm_hw_params_alloca( &hwparams );
+
+ bool fatal = false;
+ QString errMessage;
+ unsigned int chunks = 8;
+
+ err = snd_pcm_hw_params_any( handle, hwparams );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_any: err = %1").arg(err);
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_access( handle, hwparams, access );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_access: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = setFormat();
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_format: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &freakuency, 0 );
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ unsigned int maxBufferTime = 0;
+ unsigned int minBufferTime = 0;
+ unsigned int maxPeriodTime = 0;
+ unsigned int minPeriodTime = 0;
+
+ err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &maxBufferTime, &dir);
+ if ( err >= 0)
+ err = snd_pcm_hw_params_get_buffer_time_min(hwparams, &minBufferTime, &dir);
+ if ( err >= 0)
+ err = snd_pcm_hw_params_get_period_time_max(hwparams, &maxPeriodTime, &dir);
+ if ( err >= 0)
+ err = snd_pcm_hw_params_get_period_time_min(hwparams, &minPeriodTime, &dir);
+
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: buffer/period min and max: err = %1").arg(err);
+ } else {
+ if (maxBufferTime < buffer_time || buffer_time < minBufferTime || maxPeriodTime < period_time || minPeriodTime > period_time) {
+#ifdef DEBUG_AUDIO
+ qDebug()<<"defaults out of range";
+ qDebug()<<"pmin="<<minPeriodTime<<", pmax="<<maxPeriodTime<<", bmin="<<minBufferTime<<", bmax="<<maxBufferTime;
+#endif
+ period_time = minPeriodTime;
+ if (period_time*4 <= maxBufferTime) {
+ // Use 4 periods if possible
+ buffer_time = period_time*4;
+ chunks = 4;
+ } else if (period_time*2 <= maxBufferTime) {
+ // Use 2 periods if possible
+ buffer_time = period_time*2;
+ chunks = 2;
+ } else {
+ qWarning()<<"QAudioOutput: alsa only supports single period!";
+ fatal = true;
+ }
+#ifdef DEBUG_AUDIO
+ qDebug()<<"used: buffer_time="<<buffer_time<<", period_time="<<period_time;
+#endif
+ }
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
+ }
+ }
+ if ( !fatal ) {
+ err = snd_pcm_hw_params(handle, hwparams);
+ if ( err < 0 ) {
+ fatal = true;
+ errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params: err = %1").arg(err);
+ }
+ }
+ if( err < 0) {
+ qWarning()<<errMessage;
+ errorState = QAudio::OpenError;
+ emit errorChanged(errorState);
+ deviceState = QAudio::StoppedState;
+ return false;
+ }
+ snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
+ buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
+ snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
+ period_size = snd_pcm_frames_to_bytes(handle,period_frames);
+ snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
+ snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
+
+ // Step 3: Set the desired SW parameters.
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_sw_params_alloca(&swparams);
+ snd_pcm_sw_params_current(handle, swparams);
+ snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
+ snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
+ snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
+ snd_pcm_sw_params(handle, swparams);
+
+ // Step 4: Prepare audio
+ if(audioBuffer == 0)
+ audioBuffer = new char[snd_pcm_frames_to_bytes(handle,buffer_frames)];
+ snd_pcm_prepare( handle );
+ snd_pcm_start(handle);
+
+ // Step 5: Setup callback and timer fallback
+ snd_async_add_pcm_handler(&ahandler, handle, async_callback, this);
+ bytesAvailable = bytesFree();
+
+ // Step 6: Start audio processing
+ timer->start(period_time/1000);
+
+ clockStamp.restart();
+ timeStamp.restart();
+ elapsedTimeOffset = 0;
+ errorState = QAudio::NoError;
+ totalTimeValue = 0;
+ opened = true;
+
+ return true;
+}
+
+void QAudioOutputPrivate::close()
+{
+ timer->stop();
+
+ if ( handle ) {
+ snd_pcm_drain( handle );
+ snd_pcm_close( handle );
+ handle = 0;
+ delete [] audioBuffer;
+ audioBuffer=0;
+ }
+ if(!pullMode && audioSource) {
+ delete audioSource;
+ audioSource = 0;
+ }
+ opened = false;
+}
+
+int QAudioOutputPrivate::bytesFree() const
+{
+ if(resuming)
+ return period_size;
+
+ if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+ return 0;
+
+ int frames = snd_pcm_avail_update(handle);
+ if (frames == -EPIPE) {
+ // Try and handle buffer underrun
+ int err = snd_pcm_recover(handle, frames, 0);
+ if (err < 0)
+ return 0;
+ else
+ frames = snd_pcm_avail_update(handle);
+ } else if (frames < 0) {
+ return 0;
+ }
+
+ if ((int)frames > (int)buffer_frames)
+ frames = buffer_frames;
+
+ return snd_pcm_frames_to_bytes(handle, frames);
+}
+
+qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
+{
+ // Write out some audio data
+ if ( !handle )
+ return 0;
+#ifdef DEBUG_AUDIO
+ qDebug()<<"frames to write out = "<<
+ snd_pcm_bytes_to_frames( handle, (int)len )<<" ("<<len<<") bytes";
+#endif
+ int frames, err;
+ int space = bytesFree();
+ if(len < space) {
+ // Just write it
+ frames = snd_pcm_bytes_to_frames( handle, (int)len );
+ err = snd_pcm_writei( handle, data, frames );
+ } else {
+ // Only write space worth
+ frames = snd_pcm_bytes_to_frames( handle, (int)space );
+ err = snd_pcm_writei( handle, data, frames );
+ }
+ if(err > 0) {
+ totalTimeValue += err;
+ resuming = false;
+ errorState = QAudio::NoError;
+ if (deviceState != QAudio::ActiveState) {
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ return snd_pcm_frames_to_bytes( handle, err );
+ } else
+ err = xrun_recovery(err);
+
+ if(err < 0) {
+ close();
+ errorState = QAudio::FatalError;
+ emit errorChanged(errorState);
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ }
+ return 0;
+}
+
+int QAudioOutputPrivate::periodSize() const
+{
+ return period_size;
+}
+
+void QAudioOutputPrivate::setBufferSize(int value)
+{
+ if(deviceState == QAudio::StoppedState)
+ buffer_size = value;
+}
+
+int QAudioOutputPrivate::bufferSize() const
+{
+ return buffer_size;
+}
+
+void QAudioOutputPrivate::setNotifyInterval(int ms)
+{
+ intervalTime = qMax(0, ms);
+}
+
+int QAudioOutputPrivate::notifyInterval() const
+{
+ return intervalTime;
+}
+
+qint64 QAudioOutputPrivate::processedUSecs() const
+{
+ return qint64(1000000) * totalTimeValue / settings.frequency();
+}
+
+void QAudioOutputPrivate::resume()
+{
+ if(deviceState == QAudio::SuspendedState) {
+ int err = 0;
+
+ if(handle) {
+ err = snd_pcm_prepare( handle );
+ if(err < 0)
+ xrun_recovery(err);
+
+ err = snd_pcm_start(handle);
+ if(err < 0)
+ xrun_recovery(err);
+
+ bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames);
+ }
+ resuming = true;
+
+ deviceState = QAudio::ActiveState;
+
+ errorState = QAudio::NoError;
+ timer->start(period_time/1000);
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioOutputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (deviceState == QAudio::StoppedState)
+ settings = fmt;
+}
+
+QAudioFormat QAudioOutputPrivate::format() const
+{
+ return settings;
+}
+
+void QAudioOutputPrivate::suspend()
+{
+ if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState || resuming) {
+ timer->stop();
+ deviceState = QAudio::SuspendedState;
+ errorState = QAudio::NoError;
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioOutputPrivate::userFeed()
+{
+ if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
+ return;
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() OUT";
+#endif
+ if(deviceState == QAudio::IdleState)
+ bytesAvailable = bytesFree();
+
+ deviceReady();
+}
+
+void QAudioOutputPrivate::feedback()
+{
+ updateAvailable();
+}
+
+
+void QAudioOutputPrivate::updateAvailable()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :updateAvailable()";
+#endif
+ bytesAvailable = bytesFree();
+}
+
+bool QAudioOutputPrivate::deviceReady()
+{
+ if(pullMode) {
+ int l = 0;
+ int chunks = bytesAvailable/period_size;
+ if(chunks==0) {
+ bytesAvailable = bytesFree();
+ return false;
+ }
+#ifdef DEBUG_AUDIO
+ qDebug()<<"deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
+ qDebug()<<"deviceReady() no. of chunks that can fit ="<<chunks<<", chunks in bytes ="<<period_size*chunks;
+#endif
+ int input = period_frames*chunks;
+ if(input > (int)buffer_frames)
+ input = buffer_frames;
+ l = audioSource->read(audioBuffer,snd_pcm_frames_to_bytes(handle, input));
+ if(l > 0) {
+ // Got some data to output
+ if(deviceState != QAudio::ActiveState)
+ return true;
+ qint64 bytesWritten = write(audioBuffer,l);
+ if (bytesWritten != l)
+ audioSource->seek(audioSource->pos()-(l-bytesWritten));
+ bytesAvailable = bytesFree();
+
+ } else if(l == 0) {
+ // Did not get any data to output
+ bytesAvailable = bytesFree();
+ if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
+ // Underrun
+ if (deviceState != QAudio::IdleState) {
+ errorState = QAudio::UnderrunError;
+ emit errorChanged(errorState);
+ deviceState = QAudio::IdleState;
+ emit stateChanged(deviceState);
+ }
+ }
+
+ } else if(l < 0) {
+ close();
+ deviceState = QAudio::StoppedState;
+ errorState = QAudio::IOError;
+ emit errorChanged(errorState);
+ emit stateChanged(deviceState);
+ }
+ } else {
+ bytesAvailable = bytesFree();
+ if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
+ // Underrun
+ if (deviceState != QAudio::IdleState) {
+ errorState = QAudio::UnderrunError;
+ emit errorChanged(errorState);
+ deviceState = QAudio::IdleState;
+ emit stateChanged(deviceState);
+ }
+ }
+ }
+
+ if(deviceState != QAudio::ActiveState)
+ return true;
+
+ if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+ emit notify();
+ elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
+ timeStamp.restart();
+ }
+ return true;
+}
+
+qint64 QAudioOutputPrivate::elapsedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+
+ return clockStamp.elapsed()*1000;
+}
+
+void QAudioOutputPrivate::reset()
+{
+ if(handle)
+ snd_pcm_reset(handle);
+
+ stop();
+}
+
+OutputPrivate::OutputPrivate(QAudioOutputPrivate* audio)
+{
+ audioDevice = qobject_cast<QAudioOutputPrivate*>(audio);
+}
+
+OutputPrivate::~OutputPrivate() {}
+
+qint64 OutputPrivate::readData( char* data, qint64 len)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(len)
+
+ return 0;
+}
+
+qint64 OutputPrivate::writeData(const char* data, qint64 len)
+{
+ int retry = 0;
+ qint64 written = 0;
+ if((audioDevice->deviceState == QAudio::ActiveState)
+ ||(audioDevice->deviceState == QAudio::IdleState)) {
+ while(written < len) {
+ int chunk = audioDevice->write(data+written,(len-written));
+ if(chunk <= 0)
+ retry++;
+ written+=chunk;
+ if(retry > 10)
+ return written;
+ }
+ }
+ return written;
+
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qaudiooutput_alsa_p.cpp"
diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.h b/src/multimedia/audio/qaudiooutput_alsa_p.h
new file mode 100644
index 000000000..f914ded2c
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_alsa_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOOUTPUTALSA_H
+#define QAUDIOOUTPUTALSA_H
+
+#include <alsa/asoundlib.h>
+
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdatetime.h>
+
+#include "qaudio.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class OutputPrivate;
+
+class QAudioOutputPrivate : public QAbstractAudioOutput
+{
+ friend class OutputPrivate;
+ Q_OBJECT
+public:
+ QAudioOutputPrivate(const QByteArray &device);
+ ~QAudioOutputPrivate();
+
+ qint64 write( const char *data, qint64 len );
+
+ void start(QIODevice* device);
+ QIODevice* start();
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+ int bytesFree() const;
+ int periodSize() const;
+ void setBufferSize(int value);
+ int bufferSize() const;
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+ QAudio::Error error() const;
+ QAudio::State state() const;
+ void setFormat(const QAudioFormat& fmt);
+ QAudioFormat format() const;
+
+ QIODevice* audioSource;
+ QAudioFormat settings;
+ QAudio::Error errorState;
+ QAudio::State deviceState;
+
+private slots:
+ void userFeed();
+ void feedback();
+ void updateAvailable();
+ bool deviceReady();
+
+signals:
+ void processMore();
+
+private:
+ bool opened;
+ bool pullMode;
+ bool resuming;
+ int buffer_size;
+ int period_size;
+ int intervalTime;
+ qint64 totalTimeValue;
+ unsigned int buffer_time;
+ unsigned int period_time;
+ snd_pcm_uframes_t buffer_frames;
+ snd_pcm_uframes_t period_frames;
+ static void async_callback(snd_async_handler_t *ahandler);
+ int xrun_recovery(int err);
+
+ int setFormat();
+ bool open();
+ void close();
+
+ QTimer* timer;
+ QByteArray m_device;
+ int bytesAvailable;
+ QTime timeStamp;
+ QTime clockStamp;
+ qint64 elapsedTimeOffset;
+ char* audioBuffer;
+ snd_pcm_t* handle;
+ snd_async_handler_t* ahandler;
+ snd_pcm_access_t access;
+ snd_pcm_format_t pcmformat;
+ snd_timestamp_t* timestamp;
+ snd_pcm_hw_params_t *hwparams;
+};
+
+class OutputPrivate : public QIODevice
+{
+ friend class QAudioOutputPrivate;
+ Q_OBJECT
+public:
+ OutputPrivate(QAudioOutputPrivate* audio);
+ ~OutputPrivate();
+
+ qint64 readData( char* data, qint64 len);
+ qint64 writeData(const char* data, qint64 len);
+
+private:
+ QAudioOutputPrivate *audioDevice;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp
new file mode 100644
index 000000000..5e0c1cb07
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp
@@ -0,0 +1,734 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+#include <QtCore/qendian.h>
+#include <QtCore/qbuffer.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+
+#include <qaudiooutput.h>
+
+#include "qaudio_mac_p.h"
+#include "qaudiooutput_mac_p.h"
+#include "qaudiodeviceinfo_mac_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+
+namespace QtMultimediaInternal
+{
+
+static const int default_buffer_size = 8 * 1024;
+
+
+class QAudioOutputBuffer : public QObject
+{
+ Q_OBJECT
+
+public:
+ QAudioOutputBuffer(int bufferSize, int maxPeriodSize, QAudioFormat const& audioFormat):
+ m_deviceError(false),
+ m_maxPeriodSize(maxPeriodSize),
+ m_device(0)
+ {
+ m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
+ m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channels();
+ m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.frequency();
+
+ m_fillTimer = new QTimer(this);
+ connect(m_fillTimer, SIGNAL(timeout()), SLOT(fillBuffer()));
+ }
+
+ ~QAudioOutputBuffer()
+ {
+ delete m_buffer;
+ }
+
+ qint64 readFrames(char* data, qint64 maxFrames)
+ {
+ bool wecan = true;
+ qint64 framesRead = 0;
+
+ while (wecan && framesRead < maxFrames) {
+ QAudioRingBuffer::Region region = m_buffer->acquireReadRegion((maxFrames - framesRead) * m_bytesPerFrame);
+
+ if (region.second > 0) {
+ // Ensure that we only read whole frames.
+ region.second -= region.second % m_bytesPerFrame;
+
+ if (region.second > 0) {
+ memcpy(data + (framesRead * m_bytesPerFrame), region.first, region.second);
+ framesRead += region.second / m_bytesPerFrame;
+ } else
+ wecan = false; // If there is only a partial frame left we should exit.
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseReadRegion(region);
+ }
+
+ if (framesRead == 0 && m_deviceError)
+ framesRead = -1;
+
+ return framesRead;
+ }
+
+ qint64 writeBytes(const char* data, qint64 maxSize)
+ {
+ bool wecan = true;
+ qint64 bytesWritten = 0;
+
+ maxSize -= maxSize % m_bytesPerFrame;
+ while (wecan && bytesWritten < maxSize) {
+ QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(maxSize - bytesWritten);
+
+ if (region.second > 0) {
+ memcpy(region.first, data + bytesWritten, region.second);
+ bytesWritten += region.second;
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseWriteRegion(region);
+ }
+
+ if (bytesWritten > 0)
+ emit readyRead();
+
+ return bytesWritten;
+ }
+
+ int available() const
+ {
+ return m_buffer->free();
+ }
+
+ void reset()
+ {
+ m_buffer->reset();
+ m_device = 0;
+ m_deviceError = false;
+ }
+
+ void setPrefetchDevice(QIODevice* device)
+ {
+ if (m_device != device) {
+ m_device = device;
+ if (m_device != 0)
+ fillBuffer();
+ }
+ }
+
+ void startFillTimer()
+ {
+ if (m_device != 0)
+ m_fillTimer->start(m_buffer->size() / 2 / m_maxPeriodSize * m_periodTime);
+ }
+
+ void stopFillTimer()
+ {
+ m_fillTimer->stop();
+ }
+
+signals:
+ void readyRead();
+
+private slots:
+ void fillBuffer()
+ {
+ const int free = m_buffer->free();
+ const int writeSize = free - (free % m_maxPeriodSize);
+
+ if (writeSize > 0) {
+ bool wecan = true;
+ int filled = 0;
+
+ while (!m_deviceError && wecan && filled < writeSize) {
+ QAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(writeSize - filled);
+
+ if (region.second > 0) {
+ region.second = m_device->read(region.first, region.second);
+ if (region.second > 0)
+ filled += region.second;
+ else if (region.second == 0)
+ wecan = false;
+ else if (region.second < 0) {
+ m_fillTimer->stop();
+ region.second = 0;
+ m_deviceError = true;
+ }
+ }
+ else
+ wecan = false;
+
+ m_buffer->releaseWriteRegion(region);
+ }
+
+ if (filled > 0)
+ emit readyRead();
+ }
+ }
+
+private:
+ bool m_deviceError;
+ int m_maxPeriodSize;
+ int m_bytesPerFrame;
+ int m_periodTime;
+ QIODevice* m_device;
+ QTimer* m_fillTimer;
+ QAudioRingBuffer* m_buffer;
+};
+
+
+}
+
+class MacOutputDevice : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ MacOutputDevice(QtMultimediaInternal::QAudioOutputBuffer* audioBuffer, QObject* parent):
+ QIODevice(parent),
+ m_audioBuffer(audioBuffer)
+ {
+ open(QIODevice::WriteOnly | QIODevice::Unbuffered);
+ }
+
+ qint64 readData(char* data, qint64 len)
+ {
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return 0;
+ }
+
+ qint64 writeData(const char* data, qint64 len)
+ {
+ return m_audioBuffer->writeBytes(data, len);
+ }
+
+ bool isSequential() const
+ {
+ return true;
+ }
+
+private:
+ QtMultimediaInternal::QAudioOutputBuffer* m_audioBuffer;
+};
+
+
+QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device)
+{
+ QDataStream ds(device);
+ quint32 did, mode;
+
+ ds >> did >> mode;
+
+ if (QAudio::Mode(mode) == QAudio::AudioInput)
+ errorCode = QAudio::OpenError;
+ else {
+ audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioOutput);
+ isOpen = false;
+ audioDeviceId = AudioDeviceID(did);
+ audioUnit = 0;
+ audioIO = 0;
+ startTime = 0;
+ totalFrames = 0;
+ audioBuffer = 0;
+ internalBufferSize = QtMultimediaInternal::default_buffer_size;
+ clockFrequency = AudioGetHostClockFrequency() / 1000;
+ errorCode = QAudio::NoError;
+ stateCode = QAudio::StoppedState;
+ audioThreadState = Stopped;
+
+ intervalTimer = new QTimer(this);
+ intervalTimer->setInterval(1000);
+ connect(intervalTimer, SIGNAL(timeout()), SIGNAL(notify()));
+ }
+}
+
+QAudioOutputPrivate::~QAudioOutputPrivate()
+{
+ delete audioDeviceInfo;
+ close();
+}
+
+bool QAudioOutputPrivate::open()
+{
+ if (errorCode != QAudio::NoError)
+ return false;
+
+ if (isOpen)
+ return true;
+
+ ComponentDescription cd;
+ cd.componentType = kAudioUnitType_Output;
+ cd.componentSubType = kAudioUnitSubType_HALOutput;
+ cd.componentManufacturer = kAudioUnitManufacturer_Apple;
+ cd.componentFlags = 0;
+ cd.componentFlagsMask = 0;
+
+ // Open
+ Component cp = FindNextComponent(NULL, &cd);
+ if (cp == 0) {
+ qWarning() << "QAudioOutput: Failed to find HAL Output component";
+ return false;
+ }
+
+ if (OpenAComponent(cp, &audioUnit) != noErr) {
+ qWarning() << "QAudioOutput: Unable to Open Output Component";
+ return false;
+ }
+
+ // register callback
+ AURenderCallbackStruct cb;
+ cb.inputProc = renderCallback;
+ cb.inputProcRefCon = this;
+
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Global,
+ 0,
+ &cb,
+ sizeof(cb)) != noErr) {
+ qWarning() << "QAudioOutput: Failed to set AudioUnit callback";
+ return false;
+ }
+
+ // Set Audio Device
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioOutputUnitProperty_CurrentDevice,
+ kAudioUnitScope_Global,
+ 0,
+ &audioDeviceId,
+ sizeof(audioDeviceId)) != noErr) {
+ qWarning() << "QAudioOutput: Unable to use configured device";
+ return false;
+ }
+
+ // Set stream format
+ streamFormat = toAudioStreamBasicDescription(audioFormat);
+
+ UInt32 size = sizeof(streamFormat);
+ if (AudioUnitSetProperty(audioUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input,
+ 0,
+ &streamFormat,
+ sizeof(streamFormat)) != noErr) {
+ qWarning() << "QAudioOutput: Unable to Set Stream information";
+ return false;
+ }
+
+ // Allocate buffer
+ UInt32 numberOfFrames = 0;
+ size = sizeof(UInt32);
+ if (AudioUnitGetProperty(audioUnit,
+ kAudioDevicePropertyBufferFrameSize,
+ kAudioUnitScope_Global,
+ 0,
+ &numberOfFrames,
+ &size) != noErr) {
+ qWarning() << "QAudioInput: Failed to get audio period size";
+ return false;
+ }
+
+ periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame;
+ if (internalBufferSize < periodSizeBytes * 2)
+ internalBufferSize = periodSizeBytes * 2;
+ else
+ internalBufferSize -= internalBufferSize % streamFormat.mBytesPerFrame;
+
+ audioBuffer = new QtMultimediaInternal::QAudioOutputBuffer(internalBufferSize, periodSizeBytes, audioFormat);
+ connect(audioBuffer, SIGNAL(readyRead()), SLOT(inputReady())); // Pull
+
+ audioIO = new MacOutputDevice(audioBuffer, this);
+
+ // Init
+ if (AudioUnitInitialize(audioUnit)) {
+ qWarning() << "QAudioOutput: Failed to initialize AudioUnit";
+ return false;
+ }
+
+ isOpen = true;
+
+ return true;
+}
+
+void QAudioOutputPrivate::close()
+{
+ if (audioUnit != 0) {
+ AudioOutputUnitStop(audioUnit);
+ AudioUnitUninitialize(audioUnit);
+ CloseComponent(audioUnit);
+ }
+
+ delete audioBuffer;
+}
+
+QAudioFormat QAudioOutputPrivate::format() const
+{
+ return audioFormat;
+}
+
+void QAudioOutputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (stateCode == QAudio::StoppedState)
+ audioFormat = fmt;
+}
+
+void QAudioOutputPrivate::start(QIODevice* device)
+{
+ QIODevice* op = device;
+
+ if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::OpenError;
+ }
+
+ reset();
+ audioBuffer->reset();
+ audioBuffer->setPrefetchDevice(op);
+
+ if (op == 0) {
+ op = audioIO;
+ stateCode = QAudio::IdleState;
+ }
+ else
+ stateCode = QAudio::ActiveState;
+
+ // Start
+ errorCode = QAudio::NoError;
+ totalFrames = 0;
+ startTime = AudioGetCurrentHostTime();
+
+ if (stateCode == QAudio::ActiveState)
+ audioThreadStart();
+
+ emit stateChanged(stateCode);
+}
+
+QIODevice* QAudioOutputPrivate::start()
+{
+ if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) {
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::OpenError;
+ return audioIO;
+ }
+
+ reset();
+ audioBuffer->reset();
+ audioBuffer->setPrefetchDevice(0);
+
+ stateCode = QAudio::IdleState;
+
+ // Start
+ errorCode = QAudio::NoError;
+ totalFrames = 0;
+ startTime = AudioGetCurrentHostTime();
+
+ emit stateChanged(stateCode);
+
+ return audioIO;
+}
+
+void QAudioOutputPrivate::stop()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode != QAudio::StoppedState) {
+ audioThreadDrain();
+
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::NoError;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioOutputPrivate::reset()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode != QAudio::StoppedState) {
+ audioThreadStop();
+
+ stateCode = QAudio::StoppedState;
+ errorCode = QAudio::NoError;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioOutputPrivate::suspend()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState || stateCode == QAudio::IdleState) {
+ audioThreadStop();
+
+ stateCode = QAudio::SuspendedState;
+ errorCode = QAudio::NoError;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+void QAudioOutputPrivate::resume()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::SuspendedState) {
+ audioThreadStart();
+
+ stateCode = QAudio::ActiveState;
+ errorCode = QAudio::NoError;
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+int QAudioOutputPrivate::bytesFree() const
+{
+ return audioBuffer->available();
+}
+
+int QAudioOutputPrivate::periodSize() const
+{
+ return periodSizeBytes;
+}
+
+void QAudioOutputPrivate::setBufferSize(int bs)
+{
+ if (stateCode == QAudio::StoppedState)
+ internalBufferSize = bs;
+}
+
+int QAudioOutputPrivate::bufferSize() const
+{
+ return internalBufferSize;
+}
+
+void QAudioOutputPrivate::setNotifyInterval(int milliSeconds)
+{
+ if (intervalTimer->interval() == milliSeconds)
+ return;
+
+ if (milliSeconds <= 0)
+ milliSeconds = 0;
+
+ intervalTimer->setInterval(milliSeconds);
+}
+
+int QAudioOutputPrivate::notifyInterval() const
+{
+ return intervalTimer->interval();
+}
+
+qint64 QAudioOutputPrivate::processedUSecs() const
+{
+ return totalFrames * 1000000 / audioFormat.frequency();
+}
+
+qint64 QAudioOutputPrivate::elapsedUSecs() const
+{
+ if (stateCode == QAudio::StoppedState)
+ return 0;
+
+ return (AudioGetCurrentHostTime() - startTime) / (clockFrequency / 1000);
+}
+
+QAudio::Error QAudioOutputPrivate::error() const
+{
+ return errorCode;
+}
+
+QAudio::State QAudioOutputPrivate::state() const
+{
+ return stateCode;
+}
+
+void QAudioOutputPrivate::audioThreadStart()
+{
+ startTimers();
+ audioThreadState = Running;
+ AudioOutputUnitStart(audioUnit);
+}
+
+void QAudioOutputPrivate::audioThreadStop()
+{
+ stopTimers();
+ if (audioThreadState.testAndSetAcquire(Running, Stopped))
+ threadFinished.wait(&mutex);
+}
+
+void QAudioOutputPrivate::audioThreadDrain()
+{
+ stopTimers();
+ if (audioThreadState.testAndSetAcquire(Running, Draining))
+ threadFinished.wait(&mutex);
+}
+
+void QAudioOutputPrivate::audioDeviceStop()
+{
+ AudioOutputUnitStop(audioUnit);
+ audioThreadState = Stopped;
+ threadFinished.wakeOne();
+}
+
+void QAudioOutputPrivate::audioDeviceIdle()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState) {
+ audioDeviceStop();
+
+ errorCode = QAudio::UnderrunError;
+ stateCode = QAudio::IdleState;
+ QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
+ }
+}
+
+void QAudioOutputPrivate::audioDeviceError()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::ActiveState) {
+ audioDeviceStop();
+
+ errorCode = QAudio::IOError;
+ stateCode = QAudio::StoppedState;
+ QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
+ }
+}
+
+void QAudioOutputPrivate::startTimers()
+{
+ audioBuffer->startFillTimer();
+ if (intervalTimer->interval() > 0)
+ intervalTimer->start();
+}
+
+void QAudioOutputPrivate::stopTimers()
+{
+ audioBuffer->stopFillTimer();
+ intervalTimer->stop();
+}
+
+
+void QAudioOutputPrivate::deviceStopped()
+{
+ intervalTimer->stop();
+ emit stateChanged(stateCode);
+}
+
+void QAudioOutputPrivate::inputReady()
+{
+ QMutexLocker lock(&mutex);
+ if (stateCode == QAudio::IdleState) {
+ audioThreadStart();
+
+ stateCode = QAudio::ActiveState;
+ errorCode = QAudio::NoError;
+
+ QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, stateCode));
+ }
+}
+
+
+OSStatus QAudioOutputPrivate::renderCallback(void* inRefCon,
+ AudioUnitRenderActionFlags* ioActionFlags,
+ const AudioTimeStamp* inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData)
+{
+ Q_UNUSED(ioActionFlags)
+ Q_UNUSED(inTimeStamp)
+ Q_UNUSED(inBusNumber)
+ Q_UNUSED(inNumberFrames)
+
+ QAudioOutputPrivate* d = static_cast<QAudioOutputPrivate*>(inRefCon);
+
+ const int threadState = d->audioThreadState.fetchAndAddAcquire(0);
+ if (threadState == Stopped) {
+ ioData->mBuffers[0].mDataByteSize = 0;
+ d->audioDeviceStop();
+ }
+ else {
+ const UInt32 bytesPerFrame = d->streamFormat.mBytesPerFrame;
+ qint64 framesRead;
+
+ framesRead = d->audioBuffer->readFrames((char*)ioData->mBuffers[0].mData,
+ ioData->mBuffers[0].mDataByteSize / bytesPerFrame);
+
+ if (framesRead > 0) {
+ ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
+ d->totalFrames += framesRead;
+ }
+ else {
+ ioData->mBuffers[0].mDataByteSize = 0;
+ if (framesRead == 0) {
+ if (threadState == Draining)
+ d->audioDeviceStop();
+ else
+ d->audioDeviceIdle();
+ }
+ else
+ d->audioDeviceError();
+ }
+ }
+
+ return noErr;
+}
+
+
+QT_END_NAMESPACE
+
+#include "qaudiooutput_mac_p.moc"
diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h
new file mode 100644
index 000000000..ded618cbb
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_mac_p.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOOUTPUT_MAC_P_H
+#define QAUDIOOUTPUT_MAC_P_H
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qatomic.h>
+
+#include <qaudio.h>
+#include <qaudioformat.h>
+#include <qaudiosystem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QIODevice;
+class QAbstractAudioDeviceInfo;
+
+namespace QtMultimediaInternal
+{
+class QAudioOutputBuffer;
+}
+
+class QAudioOutputPrivate : public QAbstractAudioOutput
+{
+ Q_OBJECT
+
+public:
+ bool isOpen;
+ int internalBufferSize;
+ int periodSizeBytes;
+ qint64 totalFrames;
+ QAudioFormat audioFormat;
+ QIODevice* audioIO;
+ AudioDeviceID audioDeviceId;
+ AudioUnit audioUnit;
+ Float64 clockFrequency;
+ UInt64 startTime;
+ AudioStreamBasicDescription deviceFormat;
+ AudioStreamBasicDescription streamFormat;
+ QtMultimediaInternal::QAudioOutputBuffer* audioBuffer;
+ QAtomicInt audioThreadState;
+ QWaitCondition threadFinished;
+ QMutex mutex;
+ QTimer* intervalTimer;
+ QAbstractAudioDeviceInfo *audioDeviceInfo;
+
+ QAudio::Error errorCode;
+ QAudio::State stateCode;
+
+ QAudioOutputPrivate(const QByteArray& device);
+ ~QAudioOutputPrivate();
+
+ bool open();
+ void close();
+
+ QAudioFormat format() const;
+ void setFormat(const QAudioFormat& fmt);
+
+ QIODevice* start();
+ void start(QIODevice* device);
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+
+ int bytesFree() const;
+ int periodSize() const;
+
+ void setBufferSize(int value);
+ int bufferSize() const;
+
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+ void audioThreadStart();
+ void audioThreadStop();
+ void audioThreadDrain();
+
+ void audioDeviceStop();
+ void audioDeviceIdle();
+ void audioDeviceError();
+
+ void startTimers();
+ void stopTimers();
+
+private slots:
+ void deviceStopped();
+ void inputReady();
+
+private:
+ enum { Running, Draining, Stopped };
+
+ static OSStatus renderCallback(void* inRefCon,
+ AudioUnitRenderActionFlags* ioActionFlags,
+ const AudioTimeStamp* inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp
new file mode 100644
index 000000000..d5b31a30f
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp
@@ -0,0 +1,715 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include "qaudiooutput_win32_p.h"
+
+#ifndef SPEAKER_FRONT_LEFT
+ #define SPEAKER_FRONT_LEFT 0x00000001
+ #define SPEAKER_FRONT_RIGHT 0x00000002
+ #define SPEAKER_FRONT_CENTER 0x00000004
+ #define SPEAKER_LOW_FREQUENCY 0x00000008
+ #define SPEAKER_BACK_LEFT 0x00000010
+ #define SPEAKER_BACK_RIGHT 0x00000020
+ #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
+ #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
+ #define SPEAKER_BACK_CENTER 0x00000100
+ #define SPEAKER_SIDE_LEFT 0x00000200
+ #define SPEAKER_SIDE_RIGHT 0x00000400
+ #define SPEAKER_TOP_CENTER 0x00000800
+ #define SPEAKER_TOP_FRONT_LEFT 0x00001000
+ #define SPEAKER_TOP_FRONT_CENTER 0x00002000
+ #define SPEAKER_TOP_FRONT_RIGHT 0x00004000
+ #define SPEAKER_TOP_BACK_LEFT 0x00008000
+ #define SPEAKER_TOP_BACK_CENTER 0x00010000
+ #define SPEAKER_TOP_BACK_RIGHT 0x00020000
+ #define SPEAKER_RESERVED 0x7FFC0000
+ #define SPEAKER_ALL 0x80000000
+#endif
+
+#ifndef _WAVEFORMATEXTENSIBLE_
+
+ #define _WAVEFORMATEXTENSIBLE_
+ typedef struct
+ {
+ WAVEFORMATEX Format; // Base WAVEFORMATEX data
+ union
+ {
+ WORD wValidBitsPerSample; // Valid bits in each sample container
+ WORD wSamplesPerBlock; // Samples per block of audio data; valid
+ // if wBitsPerSample=0 (but rarely used).
+ WORD wReserved; // Zero if neither case above applies.
+ } Samples;
+ DWORD dwChannelMask; // Positions of the audio channels
+ GUID SubFormat; // Format identifier GUID
+ } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
+ typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
+
+#endif
+
+#if !defined(WAVE_FORMAT_EXTENSIBLE)
+#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
+#endif
+
+//#define DEBUG_AUDIO 1
+
+QT_BEGIN_NAMESPACE
+
+QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray &device)
+{
+ bytesAvailable = 0;
+ buffer_size = 0;
+ period_size = 0;
+ m_device = device;
+ totalTimeValue = 0;
+ intervalTime = 1000;
+ audioBuffer = 0;
+ errorState = QAudio::NoError;
+ deviceState = QAudio::StoppedState;
+ audioSource = 0;
+ pullMode = true;
+ finished = false;
+}
+
+QAudioOutputPrivate::~QAudioOutputPrivate()
+{
+ mutex.lock();
+ finished = true;
+ mutex.unlock();
+
+ close();
+}
+
+void CALLBACK QAudioOutputPrivate::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg,
+ DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
+{
+ Q_UNUSED(dwParam1)
+ Q_UNUSED(dwParam2)
+ Q_UNUSED(hWaveOut)
+
+ QAudioOutputPrivate* qAudio;
+ qAudio = (QAudioOutputPrivate*)(dwInstance);
+ if(!qAudio)
+ return;
+
+ QMutexLocker(&qAudio->mutex);
+
+ switch(uMsg) {
+ case WOM_OPEN:
+ qAudio->feedback();
+ break;
+ case WOM_CLOSE:
+ return;
+ case WOM_DONE:
+ if(qAudio->finished || qAudio->buffer_size == 0 || qAudio->period_size == 0) {
+ return;
+ }
+ qAudio->waveFreeBlockCount++;
+ if(qAudio->waveFreeBlockCount >= qAudio->buffer_size/qAudio->period_size)
+ qAudio->waveFreeBlockCount = qAudio->buffer_size/qAudio->period_size;
+ qAudio->feedback();
+ break;
+ default:
+ return;
+ }
+}
+
+WAVEHDR* QAudioOutputPrivate::allocateBlocks(int size, int count)
+{
+ int i;
+ unsigned char* buffer;
+ WAVEHDR* blocks;
+ DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count;
+
+ if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ totalBufferSize)) == 0) {
+ qWarning("QAudioOutput: Memory allocation error");
+ return 0;
+ }
+ blocks = (WAVEHDR*)buffer;
+ buffer += sizeof(WAVEHDR)*count;
+ for(i = 0; i < count; i++) {
+ blocks[i].dwBufferLength = size;
+ blocks[i].lpData = (LPSTR)buffer;
+ buffer += size;
+ }
+ return blocks;
+}
+
+void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray)
+{
+ WAVEHDR* blocks = blockArray;
+
+ int count = buffer_size/period_size;
+
+ for(int i = 0; i < count; i++) {
+ waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR));
+ blocks++;
+ }
+ HeapFree(GetProcessHeap(), 0, blockArray);
+}
+
+QAudioFormat QAudioOutputPrivate::format() const
+{
+ return settings;
+}
+
+void QAudioOutputPrivate::setFormat(const QAudioFormat& fmt)
+{
+ if (deviceState == QAudio::StoppedState)
+ settings = fmt;
+}
+
+void QAudioOutputPrivate::start(QIODevice* device)
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = true;
+ audioSource = device;
+
+ deviceState = QAudio::ActiveState;
+
+ if(!open())
+ return;
+
+ emit stateChanged(deviceState);
+}
+
+QIODevice* QAudioOutputPrivate::start()
+{
+ if(deviceState != QAudio::StoppedState)
+ close();
+
+ if(!pullMode && audioSource)
+ delete audioSource;
+
+ pullMode = false;
+ audioSource = new OutputPrivate(this);
+ audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
+
+ deviceState = QAudio::IdleState;
+
+ if(!open())
+ return 0;
+
+ emit stateChanged(deviceState);
+
+ return audioSource;
+}
+
+void QAudioOutputPrivate::stop()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+ close();
+ if(!pullMode && audioSource) {
+ delete audioSource;
+ audioSource = 0;
+ }
+ emit stateChanged(deviceState);
+}
+
+bool QAudioOutputPrivate::open()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
+#endif
+
+ period_size = 0;
+
+ if (!settings.isValid()) {
+ qWarning("QAudioOutput: open error, invalid format.");
+ } else if (settings.channelCount() <= 0) {
+ qWarning("QAudioOutput: open error, invalid number of channels (%d).",
+ settings.channelCount());
+ } else if (settings.sampleSize() <= 0) {
+ qWarning("QAudioOutput: open error, invalid sample size (%d).",
+ settings.sampleSize());
+ } else if (settings.frequency() < 8000 || settings.frequency() > 96000) {
+ qWarning("QAudioOutput: open error, frequency out of range (%d).", settings.frequency());
+ } else if (buffer_size == 0) {
+ // Default buffer size, 200ms, default period size is 40ms
+ buffer_size
+ = (settings.frequency()
+ * settings.channelCount()
+ * settings.sampleSize()
+ + 39) / 40;
+ period_size = buffer_size / 5;
+ } else {
+ period_size = buffer_size / 5;
+ }
+
+ if (period_size == 0) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return false;
+ }
+
+ waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
+
+ mutex.lock();
+ waveFreeBlockCount = buffer_size/period_size;
+ mutex.unlock();
+
+ waveCurrentBlock = 0;
+
+ if(audioBuffer == 0)
+ audioBuffer = new char[buffer_size];
+
+ timeStamp.restart();
+ elapsedTimeOffset = 0;
+
+ wfx.nSamplesPerSec = settings.frequency();
+ wfx.wBitsPerSample = settings.sampleSize();
+ wfx.nChannels = settings.channels();
+ wfx.cbSize = 0;
+
+ bool surround = false;
+
+ if (settings.channels() > 2)
+ surround = true;
+
+ wfx.wFormatTag = WAVE_FORMAT_PCM;
+ wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
+ wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
+
+ QDataStream ds(&m_device, QIODevice::ReadOnly);
+ quint32 deviceId;
+ ds >> deviceId;
+
+ if (!surround) {
+ if (waveOutOpen(&hWaveOut, UINT_PTR(deviceId), &wfx,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
+ } else {
+ WAVEFORMATEXTENSIBLE wfex;
+ wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ wfex.Format.nChannels = settings.channels();
+ wfex.Format.wBitsPerSample = settings.sampleSize();
+ wfex.Format.nSamplesPerSec = settings.frequency();
+ wfex.Format.nBlockAlign = wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
+ wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*wfex.Format.nBlockAlign;
+ wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
+ static const GUID _KSDATAFORMAT_SUBTYPE_PCM = {
+ 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+ wfex.SubFormat=_KSDATAFORMAT_SUBTYPE_PCM;
+ wfex.Format.cbSize=22;
+
+ wfex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ if (settings.channels() >= 4)
+ wfex.dwChannelMask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
+ if (settings.channels() >= 6)
+ wfex.dwChannelMask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY;
+ if (settings.channels() == 8)
+ wfex.dwChannelMask |= SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
+
+ if (waveOutOpen(&hWaveOut, UINT_PTR(deviceId), &wfex.Format,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
+ }
+
+ totalTimeValue = 0;
+ timeStampOpened.restart();
+ elapsedTimeOffset = 0;
+
+ errorState = QAudio::NoError;
+ if(pullMode) {
+ deviceState = QAudio::ActiveState;
+ QTimer::singleShot(10, this, SLOT(feedback()));
+ } else
+ deviceState = QAudio::IdleState;
+
+ return true;
+}
+
+void QAudioOutputPrivate::close()
+{
+ if(deviceState == QAudio::StoppedState)
+ return;
+
+ deviceState = QAudio::StoppedState;
+ errorState = QAudio::NoError;
+ int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
+ *settings.channels()*(settings.sampleSize()/8));
+ waveOutReset(hWaveOut);
+ Sleep(delay+10);
+
+ freeBlocks(waveBlocks);
+ waveOutClose(hWaveOut);
+ delete [] audioBuffer;
+ audioBuffer = 0;
+ buffer_size = 0;
+}
+
+int QAudioOutputPrivate::bytesFree() const
+{
+ int buf;
+ buf = waveFreeBlockCount*period_size;
+
+ return buf;
+}
+
+int QAudioOutputPrivate::periodSize() const
+{
+ return period_size;
+}
+
+void QAudioOutputPrivate::setBufferSize(int value)
+{
+ if(deviceState == QAudio::StoppedState)
+ buffer_size = value;
+}
+
+int QAudioOutputPrivate::bufferSize() const
+{
+ return buffer_size;
+}
+
+void QAudioOutputPrivate::setNotifyInterval(int ms)
+{
+ intervalTime = qMax(0, ms);
+}
+
+int QAudioOutputPrivate::notifyInterval() const
+{
+ return intervalTime;
+}
+
+qint64 QAudioOutputPrivate::processedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+ qint64 result = qint64(1000000) * totalTimeValue /
+ (settings.channels()*(settings.sampleSize()/8)) /
+ settings.frequency();
+
+ return result;
+}
+
+qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
+{
+ // Write out some audio data
+ if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+ return 0;
+
+ char* p = (char*)data;
+ int l = (int)len;
+
+ WAVEHDR* current;
+ int remain;
+ current = &waveBlocks[waveCurrentBlock];
+ while(l > 0) {
+ mutex.lock();
+ if(waveFreeBlockCount==0) {
+ mutex.unlock();
+ break;
+ }
+ mutex.unlock();
+
+ if(current->dwFlags & WHDR_PREPARED)
+ waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
+
+ if(l < period_size)
+ remain = l;
+ else
+ remain = period_size;
+ memcpy(current->lpData, p, remain);
+
+ l -= remain;
+ p += remain;
+ current->dwBufferLength = remain;
+ waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
+ waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
+
+ mutex.lock();
+ waveFreeBlockCount--;
+#ifdef DEBUG_AUDIO
+ qDebug("write out l=%d, waveFreeBlockCount=%d",
+ current->dwBufferLength,waveFreeBlockCount);
+#endif
+ mutex.unlock();
+
+ totalTimeValue += current->dwBufferLength;
+ waveCurrentBlock++;
+ waveCurrentBlock %= buffer_size/period_size;
+ current = &waveBlocks[waveCurrentBlock];
+ current->dwUser = 0;
+ errorState = QAudio::NoError;
+ if (deviceState != QAudio::ActiveState) {
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ }
+ return (len-l);
+}
+
+void QAudioOutputPrivate::resume()
+{
+ if(deviceState == QAudio::SuspendedState) {
+ deviceState = QAudio::ActiveState;
+ errorState = QAudio::NoError;
+ waveOutRestart(hWaveOut);
+ QTimer::singleShot(10, this, SLOT(feedback()));
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioOutputPrivate::suspend()
+{
+ if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState) {
+ int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
+ *settings.channels()*(settings.sampleSize()/8));
+ waveOutPause(hWaveOut);
+ Sleep(delay+10);
+ deviceState = QAudio::SuspendedState;
+ errorState = QAudio::NoError;
+ emit stateChanged(deviceState);
+ }
+}
+
+void QAudioOutputPrivate::feedback()
+{
+#ifdef DEBUG_AUDIO
+ QTime now(QTime::currentTime());
+ qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback()";
+#endif
+ bytesAvailable = bytesFree();
+
+ if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState)) {
+ if(bytesAvailable >= period_size)
+ QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection);
+ }
+}
+
+bool QAudioOutputPrivate::deviceReady()
+{
+ if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
+ return false;
+
+ if(pullMode) {
+ int chunks = bytesAvailable/period_size;
+#ifdef DEBUG_AUDIO
+ qDebug()<<"deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
+ qDebug()<<"deviceReady() no. of chunks that can fit ="<<chunks<<", chunks in bytes ="<<chunks*period_size;
+#endif
+ bool startup = false;
+ if(totalTimeValue == 0)
+ startup = true;
+
+ bool full=false;
+
+ mutex.lock();
+ if(waveFreeBlockCount==0) full = true;
+ mutex.unlock();
+
+ if (full){
+#ifdef DEBUG_AUDIO
+ qDebug() << "Skipping data as unable to write";
+#endif
+ if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime ) {
+ emit notify();
+ elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
+ timeStamp.restart();
+ }
+ return true;
+ }
+
+ if(startup)
+ waveOutPause(hWaveOut);
+ int input = period_size*chunks;
+ int l = audioSource->read(audioBuffer,input);
+ if(l > 0) {
+ int out= write(audioBuffer,l);
+ if(out > 0) {
+ if (deviceState != QAudio::ActiveState) {
+ deviceState = QAudio::ActiveState;
+ emit stateChanged(deviceState);
+ }
+ }
+ if ( out < l) {
+ // Didn't write all data
+ audioSource->seek(audioSource->pos()-(l-out));
+ }
+ if(startup)
+ waveOutRestart(hWaveOut);
+ } else if(l == 0) {
+ bytesAvailable = bytesFree();
+
+ int check = 0;
+
+ mutex.lock();
+ check = waveFreeBlockCount;
+ mutex.unlock();
+
+ if(check == buffer_size/period_size) {
+ if (deviceState != QAudio::IdleState) {
+ errorState = QAudio::UnderrunError;
+ deviceState = QAudio::IdleState;
+ emit stateChanged(deviceState);
+ }
+ }
+
+ } else if(l < 0) {
+ bytesAvailable = bytesFree();
+ if (errorState != QAudio::IOError)
+ errorState = QAudio::IOError;
+ }
+ } else {
+ int buffered;
+
+ mutex.lock();
+ buffered = waveFreeBlockCount;
+ mutex.unlock();
+
+ if (buffered >= buffer_size/period_size && deviceState == QAudio::ActiveState) {
+ if (deviceState != QAudio::IdleState) {
+ errorState = QAudio::UnderrunError;
+ deviceState = QAudio::IdleState;
+ emit stateChanged(deviceState);
+ }
+ }
+ }
+ if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
+ return true;
+
+ if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
+ emit notify();
+ elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
+ timeStamp.restart();
+ }
+
+ return true;
+}
+
+qint64 QAudioOutputPrivate::elapsedUSecs() const
+{
+ if (deviceState == QAudio::StoppedState)
+ return 0;
+
+ return timeStampOpened.elapsed()*1000;
+}
+
+QAudio::Error QAudioOutputPrivate::error() const
+{
+ return errorState;
+}
+
+QAudio::State QAudioOutputPrivate::state() const
+{
+ return deviceState;
+}
+
+void QAudioOutputPrivate::reset()
+{
+ close();
+}
+
+OutputPrivate::OutputPrivate(QAudioOutputPrivate* audio)
+{
+ audioDevice = qobject_cast<QAudioOutputPrivate*>(audio);
+}
+
+OutputPrivate::~OutputPrivate() {}
+
+qint64 OutputPrivate::readData( char* data, qint64 len)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(len)
+
+ return 0;
+}
+
+qint64 OutputPrivate::writeData(const char* data, qint64 len)
+{
+ int retry = 0;
+ qint64 written = 0;
+
+ if((audioDevice->deviceState == QAudio::ActiveState)
+ ||(audioDevice->deviceState == QAudio::IdleState)) {
+ qint64 l = len;
+ while(written < l) {
+ int chunk = audioDevice->write(data+written,(l-written));
+ if(chunk <= 0)
+ retry++;
+ else
+ written+=chunk;
+
+ if(retry > 10)
+ return written;
+ }
+ audioDevice->deviceState = QAudio::ActiveState;
+ }
+ return written;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qaudiooutput_win32_p.cpp"
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.h b/src/multimedia/audio/qaudiooutput_win32_p.h
new file mode 100644
index 000000000..aa86d4e9b
--- /dev/null
+++ b/src/multimedia/audio/qaudiooutput_win32_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QAUDIOOUTPUTWIN_H
+#define QAUDIOOUTPUTWIN_H
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qmutex.h>
+
+#include <qaudio.h>
+#include <qaudiodeviceinfo.h>
+#include <qaudiosystem.h>
+
+// For compat with 4.6
+#if !defined(QT_WIN_CALLBACK)
+# if defined(Q_CC_MINGW)
+# define QT_WIN_CALLBACK CALLBACK __attribute__ ((force_align_arg_pointer))
+# else
+# define QT_WIN_CALLBACK CALLBACK
+# endif
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioOutputPrivate : public QAbstractAudioOutput
+{
+ Q_OBJECT
+public:
+ QAudioOutputPrivate(const QByteArray &device);
+ ~QAudioOutputPrivate();
+
+ qint64 write( const char *data, qint64 len );
+
+ void setFormat(const QAudioFormat& fmt);
+ QAudioFormat format() const;
+ QIODevice* start();
+ void start(QIODevice* device);
+ void stop();
+ void reset();
+ void suspend();
+ void resume();
+ int bytesFree() const;
+ int periodSize() const;
+ void setBufferSize(int value);
+ int bufferSize() const;
+ void setNotifyInterval(int milliSeconds);
+ int notifyInterval() const;
+ qint64 processedUSecs() const;
+ qint64 elapsedUSecs() const;
+ QAudio::Error error() const;
+ QAudio::State state() const;
+
+ QIODevice* audioSource;
+ QAudioFormat settings;
+ QAudio::Error errorState;
+ QAudio::State deviceState;
+
+private slots:
+ void feedback();
+ bool deviceReady();
+
+private:
+ QByteArray m_device;
+ bool resuming;
+ int bytesAvailable;
+ QTime timeStamp;
+ qint64 elapsedTimeOffset;
+ QTime timeStampOpened;
+ qint32 buffer_size;
+ qint32 period_size;
+ qint64 totalTimeValue;
+ bool pullMode;
+ int intervalTime;
+ static void QT_WIN_CALLBACK waveOutProc( HWAVEOUT hWaveOut, UINT uMsg,
+ DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
+
+ QMutex mutex;
+
+ WAVEHDR* allocateBlocks(int size, int count);
+ void freeBlocks(WAVEHDR* blockArray);
+ bool open();
+ void close();
+
+ WAVEFORMATEX wfx;
+ HWAVEOUT hWaveOut;
+ MMRESULT result;
+ WAVEHDR header;
+ WAVEHDR* waveBlocks;
+ volatile bool finished;
+ volatile int waveFreeBlockCount;
+ int waveCurrentBlock;
+ char* audioBuffer;
+};
+
+class OutputPrivate : public QIODevice
+{
+ Q_OBJECT
+public:
+ OutputPrivate(QAudioOutputPrivate* audio);
+ ~OutputPrivate();
+
+ qint64 readData( char* data, qint64 len);
+ qint64 writeData(const char* data, qint64 len);
+
+private:
+ QAudioOutputPrivate *audioDevice;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/audio/qaudiopluginloader.cpp b/src/multimedia/audio/qaudiopluginloader.cpp
new file mode 100644
index 000000000..58006356a
--- /dev/null
+++ b/src/multimedia/audio/qaudiopluginloader.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudiosystemplugin.h"
+#include "qaudiopluginloader_p.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qpluginloader.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QAudioPluginLoader::QAudioPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
+ m_iid(iid)
+{
+ m_location = location + QLatin1Char('/');
+ load();
+}
+
+QAudioPluginLoader::~QAudioPluginLoader()
+{
+ for (int i = 0; i < m_plugins.count(); i++ ) {
+ delete m_plugins.at(i);
+ }
+}
+
+QStringList QAudioPluginLoader::pluginList() const
+{
+#if !defined QT_NO_DEBUG
+ const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
+#endif
+
+ QStringList paths = QCoreApplication::libraryPaths();
+#ifdef QTM_PLUGIN_PATH
+ paths << QLatin1String(QTM_PLUGIN_PATH);
+#endif
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qDebug() << "Plugin paths:" << paths;
+#endif
+
+ //temp variable to avoid multiple identic path
+ QSet<QString> processed;
+
+ /* Discover a bunch o plugins */
+ QStringList plugins;
+
+ /* Enumerate our plugin paths */
+ for (int i=0; i < paths.count(); i++) {
+ if (processed.contains(paths.at(i)))
+ continue;
+ processed.insert(paths.at(i));
+ QDir pluginsDir(paths.at(i)+m_location);
+ if (!pluginsDir.exists())
+ continue;
+
+ QStringList files = pluginsDir.entryList(QDir::Files);
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qDebug()<<"Looking for plugins in "<<pluginsDir.path()<<files;
+#endif
+ for (int j=0; j < files.count(); j++) {
+ const QString &file = files.at(j);
+ plugins << pluginsDir.absoluteFilePath(file);
+ }
+ }
+ return plugins;
+}
+
+QStringList QAudioPluginLoader::keys() const
+{
+ QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
+
+ QStringList list;
+ for (int i = 0; i < m_plugins.count(); i++) {
+ QAudioSystemPlugin* p = qobject_cast<QAudioSystemPlugin*>(m_plugins.at(i)->instance());
+ if (p) list << p->keys();
+ }
+
+ return list;
+}
+
+QObject* QAudioPluginLoader::instance(QString const &key)
+{
+ QMutexLocker locker(&m_mutex);
+
+ for (int i = 0; i < m_plugins.count(); i++) {
+ QAudioSystemPlugin* p = qobject_cast<QAudioSystemPlugin*>(m_plugins.at(i)->instance());
+ if (p && p->keys().contains(key))
+ return m_plugins.at(i)->instance();
+ }
+ return 0;
+}
+
+QList<QObject*> QAudioPluginLoader::instances(QString const &key)
+{
+ QMutexLocker locker(&m_mutex);
+
+ QList<QObject*> list;
+ for (int i = 0; i < m_plugins.count(); i++) {
+ QAudioSystemPlugin* p = qobject_cast<QAudioSystemPlugin*>(m_plugins.at(i)->instance());
+ if (p && p->keys().contains(key))
+ list << m_plugins.at(i)->instance();
+ }
+ return list;
+}
+
+void QAudioPluginLoader::load()
+{
+ if (!m_plugins.isEmpty())
+ return;
+
+#if !defined QT_NO_DEBUG
+ const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
+#endif
+
+ QStringList plugins = pluginList();
+ for (int i=0; i < plugins.count(); i++) {
+ QPluginLoader* loader = new QPluginLoader(plugins.at(i));
+ QObject *o = loader->instance();
+ if (o != 0 && o->qt_metacast(m_iid) != 0) {
+ m_plugins.append(loader);
+ } else {
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qWarning() << "QAudioPluginLoader: Failed to load plugin: "
+ << plugins.at(i) << loader->errorString();
+#endif
+ delete o;
+ //we are not calling loader->unload here for it may cause problem on some device
+ delete loader;
+ }
+ }
+}
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/audio/qaudiopluginloader_p.h b/src/multimedia/audio/qaudiopluginloader_p.h
new file mode 100644
index 000000000..2e6fdbdd7
--- /dev/null
+++ b/src/multimedia/audio/qaudiopluginloader_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAUDIOPLUGINLOADER_H
+#define QAUDIOPLUGINLOADER_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.
+//
+
+#include <qtmultimediadefs.h>
+#include <QObject>
+#include <QtCore/qstring.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qpluginloader.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioPluginLoader
+{
+public:
+ QAudioPluginLoader(const char *iid,
+ const QString &suffix = QString(),
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+
+ ~QAudioPluginLoader();
+
+ QStringList keys() const;
+ QObject* instance(QString const &key);
+ QList<QObject*> instances(QString const &key);
+
+private:
+ QStringList pluginList() const;
+ void load();
+
+ QMutex m_mutex;
+
+ QByteArray m_iid;
+ QString m_location;
+ QList<QPluginLoader*> m_plugins;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QAUDIOPLUGINLOADER_H
diff --git a/src/multimedia/audio/qaudiosystem.cpp b/src/multimedia/audio/qaudiosystem.cpp
new file mode 100644
index 000000000..a8837b06f
--- /dev/null
+++ b/src/multimedia/audio/qaudiosystem.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudiosystem.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractAudioDeviceInfo
+ \brief The QAbstractAudioDeviceInfo class is a base class for audio backends.
+
+ \ingroup multimedia
+ \inmodule QtMultimedia
+ \internal
+ \since 1.0
+
+ This class implements the audio functionality for
+ QAudioDeviceInfo, i.e., QAudioDeviceInfo keeps a
+ QAbstractAudioDeviceInfo and routes function calls to it. For a
+ description of the functionality that QAbstractAudioDeviceInfo
+ implements, you can read the class and functions documentation of
+ QAudioDeviceInfo.
+
+ \sa QAudioDeviceInfo
+ \sa QAbstractAudioOutput, QAbstractAudioInput
+*/
+
+/*!
+ \fn virtual QAudioFormat QAbstractAudioDeviceInfo::preferredFormat() const
+ Returns the recommended settings to use.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual bool QAbstractAudioDeviceInfo::isFormatSupported(const QAudioFormat& format) const
+ Returns true if \a format is available from audio device.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QString QAbstractAudioDeviceInfo::deviceName() const
+ Returns the audio device name.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QStringList QAbstractAudioDeviceInfo::supportedCodecs()
+ Returns the list of currently available codecs.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QList<int> QAbstractAudioDeviceInfo::supportedSampleRates()
+ Returns the list of currently available sample rates.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QList<int> QAbstractAudioDeviceInfo::supportedChannelCounts()
+ Returns the list of currently available channels.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QList<int> QAbstractAudioDeviceInfo::supportedSampleSizes()
+ Returns the list of currently available sample sizes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QList<QAudioFormat::Endian> QAbstractAudioDeviceInfo::supportedByteOrders()
+ Returns the list of currently available byte orders.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QList<QAudioFormat::SampleType> QAbstractAudioDeviceInfo::supportedSampleTypes()
+ Returns the list of currently available sample types.
+ \since 1.0
+*/
+
+/*!
+ \class QAbstractAudioOutput
+ \brief The QAbstractAudioOutput class is a base class for audio backends.
+ \since 1.0
+
+ \ingroup multimedia
+ \inmodule QtMultimedia
+ \internal
+
+ QAbstractAudioOutput implements audio functionality for
+ QAudioOutput, i.e., QAudioOutput routes function calls to
+ QAbstractAudioOutput. For a description of the functionality that
+ is implemented, see the QAudioOutput class and function
+ descriptions.
+
+ \sa QAudioOutput
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::start(QIODevice* device)
+ Uses the \a device as the QIODevice to transfer data.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QIODevice* QAbstractAudioOutput::start()
+ Returns a pointer to the QIODevice being used to handle
+ the data transfer. This QIODevice can be used to write() audio data directly.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::stop()
+ Stops the audio output.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::reset()
+ Drops all audio data in the buffers, resets buffers to zero.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::suspend()
+ Stops processing audio data, preserving buffered audio data.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::resume()
+ Resumes processing audio data after a suspend()
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioOutput::bytesFree() const
+ Returns the free space available in bytes in the audio buffer.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioOutput::periodSize() const
+ Returns the period size in bytes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::setBufferSize(int value)
+ Sets the audio buffer size to \a value in bytes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioOutput::bufferSize() const
+ Returns the audio buffer size in bytes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::setNotifyInterval(int ms)
+ Sets the interval for notify() signal to be emitted. This is based on the \a ms
+ of audio data processed not on actual real-time. The resolution of the timer
+ is platform specific.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioOutput::notifyInterval() const
+ Returns the notify interval in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual qint64 QAbstractAudioOutput::processedUSecs() const
+ Returns the amount of audio data processed since start() was called in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual qint64 QAbstractAudioOutput::elapsedUSecs() const
+ Returns the milliseconds since start() was called, including time in Idle and suspend states.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudio::Error QAbstractAudioOutput::error() const
+ Returns the error state.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudio::State QAbstractAudioOutput::state() const
+ Returns the state of audio processing.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::setFormat(const QAudioFormat& fmt)
+ Set the QAudioFormat to use to \a fmt.
+ Setting the format is only allowable while in QAudio::StoppedState.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudioFormat QAbstractAudioOutput::format() const
+ Returns the QAudioFormat being used.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioOutput::setVolume(qreal volume)
+ Sets the volume.
+ Where \a volume is between 0.0 and 1.0.
+ \since 5.0
+*/
+
+/*!
+ \fn virtual qreal QAbstractAudioOutput::volume() const
+ Returns the volume in the range 0.0 and 1.0.
+ \since 5.0
+*/
+
+/*!
+ \fn QAbstractAudioOutput::errorChanged(QAudio::Error error)
+ This signal is emitted when the \a error state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioOutput::stateChanged(QAudio::State state)
+ This signal is emitted when the device \a state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioOutput::notify()
+ This signal is emitted when x ms of audio data has been processed
+ the interval set by setNotifyInterval(x).
+ \since 1.0
+*/
+
+
+/*!
+ \class QAbstractAudioInput
+ \brief The QAbstractAudioInput class provides access for QAudioInput to access the audio
+ device provided by the plugin.
+ \since 1.0
+
+ \ingroup multimedia
+ \inmodule QtMultimedia
+ \internal
+
+ QAudioDeviceInput keeps an instance of QAbstractAudioInput and
+ routes calls to functions of the same name to QAbstractAudioInput.
+ This means that it is QAbstractAudioInput that implements the
+ audio functionality. For a description of the functionality, see
+ the QAudioInput class description.
+
+ \sa QAudioInput
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::start(QIODevice* device)
+ Uses the \a device as the QIODevice to transfer data.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QIODevice* QAbstractAudioInput::start()
+ Returns a pointer to the QIODevice being used to handle
+ the data transfer. This QIODevice can be used to read() audio data directly.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::stop()
+ Stops the audio input.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::reset()
+ Drops all audio data in the buffers, resets buffers to zero.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::suspend()
+ Stops processing audio data, preserving buffered audio data.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::resume()
+ Resumes processing audio data after a suspend().
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioInput::bytesReady() const
+ Returns the amount of audio data available to read in bytes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioInput::periodSize() const
+ Returns the period size in bytes.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::setBufferSize(int value)
+ Sets the audio buffer size to \a value in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioInput::bufferSize() const
+ Returns the audio buffer size in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::setNotifyInterval(int ms)
+ Sets the interval for notify() signal to be emitted. This is based
+ on the \a ms of audio data processed not on actual real-time.
+ The resolution of the timer is platform specific.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual int QAbstractAudioInput::notifyInterval() const
+ Returns the notify interval in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual qint64 QAbstractAudioInput::processedUSecs() const
+ Returns the amount of audio data processed since start() was called in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual qint64 QAbstractAudioInput::elapsedUSecs() const
+ Returns the milliseconds since start() was called, including time in Idle and suspend states.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudio::Error QAbstractAudioInput::error() const
+ Returns the error state.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudio::State QAbstractAudioInput::state() const
+ Returns the state of audio processing.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual void QAbstractAudioInput::setFormat(const QAudioFormat& fmt)
+ Set the QAudioFormat to use to \a fmt.
+ Setting the format is only allowable while in QAudio::StoppedState.
+ \since 1.0
+*/
+
+/*!
+ \fn virtual QAudioFormat QAbstractAudioInput::format() const
+ Returns the QAudioFormat being used
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioInput::errorChanged(QAudio::Error error)
+ This signal is emitted when the \a error state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioInput::stateChanged(QAudio::State state)
+ This signal is emitted when the device \a state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioInput::notify()
+ This signal is emitted when x ms of audio data has been processed
+ the interval set by setNotifyInterval(x).
+ \since 1.0
+*/
+
+
+QT_END_NAMESPACE
+
+#include "moc_qaudiosystem.cpp"
diff --git a/src/multimedia/audio/qaudiosystem.h b/src/multimedia/audio/qaudiosystem.h
new file mode 100644
index 000000000..59b4eb432
--- /dev/null
+++ b/src/multimedia/audio/qaudiosystem.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAUDIOSYSTEM_H
+#define QAUDIOSYSTEM_H
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include "qaudio.h"
+#include "qaudioformat.h"
+#include "qaudiodeviceinfo.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QAbstractAudioDeviceInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual QAudioFormat preferredFormat() const = 0;
+ virtual bool isFormatSupported(const QAudioFormat &format) const = 0;
+ virtual QString deviceName() const = 0;
+ virtual QStringList supportedCodecs() = 0;
+ virtual QList<int> supportedSampleRates() = 0;
+ virtual QList<int> supportedChannelCounts() = 0;
+ virtual QList<int> supportedSampleSizes() = 0;
+ virtual QList<QAudioFormat::Endian> supportedByteOrders() = 0;
+ virtual QList<QAudioFormat::SampleType> supportedSampleTypes() = 0;
+};
+
+class Q_MULTIMEDIA_EXPORT QAbstractAudioOutput : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual void start(QIODevice *device) = 0;
+ virtual QIODevice* start() = 0;
+ virtual void stop() = 0;
+ virtual void reset() = 0;
+ virtual void suspend() = 0;
+ virtual void resume() = 0;
+ virtual int bytesFree() const = 0;
+ virtual int periodSize() const = 0;
+ virtual void setBufferSize(int value) = 0;
+ virtual int bufferSize() const = 0;
+ virtual void setNotifyInterval(int milliSeconds) = 0;
+ virtual int notifyInterval() const = 0;
+ virtual qint64 processedUSecs() const = 0;
+ virtual qint64 elapsedUSecs() const = 0;
+ virtual QAudio::Error error() const = 0;
+ virtual QAudio::State state() const = 0;
+ virtual void setFormat(const QAudioFormat& fmt) = 0;
+ virtual QAudioFormat format() const = 0;
+ virtual void setVolume(qreal) {}
+ virtual qreal volume() const { return 1.0; }
+
+Q_SIGNALS:
+ void errorChanged(QAudio::Error);
+ void stateChanged(QAudio::State);
+ void notify();
+};
+
+class Q_MULTIMEDIA_EXPORT QAbstractAudioInput : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual void start(QIODevice *device) = 0;
+ virtual QIODevice* start() = 0;
+ virtual void stop() = 0;
+ virtual void reset() = 0;
+ virtual void suspend() = 0;
+ virtual void resume() = 0;
+ virtual int bytesReady() const = 0;
+ virtual int periodSize() const = 0;
+ virtual void setBufferSize(int value) = 0;
+ virtual int bufferSize() const = 0;
+ virtual void setNotifyInterval(int milliSeconds) = 0;
+ virtual int notifyInterval() const = 0;
+ virtual qint64 processedUSecs() const = 0;
+ virtual qint64 elapsedUSecs() const = 0;
+ virtual QAudio::Error error() const = 0;
+ virtual QAudio::State state() const = 0;
+ virtual void setFormat(const QAudioFormat& fmt) = 0;
+ virtual QAudioFormat format() const = 0;
+
+Q_SIGNALS:
+ void errorChanged(QAudio::Error);
+ void stateChanged(QAudio::State);
+ void notify();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOSYSTEM_H
diff --git a/src/multimedia/audio/qaudiosystemplugin.cpp b/src/multimedia/audio/qaudiosystemplugin.cpp
new file mode 100644
index 000000000..5cbcf1d60
--- /dev/null
+++ b/src/multimedia/audio/qaudiosystemplugin.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qaudiosystemplugin.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAudioSystemPlugin
+ \brief The QAudioSystemPlugin class provides an abstract base for audio plugins.
+ \since 1.0
+
+ \ingroup multimedia
+ \inmodule QtMultimedia
+ \internal
+
+ Writing a audio plugin is achieved by subclassing this base class,
+ reimplementing the pure virtual functions keys(), availableDevices(),
+ createInput(), createOutput() and createDeviceInfo() then exporting
+ the class with the Q_EXPORT_PLUGIN2() macro.
+
+ Unit tests are available to help in debugging new plugins.
+
+ \sa QAbstractAudioDeviceInfo, QAbstractAudioOutput, QAbstractAudioInput
+
+ Qt supports win32, linux(alsa) and Mac OS X standard (builtin to the
+ QtMultimedia library at compile time).
+
+ You can support other backends other than these predefined ones by
+ creating a plugin subclassing QAudioSystemPlugin, QAbstractAudioDeviceInfo,
+ QAbstractAudioOutput and QAbstractAudioInput.
+
+ Add "default" to your list of keys() available to override the default
+ audio device to be provided by your plugin.
+
+ -audio-backend configure option will force compiling in of the builtin backend
+ into the QtMultimedia library at compile time. This is automatic by default
+ and will only be compiled into the library if the dependencies are installed.
+ eg. alsa-devel package installed for linux.
+
+ If the builtin backend is not compiled into the QtMultimedia library and
+ no audio plugins are available a fallback dummy backend will be used.
+ This should print out warnings if this is the case when you try and use QAudioInput or QAudioOutput. To fix this problem
+ reconfigure Qt using -audio-backend or create your own plugin with a default
+ key to always override the dummy fallback. The easiest way to determine
+ if you have only a dummy backend is to get a list of available audio devices.
+
+ QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).size() = 0 (dummy backend)
+*/
+
+/*!
+ Construct a new audio plugin with \a parent.
+ This is invoked automatically by the Q_EXPORT_PLUGIN2() macro.
+*/
+
+QAudioSystemPlugin::QAudioSystemPlugin(QObject* parent) :
+ QObject(parent)
+{}
+
+/*!
+ Destroy the audio plugin
+
+ You never have to call this explicitly. Qt destroys a plugin automatically when it is no longer used.
+*/
+
+QAudioSystemPlugin::~QAudioSystemPlugin()
+{}
+
+/*!
+ \fn QStringList QAudioSystemPlugin::keys() const
+ Returns the list of device identifiers this plugin supports.
+ \since 1.0
+*/
+
+/*!
+ \fn QList<QByteArray> QAudioSystemPlugin::availableDevices(QAudio::Mode mode) const
+ Returns a list of available audio devices for \a mode
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioInput* QAudioSystemPlugin::createInput(const QByteArray& device)
+ Returns a pointer to a QAbstractAudioInput created using \a device identifier
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioOutput* QAudioSystemPlugin::createOutput(const QByteArray& device)
+ Returns a pointer to a QAbstractAudioOutput created using \a device identifier
+
+ \since 1.0
+*/
+
+/*!
+ \fn QAbstractAudioDeviceInfo* QAudioSystemPlugin::createDeviceInfo(const QByteArray& device, QAudio::Mode mode)
+ Returns a pointer to a QAbstractAudioDeviceInfo created using \a device and \a mode
+
+ \since 1.0
+*/
+
+
+QT_END_NAMESPACE
+
+#include "moc_qaudiosystemplugin.cpp"
diff --git a/src/multimedia/audio/qaudiosystemplugin.h b/src/multimedia/audio/qaudiosystemplugin.h
new file mode 100644
index 000000000..f61dbcfd1
--- /dev/null
+++ b/src/multimedia/audio/qaudiosystemplugin.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QAUDIOSYSTEMPLUGIN_H
+#define QAUDIOSYSTEMPLUGIN_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+#include "qaudioformat.h"
+#include "qaudiodeviceinfo.h"
+#include "qaudiosystem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+struct Q_MULTIMEDIA_EXPORT QAudioSystemFactoryInterface : public QFactoryInterface
+{
+ virtual QList<QByteArray> availableDevices(QAudio::Mode) const = 0;
+ virtual QAbstractAudioInput* createInput(const QByteArray& device) = 0;
+ virtual QAbstractAudioOutput* createOutput(const QByteArray& device) = 0;
+ virtual QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, QAudio::Mode mode) = 0;
+};
+
+#define QAudioSystemFactoryInterface_iid \
+ "com.nokia.qt.QAudioSystemFactoryInterface"
+Q_DECLARE_INTERFACE(QAudioSystemFactoryInterface, QAudioSystemFactoryInterface_iid)
+
+class Q_MULTIMEDIA_EXPORT QAudioSystemPlugin : public QObject, public QAudioSystemFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QAudioSystemFactoryInterface:QFactoryInterface)
+
+public:
+ QAudioSystemPlugin(QObject *parent = 0);
+ ~QAudioSystemPlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QList<QByteArray> availableDevices(QAudio::Mode) const = 0;
+ virtual QAbstractAudioInput* createInput(const QByteArray& device) = 0;
+ virtual QAbstractAudioOutput* createOutput(const QByteArray& device) = 0;
+ virtual QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, QAudio::Mode mode) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAUDIOSYSTEMPLUGIN_H
diff --git a/src/multimedia/effects/effects.pri b/src/multimedia/effects/effects.pri
new file mode 100644
index 000000000..48c9906b6
--- /dev/null
+++ b/src/multimedia/effects/effects.pri
@@ -0,0 +1,36 @@
+INCLUDEPATH += effects
+
+unix:!mac {
+ contains(config_test_pulseaudio, yes) {
+ CONFIG += link_pkgconfig
+ PKGCONFIG += libpulse
+
+ DEFINES += QT_MULTIMEDIA_PULSEAUDIO
+ PRIVATE_HEADERS += effects/qsoundeffect_pulse_p.h
+ SOURCES += effects/qsoundeffect_pulse_p.cpp
+ !maemo*:DEFINES += QTM_PULSEAUDIO_DEFAULTBUFFER
+ } else {
+ DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER
+ PRIVATE_HEADERS += effects/qsoundeffect_qmedia_p.h
+ SOURCES += effects/qsoundeffect_qmedia_p.cpp
+ }
+} else:!qpa {
+ PRIVATE_HEADERS += effects/qsoundeffect_qsound_p.h
+ SOURCES += effects/qsoundeffect_qsound_p.cpp
+} else {
+ DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER
+ PRIVATE_HEADERS += effects/qsoundeffect_qmedia_p.h
+ SOURCES += effects/qsoundeffect_qmedia_p.cpp
+}
+
+PRIVATE_HEADERS += \
+ effects/qsoundeffect_p.h \
+ effects/qwavedecoder_p.h \
+ effects/qsamplecache_p.h
+
+SOURCES += \
+ effects/qsoundeffect.cpp \
+ effects/qwavedecoder_p.cpp \
+ effects/qsamplecache_p.cpp
+
+HEADERS +=
diff --git a/src/multimedia/effects/qsamplecache_p.cpp b/src/multimedia/effects/qsamplecache_p.cpp
new file mode 100644
index 000000000..1610a4382
--- /dev/null
+++ b/src/multimedia/effects/qsamplecache_p.cpp
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsamplecache_p.h"
+#include "qwavedecoder_p.h"
+#include <QtNetwork>
+
+//#define QT_SAMPLECACHE_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QSampleCache
+ \internal
+
+ When you want to get a sound sample data, you need to request the QSample reference from QSampleCache.
+
+ \since 1.1
+
+ \code
+ QSample *m_sample; // class member.
+
+ private Q_SLOTS:
+ void decoderError();
+ void sampleReady();
+ \endcode
+
+ \code
+ Q_GLOBAL_STATIC(QSampleCache, sampleCache) //declare a singleton manager
+ \endcode
+
+ \code
+ m_sample = sampleCache()->requestSample(url);
+ switch(m_sample->state()) {
+ case QSample::Ready:
+ sampleReady();
+ break;
+ case QSample::Error:
+ decoderError();
+ break;
+ default:
+ connect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
+ connect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
+ break;
+ }
+ \endcode
+
+ When you no longer need the sound sample data, you need to release it:
+
+ \code
+ if (m_sample) {
+ m_sample->release();
+ m_sample = 0;
+ }
+ \endcode
+*/
+
+QSampleCache::QSampleCache()
+ : m_networkAccessManager(0)
+ , m_mutex(QMutex::Recursive)
+ , m_capacity(0)
+ , m_usage(0)
+{
+ m_loadingThread.setObjectName(QLatin1String("QSampleCache::LoadingThread"));
+}
+
+QNetworkAccessManager& QSampleCache::networkAccessManager()
+{
+ if (!m_networkAccessManager)
+ m_networkAccessManager = new QNetworkAccessManager();
+ return *m_networkAccessManager;
+}
+
+QSampleCache::~QSampleCache()
+{
+ QMutexLocker m(&m_mutex);
+
+ m_loadingThread.quit();
+ m_loadingThread.wait();
+
+ // Killing the loading thread means that no samples can be
+ // deleted using deleteLater. And some samples that had deleteLater
+ // already called won't have been processed (m_staleSamples)
+ foreach (QSample* sample, m_samples)
+ delete sample;
+
+ foreach (QSample* sample, m_staleSamples)
+ delete sample; // deleting a sample does affect the m_staleSamples list, but foreach copies it
+
+ delete m_networkAccessManager;
+}
+
+QSample* QSampleCache::requestSample(const QUrl& url)
+{
+ if (!m_loadingThread.isRunning())
+ m_loadingThread.start();
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSampleCache: request sample [" << url << "]";
+#endif
+ QMutexLocker locker(&m_mutex);
+ QMap<QUrl, QSample*>::iterator it = m_samples.find(url);
+ QSample* sample;
+ if (it == m_samples.end()) {
+ sample = new QSample(url, this);
+ m_samples.insert(url, sample);
+ sample->moveToThread(&m_loadingThread);
+ } else {
+ sample = *it;
+ }
+
+ sample->addRef();
+ locker.unlock();
+
+ sample->loadIfNecessary();
+ return sample;
+}
+
+void QSampleCache::setCapacity(qint64 capacity)
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_capacity == capacity)
+ return;
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSampleCache: capacity changes from " << m_capacity << "to " << capacity;
+#endif
+ if (m_capacity > 0 && capacity <= 0) { //memory management strategy changed
+ for (QMap<QUrl, QSample*>::iterator it = m_samples.begin(); it != m_samples.end();) {
+ QSample* sample = *it;
+ if (sample->m_ref == 0) {
+ unloadSample(sample);
+ it = m_samples.erase(it);
+ } else
+ it++;
+ }
+ }
+
+ m_capacity = capacity;
+ refresh(0);
+}
+
+// Called locked
+void QSampleCache::unloadSample(QSample *sample)
+{
+ m_usage -= sample->m_soundData.size();
+ m_staleSamples.insert(sample);
+ sample->deleteLater();
+}
+
+// Called in both threads
+void QSampleCache::refresh(qint64 usageChange)
+{
+ QMutexLocker locker(&m_mutex);
+ m_usage += usageChange;
+ if (m_capacity <= 0 || m_usage <= m_capacity)
+ return;
+
+#ifdef QT_SAMPLECACHE_DEBUG
+ qint64 recoveredSize = 0;
+#endif
+
+ //free unused samples to keep usage under capacity limit.
+ for (QMap<QUrl, QSample*>::iterator it = m_samples.begin(); it != m_samples.end();) {
+ QSample* sample = *it;
+ if (sample->m_ref > 0) {
+ ++it;
+ continue;
+ }
+#ifdef QT_SAMPLECACHE_DEBUG
+ recoveredSize += sample->m_soundData.size();
+#endif
+ unloadSample(sample);
+ it = m_samples.erase(it);
+ if (m_usage <= m_capacity)
+ return;
+ }
+
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSampleCache: refresh(" << usageChange
+ << ") recovered size =" << recoveredSize
+ << "new usage =" << m_usage;
+#endif
+
+ if (m_usage > m_capacity)
+ qWarning() << "QSampleCache: usage[" << m_usage << " out of limit[" << m_capacity << "]";
+}
+
+// Called in both threads
+void QSampleCache::removeUnreferencedSample(QSample *sample)
+{
+ QMutexLocker m(&m_mutex);
+ m_staleSamples.remove(sample);
+}
+
+// Called in loader thread (since this lives in that thread)
+// Also called from application thread after loader thread dies.
+QSample::~QSample()
+{
+ // Remove ourselves from our parent
+ m_parent->removeUnreferencedSample(this);
+
+ QMutexLocker locker(&m_mutex);
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "~QSample" << this << ": deleted [" << m_url << "]" << QThread::currentThread();
+#endif
+ cleanup();
+}
+
+// Called in application thread
+void QSample::loadIfNecessary()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_state == QSample::Error || m_state == QSample::Creating) {
+ m_state = QSample::Loading;
+ QMetaObject::invokeMethod(this, "load", Qt::QueuedConnection);
+ }
+}
+
+// Called in both threads
+bool QSampleCache::notifyUnreferencedSample(QSample* sample)
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_capacity > 0)
+ return false;
+ m_samples.remove(sample->m_url);
+ m_staleSamples.insert(sample);
+ sample->deleteLater();
+ return true;
+}
+
+// Called in application threadd
+void QSample::release()
+{
+ QMutexLocker locker(&m_mutex);
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "Sample:: release" << this << QThread::currentThread() << m_ref;
+#endif
+ m_ref--;
+ if (m_ref == 0)
+ m_parent->notifyUnreferencedSample(this);
+}
+
+// Called in dtor and when stream is loaded
+// must be called locked.
+void QSample::cleanup()
+{
+ delete m_waveDecoder;
+ delete m_stream;
+ m_waveDecoder = 0;
+ m_stream = 0;
+}
+
+// Called in application thread
+void QSample::addRef()
+{
+ m_ref++;
+}
+
+// Called in loading thread
+void QSample::readSample()
+{
+ Q_ASSERT(QThread::currentThread()->objectName() == QLatin1String("QSampleCache::LoadingThread"));
+ QMutexLocker m(&m_mutex);
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSample: readSample";
+#endif
+ qint64 read = m_waveDecoder->read(m_soundData.data() + m_sampleReadLength,
+ qMin(m_waveDecoder->bytesAvailable(),
+ qint64(m_waveDecoder->size() - m_sampleReadLength)));
+ if (read > 0)
+ m_sampleReadLength += read;
+ if (m_sampleReadLength < m_waveDecoder->size())
+ return;
+ Q_ASSERT(m_sampleReadLength == qint64(m_soundData.size()));
+ onReady();
+}
+
+// Called in loading thread
+void QSample::decoderReady()
+{
+ Q_ASSERT(QThread::currentThread()->objectName() == QLatin1String("QSampleCache::LoadingThread"));
+ QMutexLocker m(&m_mutex);
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSample: decoder ready";
+#endif
+ m_parent->refresh(m_waveDecoder->size());
+
+ m_soundData.resize(m_waveDecoder->size());
+ m_sampleReadLength = 0;
+ qint64 read = m_waveDecoder->read(m_soundData.data(), m_waveDecoder->size());
+ if (read > 0)
+ m_sampleReadLength += read;
+ if (m_sampleReadLength >= m_waveDecoder->size())
+ onReady();
+}
+
+// Called in all threads
+QSample::State QSample::state() const
+{
+ QMutexLocker m(&m_mutex);
+ return m_state;
+}
+
+// Called in loading thread
+// Essentially a second ctor, doesn't need locks (?)
+void QSample::load()
+{
+ Q_ASSERT(QThread::currentThread()->objectName() == QLatin1String("QSampleCache::LoadingThread"));
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSample: load [" << m_url << "]";
+#endif
+ m_stream = m_parent->networkAccessManager().get(QNetworkRequest(m_url));
+ connect(m_stream, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(decoderError()));
+ m_waveDecoder = new QWaveDecoder(m_stream);
+ connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady()));
+ connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError()));
+ connect(m_waveDecoder, SIGNAL(readyRead()), SLOT(readSample()));
+}
+
+// Called in loading thread
+void QSample::decoderError()
+{
+ Q_ASSERT(QThread::currentThread()->objectName() == QLatin1String("QSampleCache::LoadingThread"));
+ QMutexLocker m(&m_mutex);
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSample: decoder error";
+#endif
+ cleanup();
+ m_state = QSample::Error;
+ emit error();
+}
+
+// Called in loading thread from decoder when sample is done. Locked already.
+void QSample::onReady()
+{
+ Q_ASSERT(QThread::currentThread()->objectName() == QLatin1String("QSampleCache::LoadingThread"));
+#ifdef QT_SAMPLECACHE_DEBUG
+ qDebug() << "QSample: load ready";
+#endif
+ m_audioFormat = m_waveDecoder->audioFormat();
+ cleanup();
+ m_state = QSample::Ready;
+ emit ready();
+}
+
+// Called in application thread, then moved to loader thread
+QSample::QSample(const QUrl& url, QSampleCache *parent)
+ : m_parent(parent)
+ , m_stream(0)
+ , m_waveDecoder(0)
+ , m_url(url)
+ , m_sampleReadLength(0)
+ , m_state(Creating)
+ , m_ref(0)
+{
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsamplecache_p.cpp"
diff --git a/src/multimedia/effects/qsamplecache_p.h b/src/multimedia/effects/qsamplecache_p.h
new file mode 100644
index 000000000..91ca457e6
--- /dev/null
+++ b/src/multimedia/effects/qsamplecache_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSAMPLECACHE_P_H
+#define QSAMPLECACHE_P_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.
+//
+
+#include <QtCore/qobject.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qset.h>
+#include <qaudioformat.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QNetworkAccessManager;
+class QSampleCache;
+class QWaveDecoder;
+
+// Lives in application thread
+class QSample : public QObject
+{
+ Q_OBJECT
+public:
+ friend class QSampleCache;
+ enum State
+ {
+ Creating,
+ Loading,
+ Error,
+ Ready,
+ };
+
+ State state() const;
+ // These are not (currently) locked because they are only meant to be called after these
+ // variables are updated to their final states
+ const QByteArray& data() const { Q_ASSERT(state() == Ready); return m_soundData; }
+ const QAudioFormat& format() const { Q_ASSERT(state() == Ready); return m_audioFormat; }
+ void release();
+
+Q_SIGNALS:
+ void error();
+ void ready();
+
+protected:
+ QSample(const QUrl& url, QSampleCache *parent);
+
+private Q_SLOTS:
+ void load();
+ void decoderError();
+ void readSample();
+ void decoderReady();
+
+private:
+ void onReady();
+ void cleanup();
+ void addRef();
+ void loadIfNecessary();
+ QSample();
+ ~QSample();
+
+ mutable QMutex m_mutex;
+ QSampleCache *m_parent;
+ QByteArray m_soundData;
+ QAudioFormat m_audioFormat;
+ QIODevice *m_stream;
+ QWaveDecoder *m_waveDecoder;
+ QUrl m_url;
+ qint64 m_sampleReadLength;
+ State m_state;
+ int m_ref;
+};
+
+class QSampleCache
+{
+public:
+ friend class QSample;
+
+ QSampleCache();
+ ~QSampleCache();
+
+ QSample* requestSample(const QUrl& url);
+ void setCapacity(qint64 capacity);
+
+private:
+ QMap<QUrl, QSample*> m_samples;
+ QSet<QSample*> m_staleSamples;
+ QNetworkAccessManager *m_networkAccessManager;
+ QMutex m_mutex;
+ qint64 m_capacity;
+ qint64 m_usage;
+ QThread m_loadingThread;
+
+ QNetworkAccessManager& networkAccessManager();
+ void refresh(qint64 usageChange);
+ bool notifyUnreferencedSample(QSample* sample);
+ void removeUnreferencedSample(QSample* sample);
+ void unloadSample(QSample* sample);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSAMPLECACHE_P_H
diff --git a/src/multimedia/effects/qsoundeffect.cpp b/src/multimedia/effects/qsoundeffect.cpp
new file mode 100644
index 000000000..b1137a22e
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect.cpp
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsoundeffect_p.h"
+
+#if defined(QT_MULTIMEDIA_PULSEAUDIO)
+#include "qsoundeffect_pulse_p.h"
+#elif(QT_MULTIMEDIA_QMEDIAPLAYER)
+#include "qsoundeffect_qmedia_p.h"
+#else
+#include "qsoundeffect_qsound_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass SoundEffect QSoundEffect
+ \brief The SoundEffect element provides a way to play sound effects in QML.
+ \since 1.0
+
+ \inmodule QtMultimedia
+
+ This element is part of the \bold{QtMultimedia 4.0} module.
+
+ The following example plays a WAV file on mouse click.
+
+ \snippet doc/src/snippets/multimedia-snippets/soundeffect.qml complete snippet
+*/
+
+/*!
+ \qmlproperty url SoundEffect::source
+ \since 1.0
+
+ This property provides a way to control the sound to play.
+*/
+
+/*!
+ \qmlproperty int SoundEffect::loops
+ \since 1.0
+
+ This property provides a way to control the number of times to repeat the sound on each play().
+
+ Set to -1 (infinite) to enable infinite loop.
+*/
+
+/*!
+ \qmlproperty qreal SoundEffect::volume
+ \since 1.0
+
+ This property holds the volume of the playback, from 0.0 (silent) to 1.0 (maximum volume).
+ Note: Currently this has no effect on Mac OS X.
+*/
+
+/*!
+ \qmlproperty bool SoundEffect::muted
+ \since 1.0
+
+ This property provides a way to control muting.
+*/
+
+/*!
+ \qmlproperty bool SoundEffect::playing
+ \since 1.1
+
+ This property indicates if the soundeffect is playing or not.
+*/
+
+/*!
+ \qmlproperty int SoundEffect::status
+ \since 1.0
+
+ This property indicates the following status of the soundeffect.
+
+ Null: no source has been set or is null.
+ Loading: the soundeffect is trying to load the source.
+ Ready: the source is loaded and ready for play.
+ Error: some error happened during operation, such as failure of loading the source.
+*/
+
+/*!
+ \qmlsignal SoundEffect::sourceChanged()
+ \since 1.0
+
+ This handler is called when the source has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::loopsChanged()
+ \since 1.0
+
+ This handler is called when the number of loops has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::volumeChanged()
+ \since 1.0
+
+ This handler is called when the volume has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::mutedChanged()
+ \since 1.0
+
+ This handler is called when the mute state has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::playingChanged()
+ \since 1.0
+
+ This handler is called when the playing property has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::statusChanged()
+
+ This handler is called when the status property has changed.
+ \since 1.0
+*/
+
+
+/*!
+ \internal
+ \since 1.0
+*/
+
+QSoundEffect::QSoundEffect(QObject *parent) :
+ QObject(parent)
+{
+ d = new QSoundEffectPrivate(this);
+ connect(d, SIGNAL(volumeChanged()), SIGNAL(volumeChanged()));
+ connect(d, SIGNAL(mutedChanged()), SIGNAL(mutedChanged()));
+ connect(d, SIGNAL(loadedChanged()), SIGNAL(loadedChanged()));
+ connect(d, SIGNAL(playingChanged()), SIGNAL(playingChanged()));
+ connect(d, SIGNAL(statusChanged()), SIGNAL(statusChanged()));
+}
+
+QSoundEffect::~QSoundEffect()
+{
+ d->deleteLater();
+}
+
+QStringList QSoundEffect::supportedMimeTypes()
+{
+ return QSoundEffectPrivate::supportedMimeTypes();
+}
+
+QUrl QSoundEffect::source() const
+{
+ return d->source();
+}
+
+void QSoundEffect::setSource(const QUrl &url)
+{
+ if (d->source() == url)
+ return;
+
+ d->setSource(url);
+
+ emit sourceChanged();
+}
+
+int QSoundEffect::loopCount() const
+{
+ return d->loopCount();
+}
+
+void QSoundEffect::setLoopCount(int loopCount)
+{
+ if (loopCount < 0 && loopCount != Infinite) {
+ qWarning("SoundEffect: loops should be SoundEffect.Infinite, 0 or positive integer");
+ return;
+ }
+ if (loopCount == 0)
+ loopCount = 1;
+ if (d->loopCount() == loopCount)
+ return;
+
+ d->setLoopCount(loopCount);
+ emit loopCountChanged();
+}
+
+qreal QSoundEffect::volume() const
+{
+ return qreal(d->volume()) / 100;
+}
+
+void QSoundEffect::setVolume(qreal volume)
+{
+ if (volume < 0 || volume > 1) {
+ qWarning("SoundEffect: volume should be between 0.0 and 1.0");
+ return;
+ }
+ int iVolume = qRound(volume * 100);
+ if (d->volume() == iVolume)
+ return;
+
+ d->setVolume(iVolume);
+}
+
+bool QSoundEffect::isMuted() const
+{
+ return d->isMuted();
+}
+
+void QSoundEffect::setMuted(bool muted)
+{
+ if (d->isMuted() == muted)
+ return;
+
+ d->setMuted(muted);
+}
+
+bool QSoundEffect::isLoaded() const
+{
+ return d->isLoaded();
+}
+
+/*!
+ \qmlmethod SoundEffect::play()
+
+ Start playback of the sound effect, looping the effect for the number of
+ times as specificed in the loops property.
+
+ This is the default method for SoundEffect.
+
+ \snippet doc/src/snippets/multimedia-snippets/soundeffect.qml play sound on click
+ \since 1.0
+*/
+void QSoundEffect::play()
+{
+ d->play();
+}
+
+bool QSoundEffect::isPlaying() const
+{
+ return d->isPlaying();
+}
+
+QSoundEffect::Status QSoundEffect::status() const
+{
+ return d->status();
+}
+
+
+/*!
+ \qmlmethod SoundEffect::stop()
+
+ Stop current playback.
+ Note that if the backend is PulseAudio, due to the limitation of the underlying API,
+ tis stop will only prevent next looping but will not be able to stop current playback immediately.
+
+ \since 1.0
+ */
+void QSoundEffect::stop()
+{
+ d->stop();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsoundeffect_p.cpp"
diff --git a/src/multimedia/effects/qsoundeffect_p.h b/src/multimedia/effects/qsoundeffect_p.h
new file mode 100644
index 000000000..93248184a
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_P_H
+#define QSOUNDEFFECT_P_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.
+//
+
+#include <qtmultimediadefs.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qstringlist.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QSoundEffectPrivate;
+
+class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultMethod", "play()")
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(int loops READ loopCount WRITE setLoopCount NOTIFY loopCountChanged)
+ Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(bool playing READ isPlaying NOTIFY playingChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_ENUMS(Loop)
+ Q_ENUMS(Status)
+
+public:
+ enum Loop
+ {
+ Infinite = -2,
+ };
+
+ enum Status
+ {
+ Null,
+ Loading,
+ Ready,
+ Error
+ };
+
+ explicit QSoundEffect(QObject *parent = 0);
+ ~QSoundEffect();
+
+ static QStringList supportedMimeTypes();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+
+ qreal volume() const;
+ void setVolume(qreal volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ bool isLoaded() const;
+
+ bool isPlaying() const;
+ Status status() const;
+
+Q_SIGNALS:
+ void sourceChanged();
+ void loopCountChanged();
+ void volumeChanged();
+ void mutedChanged();
+ void loadedChanged();
+ void playingChanged();
+ void statusChanged();
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+private:
+ Q_DISABLE_COPY(QSoundEffect)
+ QSoundEffectPrivate* d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QSOUNDEFFECT_H
diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.cpp b/src/multimedia/effects/qsoundeffect_pulse_p.cpp
new file mode 100644
index 000000000..4570f8fd5
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_pulse_p.cpp
@@ -0,0 +1,957 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include <qaudioformat.h>
+#include <QtNetwork>
+#include <QTime>
+
+#include "qsoundeffect_pulse_p.h"
+
+#if defined(Q_WS_MAEMO_6)
+#include <pulse/ext-stream-restore.h>
+#endif
+
+#include <unistd.h>
+
+//#define QT_PA_DEBUG
+#ifndef QTM_PULSEAUDIO_DEFAULTBUFFER
+#define QT_PA_STREAM_BUFFER_SIZE_MAX (1024 * 64) //64KB is a trade-off for balancing control latency and uploading overhead
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace
+{
+inline pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format)
+{
+ pa_sample_spec spec;
+
+ spec.rate = format.frequency();
+ spec.channels = format.channels();
+
+ if (format.sampleSize() == 8)
+ spec.format = PA_SAMPLE_U8;
+ else if (format.sampleSize() == 16) {
+ switch (format.byteOrder()) {
+ case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S16BE; break;
+ case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S16LE; break;
+ }
+ }
+ else if (format.sampleSize() == 32) {
+ switch (format.byteOrder()) {
+ case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S32BE; break;
+ case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S32LE; break;
+ }
+ }
+
+ return spec;
+}
+
+class PulseDaemon : public QObject
+{
+ Q_OBJECT
+public:
+ PulseDaemon(): m_prepared(false)
+ {
+ prepare();
+ }
+
+ ~PulseDaemon()
+ {
+ if (m_prepared)
+ release();
+ }
+
+ inline void lock()
+ {
+ pa_threaded_mainloop_lock(m_mainLoop);
+ }
+
+ inline void unlock()
+ {
+ pa_threaded_mainloop_unlock(m_mainLoop);
+ }
+
+ inline pa_context *context() const
+ {
+ return m_context;
+ }
+
+ inline pa_cvolume * calcVolume(pa_cvolume *dest, int soundEffectVolume)
+ {
+ dest->channels = 2;
+ dest->values[0] = dest->values[1] = m_vol * soundEffectVolume / 100;
+ return dest;
+ }
+
+ void updateStatus(const pa_cvolume& volume)
+ {
+ if (m_vol != pa_cvolume_max(&volume)) {
+ m_vol = pa_cvolume_max(&volume);
+ emit volumeChanged();
+ }
+ }
+
+Q_SIGNALS:
+ void contextReady();
+ void volumeChanged();
+
+private:
+ void prepare()
+ {
+ m_vol = PA_VOLUME_NORM;
+
+ m_mainLoop = pa_threaded_mainloop_new();
+ if (m_mainLoop == 0) {
+ qWarning("PulseAudioService: unable to create pulseaudio mainloop");
+ return;
+ }
+
+ if (pa_threaded_mainloop_start(m_mainLoop) != 0) {
+ qWarning("PulseAudioService: unable to start pulseaudio mainloop");
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+
+ m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop);
+
+ lock();
+ m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toAscii().constData());
+
+ pa_context_set_state_callback(m_context, context_state_callback, this);
+
+ if (m_context == 0) {
+ qWarning("PulseAudioService: Unable to create new pulseaudio context");
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+
+ if (pa_context_connect(m_context, 0, (pa_context_flags_t)0, 0) < 0) {
+ qWarning("PulseAudioService: pa_context_connect() failed");
+ pa_context_unref(m_context);
+ pa_threaded_mainloop_free(m_mainLoop);
+ return;
+ }
+ unlock();
+
+ m_prepared = true;
+ }
+
+ void release()
+ {
+ if (!m_prepared) return;
+ pa_threaded_mainloop_stop(m_mainLoop);
+ pa_threaded_mainloop_free(m_mainLoop);
+ m_prepared = false;
+ }
+
+ static void context_state_callback(pa_context *c, void *userdata)
+ {
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ case PA_CONTEXT_READY:
+ #if defined(Q_WS_MAEMO_6)
+ pa_ext_stream_restore_read(c, &stream_restore_info_callback, self);
+ pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self);
+ pa_ext_stream_restore_subscribe(c, 1, 0, self);
+ #endif
+ QMetaObject::invokeMethod(self, "contextReady", Qt::QueuedConnection);
+ break;
+ default:
+ break;
+ }
+ }
+
+#if defined(Q_WS_MAEMO_6)
+
+ static void stream_restore_monitor_callback(pa_context *c, void *userdata)
+ {
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+ pa_ext_stream_restore_read(c, &stream_restore_info_callback, self);
+ }
+
+ static void stream_restore_info_callback(pa_context *c,
+ const pa_ext_stream_restore_info *info,
+ int eol, void *userdata)
+ {
+ Q_UNUSED(c)
+
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+
+ if (!eol) {
+ if (QString(info->name).startsWith(QLatin1String("sink-input-by-media-role:x-maemo"))) {
+#ifdef QT_PA_DEBUG
+ qDebug() << "x-maemo volume =(" << info->volume.values[0] * 100 / PA_VOLUME_NORM << ","
+ << info->volume.values[1] * 100 / PA_VOLUME_NORM << "), "
+ << "mute = " << info->mute;
+#endif
+ self->updateStatus(info->volume);
+ }
+ }
+ }
+#endif
+
+ pa_volume_t m_vol;
+
+ bool m_prepared;
+ pa_context *m_context;
+ pa_threaded_mainloop *m_mainLoop;
+ pa_mainloop_api *m_mainLoopApi;
+};
+
+}
+
+Q_GLOBAL_STATIC(PulseDaemon, daemon)
+Q_GLOBAL_STATIC(QSampleCache, sampleCache)
+
+namespace
+{
+class PulseDaemonLocker
+{
+public:
+ PulseDaemonLocker()
+ {
+ daemon()->lock();
+ }
+
+ ~PulseDaemonLocker()
+ {
+ daemon()->unlock();
+ }
+};
+}
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_pulseStream(0),
+ m_sinkInputId(-1),
+ m_emptying(false),
+ m_sampleReady(false),
+ m_playing(false),
+ m_status(QSoundEffect::Null),
+ m_muted(false),
+ m_playQueued(false),
+ m_stopping(false),
+ m_volume(100),
+ m_loopCount(1),
+ m_runningCount(0),
+ m_sample(0) ,
+ m_position(0)
+{
+ pa_sample_spec_init(&m_pulseSpec);
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+ unloadPulseStream();
+
+ if (m_sample)
+ m_sample->release();
+}
+
+QStringList QSoundEffectPrivate::supportedMimeTypes()
+{
+ QStringList supportedTypes;
+ supportedTypes << QLatin1String("audio/x-wav") << QLatin1String("audio/vnd.wave") ;
+ return supportedTypes;
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_source;
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ Q_ASSERT(m_source != url);
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "setSource =" << url;
+#endif
+ stop();
+ if (m_sample) {
+ if (!m_sampleReady) {
+ disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
+ disconnect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
+ }
+ m_sample->release();
+ m_sample = 0;
+ }
+
+ m_source = url;
+ m_sampleReady = false;
+
+ PulseDaemonLocker locker;
+ m_runningCount = 0;
+ if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) {
+ pa_stream_set_write_callback(m_pulseStream, 0, 0);
+ pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
+ pa_operation_unref(pa_stream_cork(m_pulseStream, 1, 0, 0));
+ }
+ setPlaying(false);
+
+ if (url.isEmpty()) {
+ setStatus(QSoundEffect::Null);
+ return;
+ }
+
+ setStatus(QSoundEffect::Loading);
+ m_sample = sampleCache()->requestSample(url);
+ connect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
+ connect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
+ switch(m_sample->state()) {
+ case QSample::Ready:
+ sampleReady();
+ break;
+ case QSample::Error:
+ decoderError();
+ break;
+ default:
+ break;
+ }
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int loopCount)
+{
+ if (loopCount == 0)
+ loopCount = 1;
+ m_loopCount = loopCount;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_volume;
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_volume = volume;
+ emit volumeChanged();
+ updateVolume();
+}
+
+void QSoundEffectPrivate::updateVolume()
+{
+ if (m_sinkInputId < 0)
+ return;
+ PulseDaemonLocker locker;
+ pa_cvolume volume;
+ pa_operation_unref(pa_context_set_sink_input_volume(daemon()->context(), m_sinkInputId, daemon()->calcVolume(&volume, m_volume), setvolume_callback, this));
+ Q_ASSERT(pa_cvolume_valid(&volume));
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "updateVolume =" << pa_cvolume_max(&volume);
+#endif
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+ emit mutedChanged();
+ updateMuted();
+}
+
+void QSoundEffectPrivate::updateMuted()
+{
+ if (m_sinkInputId < 0)
+ return;
+ PulseDaemonLocker locker;
+ pa_operation_unref(pa_context_set_sink_input_mute(daemon()->context(), m_sinkInputId, m_muted, setmuted_callback, this));
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "updateMuted = " << daemon()->calcMuted(m_muted);
+#endif
+}
+
+bool QSoundEffectPrivate::isLoaded() const
+{
+ return m_status == QSoundEffect::Ready;
+}
+
+bool QSoundEffectPrivate::isPlaying() const
+{
+ return m_playing;
+}
+
+QSoundEffect::Status QSoundEffectPrivate::status() const
+{
+ return m_status;
+}
+
+void QSoundEffectPrivate::setPlaying(bool playing)
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "setPlaying(" << playing << ")";
+#endif
+ if (m_playing == playing)
+ return;
+ if (!playing)
+ m_playQueued = false;
+ m_playing = playing;
+ emit playingChanged();
+}
+
+void QSoundEffectPrivate::setStatus(QSoundEffect::Status status)
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "setStatus" << status;
+#endif
+ if (m_status == status)
+ return;
+ bool oldLoaded = isLoaded();
+ m_status = status;
+ emit statusChanged();
+ if (oldLoaded != isLoaded())
+ emit loadedChanged();
+}
+
+void QSoundEffectPrivate::play()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "play";
+#endif
+ if (m_status == QSoundEffect::Null || m_status == QSoundEffect::Error || m_playQueued)
+ return;
+
+ PulseDaemonLocker locker;
+ if (!m_sampleReady || m_stopping || m_emptying) {
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "play deferred";
+#endif
+ m_playQueued = true;
+ } else {
+ if (m_playing) { //restart playing from the beginning
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "restart playing";
+#endif
+ m_runningCount = 0;
+ m_playQueued = true;
+ Q_ASSERT(m_pulseStream);
+ emptyStream();
+ return;
+ }
+ m_runningCount = m_loopCount;
+ playSample();
+ }
+
+ setPlaying(true);
+}
+
+void QSoundEffectPrivate::emptyStream()
+{
+ m_emptying = true;
+ pa_stream_set_write_callback(m_pulseStream, 0, this);
+ pa_stream_set_underflow_callback(m_pulseStream, 0, this);
+ pa_operation_unref(pa_stream_flush(m_pulseStream, stream_flush_callback, this));
+}
+
+void QSoundEffectPrivate::emptyComplete()
+{
+ PulseDaemonLocker locker;
+ m_emptying = false;
+ pa_operation_unref(pa_stream_cork(m_pulseStream, 1, stream_cork_callback, this));
+}
+
+void QSoundEffectPrivate::sampleReady()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "sampleReady";
+#endif
+ disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
+ disconnect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady()));
+ pa_sample_spec newFormatSpec = audioFormatToSampleSpec(m_sample->format());
+
+ if (m_pulseStream && (memcmp(&m_pulseSpec, &newFormatSpec, sizeof(m_pulseSpec)) != 0)) {
+ unloadPulseStream();
+ }
+ m_pulseSpec = newFormatSpec;
+
+ m_sampleReady = true;
+ m_position = 0;
+
+ if (m_name.isNull())
+ m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
+
+ PulseDaemonLocker locker;
+ if (m_pulseStream) {
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "reuse existing pulsestream";
+#endif
+#ifdef QTM_PULSEAUDIO_DEFAULTBUFFER
+ const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(m_pulseStream);
+ if (bufferAttr->prebuf > uint32_t(m_sample->data().size())) {
+ pa_buffer_attr newBufferAttr;
+ newBufferAttr = *bufferAttr;
+ newBufferAttr.prebuf = m_sample->data().size();
+ pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, this);
+ } else {
+ streamReady();
+ }
+#else
+ const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(m_pulseStream);
+ if (bufferAttr->tlength < m_sample->data().size() && bufferAttr->tlength < QT_PA_STREAM_BUFFER_SIZE_MAX) {
+ pa_buffer_attr newBufferAttr;
+ newBufferAttr.maxlength = -1;
+ newBufferAttr.tlength = qMin(m_sample->data().size(), QT_PA_STREAM_BUFFER_SIZE_MAX);
+ newBufferAttr.minreq = bufferAttr->tlength / 2;
+ newBufferAttr.prebuf = -1;
+ newBufferAttr.fragsize = -1;
+ pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_reset_buffer_callback, this);
+ } else if (bufferAttr->prebuf > uint32_t(m_sample->data().size())) {
+ pa_buffer_attr newBufferAttr;
+ newBufferAttr = *bufferAttr;
+ newBufferAttr.prebuf = m_sample->data().size();
+ pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, this);
+ } else {
+ streamReady();
+ }
+#endif
+ } else {
+ if (pa_context_get_state(daemon()->context()) != PA_CONTEXT_READY) {
+ connect(daemon(), SIGNAL(contextReady()), SLOT(contextReady()));
+ return;
+ }
+ createPulseStream();
+ }
+}
+
+void QSoundEffectPrivate::decoderError()
+{
+ qWarning("QSoundEffect(pulseaudio): Error decoding source");
+ disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
+ bool playingDirty = false;
+ if (m_playing) {
+ m_playing = false;
+ playingDirty = true;
+ }
+ setStatus(QSoundEffect::Error);
+ if (playingDirty)
+ emit playingChanged();
+}
+
+void QSoundEffectPrivate::unloadPulseStream()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "unloadPulseStream";
+#endif
+ m_sinkInputId = -1;
+ PulseDaemonLocker locker;
+ if (m_pulseStream) {
+ pa_stream_set_state_callback(m_pulseStream, 0, 0);
+ pa_stream_set_write_callback(m_pulseStream, 0, 0);
+ pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
+ pa_stream_disconnect(m_pulseStream);
+ pa_stream_unref(m_pulseStream);
+ disconnect(daemon(), SIGNAL(volumeChanged()), this, SLOT(updateVolume()));
+ m_pulseStream = 0;
+ }
+}
+
+void QSoundEffectPrivate::prepare()
+{
+ if (!m_pulseStream || !m_sampleReady)
+ return;
+ PulseDaemonLocker locker;
+ pa_stream_set_write_callback(m_pulseStream, stream_write_callback, this);
+ pa_stream_set_underflow_callback(m_pulseStream, stream_underrun_callback, this);
+ m_stopping = false;
+ size_t writeBytes = size_t(qMin(m_pulseBufferSize, m_sample->data().size()));
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "prepare(): writable size =" << pa_stream_writable_size(m_pulseStream)
+ << "actual writeBytes =" << writeBytes
+ << "m_playQueued =" << m_playQueued;
+#endif
+ m_position = int(writeBytes);
+ if (pa_stream_write(m_pulseStream, reinterpret_cast<void *>(const_cast<char*>(m_sample->data().data())), writeBytes,
+ stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) {
+ qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(daemon()->context())));
+ }
+ if (m_playQueued) {
+ m_playQueued = false;
+ m_runningCount = m_loopCount;
+ playSample();
+ }
+}
+
+void QSoundEffectPrivate::uploadSample()
+{
+ if (m_runningCount == 0) {
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "uploadSample: return due to 0 m_runningCount";
+#endif
+ return;
+ }
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "uploadSample: m_runningCount =" << m_runningCount;
+#endif
+ if (m_position == m_sample->data().size()) {
+ m_position = 0;
+ if (m_runningCount > 0)
+ m_runningCount--;
+ if (m_runningCount == 0) {
+ return;
+ }
+ }
+
+ int writtenBytes = 0;
+ int writableSize = int(pa_stream_writable_size(m_pulseStream));
+ int firstPartLength = qMin(m_sample->data().size() - m_position, writableSize);
+ if (pa_stream_write(m_pulseStream, reinterpret_cast<void *>(const_cast<char*>(m_sample->data().data()) + m_position),
+ firstPartLength, stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) {
+ qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(daemon()->context())));
+ }
+ writtenBytes = firstPartLength;
+ m_position += firstPartLength;
+ if (m_position == m_sample->data().size()) {
+ m_position = 0;
+ if (m_runningCount > 0)
+ m_runningCount--;
+ if (m_runningCount != 0 && firstPartLength < writableSize)
+ {
+ while (writtenBytes < writableSize) {
+ int writeSize = qMin(writableSize - writtenBytes, m_sample->data().size());
+ if (pa_stream_write(m_pulseStream, reinterpret_cast<void *>(const_cast<char*>(m_sample->data().data())),
+ writeSize, stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) {
+ qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(daemon()->context())));
+ }
+ writtenBytes += writeSize;
+ if (writeSize < m_sample->data().size()) {
+ m_position = writeSize;
+ break;
+ }
+ if (m_runningCount > 0)
+ m_runningCount--;
+ if (m_runningCount == 0)
+ break;
+ }
+ }
+ }
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "uploadSample: use direct write, writeable size =" << writableSize
+ << "actual writtenBytes =" << writtenBytes;
+#endif
+}
+
+void QSoundEffectPrivate::playSample()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "playSample";
+#endif
+ Q_ASSERT(m_pulseStream);
+ pa_operation_unref(pa_stream_cork(m_pulseStream, 0, 0, 0));
+}
+
+void QSoundEffectPrivate::stop()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "stop";
+#endif
+ if (!m_playing)
+ return;
+ setPlaying(false);
+ PulseDaemonLocker locker;
+ m_stopping = true;
+ if (m_pulseStream)
+ emptyStream();
+ m_runningCount = 0;
+ m_position = 0;
+ m_playQueued = false;
+}
+
+void QSoundEffectPrivate::underRun()
+{
+ stop();
+}
+
+void QSoundEffectPrivate::streamReady()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "streamReady";
+#endif
+ PulseDaemonLocker locker;
+ m_sinkInputId = pa_stream_get_index(m_pulseStream);
+ updateMuted();
+ updateVolume();
+#ifdef QT_PA_DEBUG
+ const pa_buffer_attr *realBufAttr = pa_stream_get_buffer_attr(m_pulseStream);
+ qDebug() << this << "m_sinkInputId =" << m_sinkInputId
+ << "tlength =" << realBufAttr->tlength << "maxlength =" << realBufAttr->maxlength
+ << "minreq = " << realBufAttr->minreq << "prebuf =" << realBufAttr->prebuf;
+#endif
+ prepare();
+ setStatus(QSoundEffect::Ready);
+}
+
+void QSoundEffectPrivate::createPulseStream()
+{
+#ifdef QT_PA_DEBUG
+ qDebug() << this << "createPulseStream";
+#endif
+
+ pa_proplist *propList = pa_proplist_new();
+ pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, "soundeffect");
+ pa_stream *stream = pa_stream_new_with_proplist(daemon()->context(), m_name.constData(), &m_pulseSpec, 0, propList);
+ pa_proplist_free(propList);
+
+ connect(daemon(), SIGNAL(volumeChanged()), this, SLOT(updateVolume()));
+
+ if (stream == 0) {
+ qWarning("QSoundEffect(pulseaudio): Failed to create stream");
+ m_pulseStream = 0;
+ setStatus(QSoundEffect::Error);
+ setPlaying(false);
+ return;
+ }
+ else {
+ pa_stream_set_state_callback(stream, stream_state_callback, this);
+ pa_stream_set_write_callback(stream, stream_write_callback, this);
+ pa_stream_set_underflow_callback(stream, stream_underrun_callback, this);
+ }
+ m_pulseStream = stream;
+
+#ifndef QTM_PULSEAUDIO_DEFAULTBUFFER
+ pa_buffer_attr bufferAttr;
+ bufferAttr.tlength = qMin(m_sample->data().size(), QT_PA_STREAM_BUFFER_SIZE_MAX);
+ bufferAttr.maxlength = -1;
+ bufferAttr.minreq = bufferAttr.tlength / 2;
+ bufferAttr.prebuf = -1;
+ bufferAttr.fragsize = -1;
+ if (pa_stream_connect_playback(m_pulseStream, 0, &bufferAttr,
+#else
+ if (pa_stream_connect_playback(m_pulseStream, 0, 0,
+#endif
+ m_muted ? pa_stream_flags_t(PA_STREAM_START_MUTED | PA_STREAM_START_CORKED)
+ : pa_stream_flags_t(PA_STREAM_START_UNMUTED | PA_STREAM_START_CORKED),
+ 0, 0) < 0) {
+ qWarning("QSoundEffect(pulseaudio): Failed to connect stream, error = %s",
+ pa_strerror(pa_context_errno(daemon()->context())));
+ }
+}
+
+void QSoundEffectPrivate::contextReady()
+{
+ disconnect(daemon(), SIGNAL(contextReady()), this, SLOT(contextReady()));
+ PulseDaemonLocker locker;
+ createPulseStream();
+}
+
+void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata)
+{
+ Q_UNUSED(length);
+ Q_UNUSED(s)
+
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_write_callback";
+#endif
+ self->uploadSample();
+}
+
+void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata)
+{
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_READY:
+ {
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "pulse stream ready";
+#endif
+ const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(self->m_pulseStream);
+ self->m_pulseBufferSize = bufferAttr->tlength;
+ if (bufferAttr->prebuf > uint32_t(self->m_sample->data().size())) {
+ pa_buffer_attr newBufferAttr;
+ newBufferAttr = *bufferAttr;
+ newBufferAttr.prebuf = self->m_sample->data().size();
+ pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, userdata);
+ } else {
+ QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection);
+ }
+ break;
+ }
+ case PA_STREAM_CREATING:
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "pulse stream creating";
+#endif
+ break;
+ case PA_STREAM_TERMINATED:
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "pulse stream terminated";
+#endif
+ break;
+
+ case PA_STREAM_FAILED:
+ default:
+ qWarning("QSoundEffect(pulseaudio): Error in pulse audio stream");
+ break;
+ }
+}
+
+void QSoundEffectPrivate::stream_reset_buffer_callback(pa_stream *s, int success, void *userdata)
+{
+ Q_UNUSED(s);
+ if (!success)
+ qWarning("QSoundEffect(pulseaudio): faild to reset buffer attribute");
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_reset_buffer_callback";
+#endif
+ const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(self->m_pulseStream);
+ self->m_pulseBufferSize = bufferAttr->tlength;
+ if (bufferAttr->prebuf > uint32_t(self->m_sample->data().size())) {
+ pa_buffer_attr newBufferAttr;
+ newBufferAttr = *bufferAttr;
+ newBufferAttr.prebuf = self->m_sample->data().size();
+ pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, userdata);
+ } else {
+ QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection);
+ }
+}
+
+void QSoundEffectPrivate::stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata)
+{
+ Q_UNUSED(s);
+ if (!success)
+ qWarning("QSoundEffect(pulseaudio): faild to adjust pre-buffer attribute");
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_adjust_prebuffer_callback";
+#endif
+ QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection);
+}
+
+void QSoundEffectPrivate::setvolume_callback(pa_context *c, int success, void *userdata)
+{
+ Q_UNUSED(c);
+ Q_UNUSED(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << reinterpret_cast<QSoundEffectPrivate*>(userdata) << "setvolume_callback";
+#endif
+ if (!success) {
+ qWarning("QSoundEffect(pulseaudio): faild to set volume");
+ }
+}
+
+void QSoundEffectPrivate::setmuted_callback(pa_context *c, int success, void *userdata)
+{
+ Q_UNUSED(c);
+ Q_UNUSED(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << reinterpret_cast<QSoundEffectPrivate*>(userdata) << "setmuted_callback";
+#endif
+ if (!success) {
+ qWarning("QSoundEffect(pulseaudio): faild to set muted");
+ }
+}
+
+void QSoundEffectPrivate::stream_underrun_callback(pa_stream *s, void *userdata)
+{
+ Q_UNUSED(s);
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_underrun_callback";
+#endif
+ if (self->m_runningCount == 0 && !self->m_playQueued)
+ QMetaObject::invokeMethod(self, "underRun", Qt::QueuedConnection);
+#ifdef QT_PA_DEBUG
+ else
+ qDebug() << "underun corked =" << pa_stream_is_corked(s);
+#endif
+}
+
+void QSoundEffectPrivate::stream_cork_callback(pa_stream *s, int success, void *userdata)
+{
+ Q_UNUSED(s);
+ if (!success)
+ qWarning("QSoundEffect(pulseaudio): faild to stop");
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_cork_callback";
+#endif
+ QMetaObject::invokeMethod(self, "prepare", Qt::QueuedConnection);
+}
+
+void QSoundEffectPrivate::stream_flush_callback(pa_stream *s, int success, void *userdata)
+{
+ Q_UNUSED(s);
+ if (!success)
+ qWarning("QSoundEffect(pulseaudio): faild to drain");
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+#ifdef QT_PA_DEBUG
+ qDebug() << self << "stream_flush_callback";
+#endif
+ QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection);
+}
+
+void QSoundEffectPrivate::stream_write_done_callback(void *p)
+{
+ Q_UNUSED(p);
+#ifdef QT_PA_DEBUG
+ qDebug() << "stream_write_done_callback";
+#endif
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsoundeffect_pulse_p.cpp"
+#include "qsoundeffect_pulse_p.moc"
diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.h b/src/multimedia/effects/qsoundeffect_pulse_p.h
new file mode 100644
index 000000000..c78bcdec5
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_pulse_p.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_PULSE_H
+#define QSOUNDEFFECT_PULSE_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.
+//
+
+
+#include "qsoundeffect_p.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qdatetime.h>
+#include <qmediaplayer.h>
+#include <pulse/pulseaudio.h>
+#include "qsamplecache_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ static QStringList supportedMimeTypes();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ bool isLoaded() const;
+ bool isPlaying() const;
+ QSoundEffect::Status status() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+ void loadedChanged();
+ void playingChanged();
+ void statusChanged();
+
+private Q_SLOTS:
+ void decoderError();
+ void sampleReady();
+ void uploadSample();
+ void contextReady();
+ void underRun();
+ void prepare();
+ void streamReady();
+ void emptyComplete();
+ void updateVolume();
+ void updateMuted();
+
+private:
+ void playSample();
+
+ void emptyStream();
+ void createPulseStream();
+ void unloadPulseStream();
+
+ void setPlaying(bool playing);
+ void setStatus(QSoundEffect::Status status);
+
+ static void stream_write_callback(pa_stream *s, size_t length, void *userdata);
+ static void stream_state_callback(pa_stream *s, void *userdata);
+ static void stream_underrun_callback(pa_stream *s, void *userdata);
+ static void stream_cork_callback(pa_stream *s, int success, void *userdata);
+ static void stream_flush_callback(pa_stream *s, int success, void *userdata);
+ static void stream_write_done_callback(void *p);
+ static void stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata);
+ static void stream_reset_buffer_callback(pa_stream *s, int success, void *userdata);
+ static void setvolume_callback(pa_context *c, int success, void *userdata);
+ static void setmuted_callback(pa_context *c, int success, void *userdata);
+
+ pa_stream *m_pulseStream;
+ int m_sinkInputId;
+ pa_sample_spec m_pulseSpec;
+ int m_pulseBufferSize;
+
+ bool m_emptying;
+ bool m_sampleReady;
+ bool m_playing;
+ QSoundEffect::Status m_status;
+ bool m_muted;
+ bool m_playQueued;
+ bool m_stopping;
+ int m_volume;
+ int m_loopCount;
+ int m_runningCount;
+ QUrl m_source;
+ QByteArray m_name;
+
+ QSample *m_sample;
+ int m_position;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_PULSE_H
diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp
new file mode 100644
index 000000000..dfd56b09c
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include "qsoundeffect_qmedia_p.h"
+
+#include <QtCore/qcoreapplication.h>
+
+#include "qmediacontent.h"
+#include "qmediaplayer.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_loopCount(1),
+ m_runningCount(0),
+ m_player(0),
+ m_status(QSoundEffect::Null),
+ m_playing(false)
+{
+ m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency);
+ connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(stateChanged(QMediaPlayer::State)));
+ connect(m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(m_player, SIGNAL(error(QMediaPlayer::Error)), SLOT(error(QMediaPlayer::Error)));
+ connect(m_player, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged()));
+ connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged()));
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+}
+
+QStringList QSoundEffectPrivate::supportedMimeTypes()
+{
+ return QMediaPlayer::supportedMimeTypes();
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_player->media().canonicalUrl();
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ m_player->setMedia(url);
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int loopCount)
+{
+ m_loopCount = loopCount;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_player->volume();
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_player->setVolume(volume);
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_player->isMuted();
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_player->setMuted(muted);
+}
+
+bool QSoundEffectPrivate::isLoaded() const
+{
+ return m_status == QSoundEffect::Ready;
+}
+
+bool QSoundEffectPrivate::isPlaying() const
+{
+ return m_playing;
+}
+
+QSoundEffect::Status QSoundEffectPrivate::status() const
+{
+ return m_status;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_status == QSoundEffect::Null || m_status == QSoundEffect::Error)
+ return;
+ if (m_loopCount < 0) {
+ m_runningCount = -1;
+ }
+ else {
+ if (m_runningCount < 0)
+ m_runningCount = 0;
+ m_runningCount += m_loopCount;
+ }
+ m_player->play();
+}
+
+void QSoundEffectPrivate::stop()
+{
+ m_runningCount = 0;
+ m_player->stop();
+}
+
+void QSoundEffectPrivate::stateChanged(QMediaPlayer::State state)
+{
+ if (state == QMediaPlayer::StoppedState) {
+ if (m_runningCount < 0) {
+ m_player->play();
+ } else if (m_runningCount == 0) {
+ setPlaying(false);
+ return;
+ } else if (--m_runningCount > 0) {
+ m_player->play();
+ } else {
+ setPlaying(false);
+ }
+ } else {
+ setPlaying(true);
+ }
+}
+
+void QSoundEffectPrivate::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+{
+ switch(status) {
+ case QMediaPlayer::LoadingMedia:
+ setStatus(QSoundEffect::Loading);
+ break;
+ case QMediaPlayer::NoMedia:
+ setStatus(QSoundEffect::Null);
+ break;
+ case QMediaPlayer::InvalidMedia:
+ setStatus(QSoundEffect::Error);
+ break;
+ default:
+ setStatus(QSoundEffect::Ready);
+ break;
+ }
+}
+
+void QSoundEffectPrivate::error(QMediaPlayer::Error err)
+{
+ bool playingDirty = false;
+ if (m_playing) {
+ m_playing = false;
+ playingDirty = true;
+ }
+ setStatus(QSoundEffect::Error);
+ if (playingDirty)
+ emit playingChanged();
+}
+
+void QSoundEffectPrivate::setStatus(QSoundEffect::Status status)
+{
+ if (m_status == status)
+ return;
+ bool oldLoaded = isLoaded();
+ m_status = status;
+ emit statusChanged();
+ if (oldLoaded != isLoaded())
+ emit loadedChanged();
+}
+
+void QSoundEffectPrivate::setPlaying(bool playing)
+{
+ if (m_playing == playing)
+ return;
+ m_playing = playing;
+ emit playingChanged();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsoundeffect_qmedia_p.cpp"
diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.h b/src/multimedia/effects/qsoundeffect_qmedia_p.h
new file mode 100644
index 000000000..adafa04a2
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_qmedia_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_QMEDIA_H
+#define QSOUNDEFFECT_QMEDIA_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.
+//
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include "qmediaplayer.h"
+#include "qsoundeffect_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ static QStringList supportedMimeTypes();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ bool isLoaded() const;
+ bool isPlaying() const;
+ QSoundEffect::Status status() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+ void loadedChanged();
+ void playingChanged();
+ void statusChanged();
+
+private Q_SLOTS:
+ void stateChanged(QMediaPlayer::State);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus);
+ void error(QMediaPlayer::Error);
+
+private:
+ void setStatus(QSoundEffect::Status status);
+ void setPlaying(bool playing);
+
+ int m_loopCount;
+ int m_runningCount;
+ bool m_playing;
+ QSoundEffect::Status m_status;
+ QMediaPlayer *m_player;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QMEDIA_H
diff --git a/src/multimedia/effects/qsoundeffect_qsound_p.cpp b/src/multimedia/effects/qsoundeffect_qsound_p.cpp
new file mode 100644
index 000000000..0b9082eb5
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_qsound_p.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+// INTERNAL USE ONLY: Do NOT use for any other purpose.
+//
+
+#include "qsoundeffect_qsound_p.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtWidgets/qsound.h>
+#include <QtCore/qstringlist.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_playing(false),
+ m_timerID(0),
+ m_muted(false),
+ m_loopCount(1),
+ m_volume(100),
+ m_status(QSoundEffect::Null),
+ m_sound(0)
+{
+ if (!QSound::isAvailable())
+ qWarning("SoundEffect(qsound) : not available");
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+}
+
+QStringList QSoundEffectPrivate::supportedMimeTypes()
+{
+ QStringList supportedTypes;
+ supportedTypes << QLatin1String("audio/x-wav") << QLatin1String("audio/vnd.wave") ;
+ return supportedTypes;
+}
+
+QUrl QSoundEffectPrivate::source() const
+{
+ return m_source;
+}
+
+void QSoundEffectPrivate::setSource(const QUrl &url)
+{
+ if (url.isEmpty()) {
+ m_source = QUrl();
+ setStatus(QSoundEffect::Null);
+ return;
+ }
+
+ if (url.scheme() != QLatin1String("file")) {
+ m_source = url;
+ setStatus(QSoundEffect::Error);
+ return;
+ }
+
+ if (m_sound != 0)
+ delete m_sound;
+
+ m_source = url;
+ m_sound = new QSound(m_source.toLocalFile(), this);
+ m_sound->setLoops(m_loopCount);
+ m_status = QSoundEffect::Ready;
+ emit statusChanged();
+ emit loadedChanged();
+}
+
+int QSoundEffectPrivate::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffectPrivate::setLoopCount(int lc)
+{
+ m_loopCount = lc;
+ if (m_sound)
+ m_sound->setLoops(lc);
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_volume;
+}
+
+void QSoundEffectPrivate::setVolume(int v)
+{
+ m_volume = v;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+}
+
+bool QSoundEffectPrivate::isLoaded() const
+{
+ return m_status == QSoundEffect::Ready;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_status == QSoundEffect::Null || m_status == QSoundEffect::Error)
+ return;
+ if (m_timerID != 0)
+ killTimer(m_timerID);
+ m_timerID = startTimer(500);
+ m_sound->play();
+ setPlaying(true);
+}
+
+
+void QSoundEffectPrivate::stop()
+{
+ if (m_timerID != 0)
+ killTimer(m_timerID);
+ m_timerID = 0;
+ m_sound->stop();
+ setPlaying(false);
+}
+
+bool QSoundEffectPrivate::isPlaying()
+{
+ if (m_playing && m_sound && m_sound->isFinished()) {
+ if (m_timerID != 0)
+ killTimer(m_timerID);
+ m_timerID = 0;
+ setPlaying(false);
+ }
+ return m_playing;
+}
+
+QSoundEffect::Status QSoundEffectPrivate::status() const
+{
+ return m_status;
+}
+
+void QSoundEffectPrivate::timerEvent(QTimerEvent *event)
+{
+ Q_UNUSED(event);
+ setPlaying(!m_sound->isFinished());
+ if (isPlaying())
+ return;
+ killTimer(m_timerID);
+ m_timerID = 0;
+}
+
+void QSoundEffectPrivate::setStatus(QSoundEffect::Status status)
+{
+ if (m_status == status)
+ return;
+ bool oldLoaded = isLoaded();
+ m_status = status;
+ emit statusChanged();
+ if (oldLoaded != isLoaded())
+ emit loadedChanged();
+}
+
+void QSoundEffectPrivate::setPlaying(bool playing)
+{
+ if (m_playing == playing)
+ return;
+ m_playing = playing;
+ emit playingChanged();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsoundeffect_qsound_p.cpp"
diff --git a/src/multimedia/effects/qsoundeffect_qsound_p.h b/src/multimedia/effects/qsoundeffect_qsound_p.h
new file mode 100644
index 000000000..c98ad79ce
--- /dev/null
+++ b/src/multimedia/effects/qsoundeffect_qsound_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_QSOUND_H
+#define QSOUNDEFFECT_QSOUND_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.
+//
+
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include "qsoundeffect_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QSound;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ static QStringList supportedMimeTypes();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ bool isLoaded() const;
+ bool isPlaying();
+ QSoundEffect::Status status() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+Q_SIGNALS:
+ void volumeChanged();
+ void mutedChanged();
+ void loadedChanged();
+ void playingChanged();
+ void statusChanged();
+
+private:
+ void setStatus(QSoundEffect::Status status);
+ void setPlaying(bool playing);
+ void timerEvent(QTimerEvent *event);
+
+ bool m_playing;
+ int m_timerID;
+ bool m_muted;
+ int m_loopCount;
+ int m_volume;
+ QSoundEffect::Status m_status;
+ QSound *m_sound;
+ QUrl m_source;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QSOUND_H
diff --git a/src/multimedia/effects/qwavedecoder_p.cpp b/src/multimedia/effects/qwavedecoder_p.cpp
new file mode 100644
index 000000000..19b262adc
--- /dev/null
+++ b/src/multimedia/effects/qwavedecoder_p.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwavedecoder_p.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qendian.h>
+
+QT_BEGIN_NAMESPACE
+
+QWaveDecoder::QWaveDecoder(QIODevice *s, QObject *parent):
+ QIODevice(parent),
+ haveFormat(false),
+ dataSize(0),
+ remaining(0),
+ source(s),
+ state(QWaveDecoder::InitialState)
+{
+ open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ if (enoughDataAvailable())
+ QTimer::singleShot(0, this, SLOT(handleData()));
+ else
+ connect(source, SIGNAL(readyRead()), SLOT(handleData()));
+}
+
+QWaveDecoder::~QWaveDecoder()
+{
+}
+
+QAudioFormat QWaveDecoder::audioFormat() const
+{
+ return format;
+}
+
+int QWaveDecoder::duration() const
+{
+ return size() * 1000 / (format.sampleSize() / 8) / format.channels() / format.frequency();
+}
+
+qint64 QWaveDecoder::size() const
+{
+ return haveFormat ? dataSize : 0;
+}
+
+bool QWaveDecoder::isSequential() const
+{
+ return source->isSequential();
+}
+
+qint64 QWaveDecoder::bytesAvailable() const
+{
+ return haveFormat ? source->bytesAvailable() : 0;
+}
+
+qint64 QWaveDecoder::readData(char *data, qint64 maxlen)
+{
+ return haveFormat ? source->read(data, maxlen) : 0;
+}
+
+qint64 QWaveDecoder::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return -1;
+}
+
+void QWaveDecoder::handleData()
+{
+ if (state == QWaveDecoder::InitialState) {
+ if (source->bytesAvailable() < qint64(sizeof(RIFFHeader)))
+ return;
+
+ RIFFHeader riff;
+ source->read(reinterpret_cast<char *>(&riff), sizeof(RIFFHeader));
+
+ if (qstrncmp(riff.descriptor.id, "RIFF", 4) != 0 ||
+ qstrncmp(riff.type, "WAVE", 4) != 0) {
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+ emit invalidFormat();
+
+ return;
+ } else {
+ state = QWaveDecoder::WaitingForFormatState;
+ }
+ }
+
+ if (state == QWaveDecoder::WaitingForFormatState) {
+ if (findChunk("fmt ")) {
+ chunk descriptor;
+ source->peek(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
+
+ if (source->bytesAvailable() < qint64(descriptor.size + sizeof(chunk)))
+ return;
+
+ WAVEHeader wave;
+ source->read(reinterpret_cast<char *>(&wave), sizeof(WAVEHeader));
+ if (descriptor.size > sizeof(WAVEHeader))
+ discardBytes(descriptor.size - sizeof(WAVEHeader));
+
+ if (wave.audioFormat != 0 && wave.audioFormat != 1) {
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+ emit invalidFormat();
+
+ return;
+ } else {
+ int bps = qFromLittleEndian<quint16>(wave.bitsPerSample);
+
+ format.setCodec(QLatin1String("audio/pcm"));
+ format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setFrequency(qFromLittleEndian<quint32>(wave.sampleRate));
+ format.setSampleSize(bps);
+ format.setChannels(qFromLittleEndian<quint16>(wave.numChannels));
+
+ state = QWaveDecoder::WaitingForDataState;
+ }
+ }
+ }
+
+ if (state == QWaveDecoder::WaitingForDataState) {
+ if (findChunk("data")) {
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+
+ chunk descriptor;
+ source->read(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
+ dataSize = descriptor.size;
+
+ haveFormat = true;
+ connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ emit formatKnown();
+
+ return;
+ }
+ }
+
+ if (source->atEnd()) {
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+ emit invalidFormat();
+
+ return;
+ }
+
+}
+
+bool QWaveDecoder::enoughDataAvailable()
+{
+ if (source->bytesAvailable() < qint64(sizeof(chunk)))
+ return false;
+
+ chunk descriptor;
+ source->peek(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
+
+ if (source->bytesAvailable() < qint64(sizeof(chunk) + descriptor.size))
+ return false;
+
+ return true;
+}
+
+bool QWaveDecoder::findChunk(const char *chunkId)
+{
+ if (source->bytesAvailable() < qint64(sizeof(chunk)))
+ return false;
+
+ chunk descriptor;
+ source->peek(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
+
+ if (qstrncmp(descriptor.id, chunkId, 4) == 0)
+ return true;
+
+ while (source->bytesAvailable() >= qint64(sizeof(chunk) + descriptor.size)) {
+ discardBytes(sizeof(chunk) + descriptor.size);
+
+ source->peek(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
+
+ if (qstrncmp(descriptor.id, chunkId, 4) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+void QWaveDecoder::discardBytes(qint64 numBytes)
+{
+ if (source->isSequential())
+ source->read(numBytes);
+ else
+ source->seek(source->pos() + numBytes);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwavedecoder_p.cpp"
diff --git a/src/multimedia/effects/qwavedecoder_p.h b/src/multimedia/effects/qwavedecoder_p.h
new file mode 100644
index 000000000..6c4c00c25
--- /dev/null
+++ b/src/multimedia/effects/qwavedecoder_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WAVEDECODER_H
+#define WAVEDECODER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qiodevice.h>
+#include <qaudioformat.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QWaveDecoder : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ explicit QWaveDecoder(QIODevice *source, QObject *parent = 0);
+ ~QWaveDecoder();
+
+ QAudioFormat audioFormat() const;
+ int duration() const;
+
+ qint64 size() const;
+ bool isSequential() const;
+ qint64 bytesAvailable() const;
+
+Q_SIGNALS:
+ void formatKnown();
+ void invalidFormat();
+
+private Q_SLOTS:
+ void handleData();
+
+private:
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ bool enoughDataAvailable();
+ bool findChunk(const char *chunkId);
+ void discardBytes(qint64 numBytes);
+
+ enum State {
+ InitialState,
+ WaitingForFormatState,
+ WaitingForDataState
+ };
+
+ struct chunk
+ {
+ char id[4];
+ quint32 size;
+ };
+ struct RIFFHeader
+ {
+ chunk descriptor;
+ char type[4];
+ };
+ struct WAVEHeader
+ {
+ chunk descriptor;
+ quint16 audioFormat;
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+ };
+
+ bool haveFormat;
+ qint64 dataSize;
+ qint64 remaining;
+ QAudioFormat format;
+ QIODevice *source;
+ State state;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // WAVEDECODER_H
diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro
new file mode 100644
index 000000000..b955e71a0
--- /dev/null
+++ b/src/multimedia/multimedia.pro
@@ -0,0 +1,156 @@
+load(qt_module)
+
+TARGET = QtMultimedia
+QPRO_PWD = $$PWD
+QT = core network gui
+
+CONFIG += module
+MODULE_PRI += ../../modules/qt_multimedia.pri
+
+contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) {
+} else {
+ DEFINES += QT_NO_OPENGL
+}
+
+!static:DEFINES += QT_MAKEDLL
+DEFINES += QT_BUILD_MULTIMEDIA_LIB
+
+load(qt_module_config)
+
+HEADERS += qtmultimediaversion.h
+
+
+PRIVATE_HEADERS += \
+ qmediacontrol_p.h \
+ qmediaobject_p.h \
+ qmediaservice_p.h \
+ qmediaplaylist_p.h \
+ qmediaplaylistprovider_p.h \
+ qmediaimageviewerservice_p.h \
+ qmediapluginloader_p.h \
+ qvideosurfaceoutput_p.h
+
+PUBLIC_HEADERS += \
+ qmediacontrol.h \
+ qmediaobject.h \
+ qmediaservice.h \
+ qmediabindableinterface.h \
+ qlocalmediaplaylistprovider.h \
+ qmediaimageviewer.h \
+ qmediaplayer.h \
+ qmediaplayercontrol.h \
+ qmediaplaylist.h \
+ qmediaplaylistnavigator.h \
+ qmediaplaylistprovider.h \
+ qmediaplaylistioplugin.h \
+ qmediabackgroundplaybackcontrol.h \
+ qmediacontent.h \
+ qmediaresource.h \
+ qmediarecorder.h \
+ qmediaencodersettings.h \
+ qmediarecordercontrol.h \
+ qmediaserviceprovider.h \
+ qmediaserviceproviderplugin.h \
+ qmetadatareadercontrol.h \
+ qmetadatawritercontrol.h \
+ qmediastreamscontrol.h \
+ qradiotuner.h \
+ qradiotunercontrol.h \
+ qtmedianamespace.h \
+ qaudioencodercontrol.h \
+ qvideoencodercontrol.h \
+ qimageencodercontrol.h \
+ qaudiocapturesource.h \
+ qmediacontainercontrol.h \
+ qmediaplaylistcontrol.h \
+ qmediaplaylistsourcecontrol.h \
+ qaudioendpointselector.h \
+ qvideodevicecontrol.h \
+ qvideorenderercontrol.h \
+ qmediatimerange.h \
+ qmedianetworkaccesscontrol.h \
+ qmediaenumdebug.h \
+ qtmultimediadefs.h
+
+SOURCES += qmediacontrol.cpp \
+ qmediaobject.cpp \
+ qmediaservice.cpp \
+ qmediabindableinterface.cpp \
+ qlocalmediaplaylistprovider.cpp \
+ qmediaimageviewer.cpp \
+ qmediaimageviewerservice.cpp \
+ qmediaplayer.cpp \
+ qmediaplayercontrol.cpp \
+ qmediaplaylist.cpp \
+ qmediaplaylistioplugin.cpp \
+ qmediaplaylistnavigator.cpp \
+ qmediaplaylistprovider.cpp \
+ qmediarecorder.cpp \
+ qmediaencodersettings.cpp \
+ qmediarecordercontrol.cpp \
+ qmediacontent.cpp \
+ qmediaresource.cpp \
+ qmediaserviceprovider.cpp \
+ qmetadatareadercontrol.cpp \
+ qmetadatawritercontrol.cpp \
+ qmediastreamscontrol.cpp \
+ qradiotuner.cpp \
+ qradiotunercontrol.cpp \
+ qaudioencodercontrol.cpp \
+ qvideoencodercontrol.cpp \
+ qimageencodercontrol.cpp \
+ qaudiocapturesource.cpp \
+ qmediacontainercontrol.cpp \
+ qmediaplaylistcontrol.cpp \
+ qmediaplaylistsourcecontrol.cpp \
+ qaudioendpointselector.cpp \
+ qvideodevicecontrol.cpp \
+ qmediapluginloader.cpp \
+ qvideorenderercontrol.cpp \
+ qmediatimerange.cpp \
+ qmedianetworkaccesscontrol.cpp \
+ qvideosurfaceoutput.cpp \
+ qmediabackgroundplaybackcontrol.cpp
+
+#Camera
+PUBLIC_HEADERS += \
+ qcamera.h \
+ qcameraimagecapture.h \
+ qcameraimagecapturecontrol.h \
+ qcameraexposure.h \
+ qcamerafocus.h \
+ qcameraimageprocessing.h \
+ qcameracontrol.h \
+ qcameralockscontrol.h \
+ qcameraexposurecontrol.h \
+ qcamerafocuscontrol.h \
+ qcameraflashcontrol.h \
+ qcameraimageprocessingcontrol.h \
+ qcameracapturedestinationcontrol.h \
+ qcameracapturebufferformatcontrol.h
+
+SOURCES += \
+ qcamera.cpp \
+ qcameraexposure.cpp \
+ qcamerafocus.cpp \
+ qcameraimageprocessing.cpp \
+ qcameraimagecapture.cpp \
+ qcameraimagecapturecontrol.cpp \
+ qcameracontrol.cpp \
+ qcameralockscontrol.cpp \
+ qcameraexposurecontrol.cpp \
+ qcamerafocuscontrol.cpp \
+ qcameraflashcontrol.cpp \
+ qcameraimageprocessingcontrol.cpp \
+ qcameracapturedestinationcontrol.cpp \
+ qcameracapturebufferformatcontrol.cpp
+
+include(audio/audio.pri)
+include(video/video.pri)
+include(effects/effects.pri)
+
+mac:!qpa {
+ LIBS += -framework AppKit -framework QuartzCore -framework QTKit
+}
+
+HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
diff --git a/src/multimedia/qaudiocapturesource.cpp b/src/multimedia/qaudiocapturesource.cpp
new file mode 100644
index 000000000..469617123
--- /dev/null
+++ b/src/multimedia/qaudiocapturesource.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaobject_p.h"
+#include <qaudiocapturesource.h>
+#include "qaudioendpointselector.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAudioCaptureSource
+ \brief The QAudioCaptureSource class provides an interface to query and select an audio input endpoint.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ QAudioCaptureSource provides access to the audio inputs available on your system.
+
+ You can query these inputs and select one to use.
+
+ A typical implementation example:
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Audio capture source
+
+ The audiocapturesource interface is then used to:
+
+ - Get and Set the audio input to use.
+
+ The capture interface is then used to:
+
+ - Set the destination using setOutputLocation()
+
+ - Set the format parameters using setAudioCodec(),
+
+ - Control the recording using record(),stop()
+
+ \sa QMediaRecorder
+*/
+
+class QAudioCaptureSourcePrivate : public QMediaObjectPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QAudioCaptureSource)
+
+ void initControls()
+ {
+ Q_Q(QAudioCaptureSource);
+
+ if (service != 0)
+ audioEndpointSelector = qobject_cast<QAudioEndpointSelector*>(service->requestControl(QAudioEndpointSelector_iid));
+
+ if (audioEndpointSelector) {
+ q->connect(audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)),
+ SIGNAL(activeAudioInputChanged(const QString&)));
+ q->connect(audioEndpointSelector, SIGNAL(availableEndpointsChanged()),
+ SIGNAL(availableAudioInputsChanged()));
+ q->connect(audioEndpointSelector, SIGNAL(availableEndpointsChanged()),
+ SLOT(statusChanged()));
+ errorState = QtMultimedia::NoError;
+ }
+ }
+
+ QAudioCaptureSourcePrivate():provider(0), audioEndpointSelector(0), errorState(QtMultimedia::ServiceMissingError) {}
+ QMediaServiceProvider *provider;
+ QAudioEndpointSelector *audioEndpointSelector;
+ QtMultimedia::AvailabilityError errorState;
+};
+
+/*!
+ Construct a QAudioCaptureSource using the QMediaService from \a provider, with \a parent.
+ \since 1.0
+*/
+
+QAudioCaptureSource::QAudioCaptureSource(QObject *parent, QMediaServiceProvider *provider):
+ QMediaObject(*new QAudioCaptureSourcePrivate, parent, provider->requestService(Q_MEDIASERVICE_AUDIOSOURCE))
+{
+ Q_D(QAudioCaptureSource);
+
+ d->provider = provider;
+ d->initControls();
+}
+
+/*!
+ Destroys the audiocapturesource object.
+*/
+
+QAudioCaptureSource::~QAudioCaptureSource()
+{
+ Q_D(QAudioCaptureSource);
+
+ if (d->service && d->audioEndpointSelector)
+ d->service->releaseControl(d->audioEndpointSelector);
+
+ if (d->provider)
+ d->provider->releaseService(d->service);
+}
+
+/*!
+ Returns the error state of the audio capture service.
+ \since 1.0
+*/
+
+QtMultimedia::AvailabilityError QAudioCaptureSource::availabilityError() const
+{
+ Q_D(const QAudioCaptureSource);
+
+ return d->errorState;
+}
+
+/*!
+ Returns true if the audio capture service is available, otherwise returns false.
+ \since 1.0
+*/
+bool QAudioCaptureSource::isAvailable() const
+{
+ Q_D(const QAudioCaptureSource);
+
+ if (d->service != NULL) {
+ if (d->audioEndpointSelector && d->audioEndpointSelector->availableEndpoints().size() > 0)
+ return true;
+ }
+ return false;
+}
+
+
+/*!
+ Returns a list of available audio inputs
+ \since 1.0
+*/
+
+QList<QString> QAudioCaptureSource::audioInputs() const
+{
+ Q_D(const QAudioCaptureSource);
+
+ QList<QString> list;
+ if (d && d->audioEndpointSelector)
+ list <<d->audioEndpointSelector->availableEndpoints();
+
+ return list;
+}
+
+/*!
+ Returns the description of the audio input device with \a name.
+ \since 1.0
+*/
+
+QString QAudioCaptureSource::audioDescription(const QString& name) const
+{
+ Q_D(const QAudioCaptureSource);
+
+ if(d->audioEndpointSelector)
+ return d->audioEndpointSelector->endpointDescription(name);
+ else
+ return QString();
+}
+
+/*!
+ Returns the default audio input name.
+ \since 1.0
+*/
+
+QString QAudioCaptureSource::defaultAudioInput() const
+{
+ Q_D(const QAudioCaptureSource);
+
+ if(d->audioEndpointSelector)
+ return d->audioEndpointSelector->defaultEndpoint();
+ else
+ return QString();
+}
+
+/*!
+ Returns the active audio input name.
+ \since 1.0
+*/
+
+QString QAudioCaptureSource::activeAudioInput() const
+{
+ Q_D(const QAudioCaptureSource);
+
+ if(d->audioEndpointSelector)
+ return d->audioEndpointSelector->activeEndpoint();
+ else
+ return QString();
+}
+
+/*!
+ Set the active audio input to \a name.
+ \since 1.0
+*/
+
+void QAudioCaptureSource::setAudioInput(const QString& name)
+{
+ Q_D(const QAudioCaptureSource);
+
+ if(d->audioEndpointSelector)
+ return d->audioEndpointSelector->setActiveEndpoint(name);
+}
+
+/*!
+ \fn QAudioCaptureSource::activeAudioInputChanged(const QString& name)
+
+ Signal emitted when active audio input changes to \a name.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioCaptureSource::availableAudioInputsChanged()
+
+ Signal is emitted when the available audio inputs change.
+ \since 1.0
+*/
+
+/*!
+ \internal
+ \since 1.0
+*/
+void QAudioCaptureSource::statusChanged()
+{
+ Q_D(QAudioCaptureSource);
+
+ if (d->audioEndpointSelector) {
+ if (d->audioEndpointSelector->availableEndpoints().size() > 0) {
+ d->errorState = QtMultimedia::NoError;
+ emit availabilityChanged(true);
+ } else {
+ d->errorState = QtMultimedia::BusyError;
+ emit availabilityChanged(false);
+ }
+ } else {
+ d->errorState = QtMultimedia::ServiceMissingError;
+ emit availabilityChanged(false);
+ }
+}
+
+#include "moc_qaudiocapturesource.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qaudiocapturesource.h b/src/multimedia/qaudiocapturesource.h
new file mode 100644
index 000000000..1571b4e8a
--- /dev/null
+++ b/src/multimedia/qaudiocapturesource.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAUDIOCAPTURESOURCE_H
+#define QAUDIOCAPTURESOURCE_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qsize.h>
+
+#include <qaudioformat.h>
+
+#include "qmediarecorder.h"
+#include "qmediacontrol.h"
+#include "qmediaobject.h"
+#include "qmediaservice.h"
+
+#include "qmediaserviceprovider.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioCaptureSourcePrivate;
+
+class Q_MULTIMEDIA_EXPORT QAudioCaptureSource : public QMediaObject
+{
+ Q_OBJECT
+
+public:
+ QAudioCaptureSource(QObject *parent = 0, QMediaServiceProvider *service = QMediaServiceProvider::defaultServiceProvider());
+ ~QAudioCaptureSource();
+
+ bool isAvailable() const;
+ QtMultimedia::AvailabilityError availabilityError() const;
+
+ QList<QString> audioInputs() const;
+
+ QString audioDescription(const QString& name) const;
+ QString defaultAudioInput() const;
+ QString activeAudioInput() const;
+
+public Q_SLOTS:
+ void setAudioInput(const QString& name);
+
+Q_SIGNALS:
+ void activeAudioInputChanged(const QString& name);
+ void availableAudioInputsChanged();
+
+private Q_SLOTS:
+ void statusChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QAudioCaptureSource)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QAUDIOCAPTURESOURCE_H
diff --git a/src/multimedia/qaudioencodercontrol.cpp b/src/multimedia/qaudioencodercontrol.cpp
new file mode 100644
index 000000000..62fa89371
--- /dev/null
+++ b/src/multimedia/qaudioencodercontrol.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudioencodercontrol.h"
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QAudioEncoderControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ \brief The QAudioEncoderControl class provides access to the settings of a
+ media service that performs audio encoding.
+
+ If a QMediaService supports encoding audio data it will implement
+ QAudioEncoderControl. This control provides information about the limits
+ of restricted audio encoder options and allows the selection of a set of
+ audio encoder settings as specified in a QAudioEncoderSettings object.
+
+ The functionality provided by this control is exposed to application code through the
+ QMediaRecorder class.
+
+ The interface name of QAudioEncoderControl is \c com.nokia.Qt.QAudioEncoderControl/1.0 as
+ defined in QAudioEncoderControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaRecorder
+*/
+
+/*!
+ \macro QAudioEncoderControl_iid
+
+ \c com.nokia.Qt.AudioEncoderControl/1.0
+
+ Defines the interface name of the QAudioEncoderControl class.
+
+ \relates QAudioEncoderControl
+*/
+
+/*!
+ Create a new audio encode control object with the given \a parent.
+*/
+QAudioEncoderControl::QAudioEncoderControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys the audio encode control.
+*/
+QAudioEncoderControl::~QAudioEncoderControl()
+{
+}
+
+/*!
+ \fn QAudioEncoderControl::supportedAudioCodecs() const
+
+ Returns the list of supported audio codec names.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::codecDescription(const QString &codec) const
+
+ Returns description of audio \a codec.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::supportedSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(),
+ bool *continuous) const
+
+ Returns the list of supported audio sample rates, if known.
+
+ If non null audio \a settings parameter is passed,
+ the returned list is reduced to sample rates supported with partial settings applied.
+
+ It can be used for example to query the list of sample rates, supported by specific audio codec.
+
+ If the encoder supports arbitrary sample rates within the supported rates range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::supportedEncodingOptions(const QString &codec) const
+
+ Returns the list of \a codec specific audio encoding options.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::encodingOption(const QString &codec, const QString &option) const
+
+ Returns the value of audio encoding \a option for \a codec.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::setEncodingOption(const QString &codec, const QString &option, const QVariant &value)
+
+ Set the \a codec specific \a option to \a value.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::audioSettings() const
+
+ Returns the audio encoder settings.
+
+ The returned value may be different tha passed to QAudioEncoderControl::setAudioSettings()
+ if the settings contains the default or undefined parameters.
+ In this case if the undefined parameters are already resolved, they should be returned.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings)
+
+ Sets the selected audio \a settings.
+ \since 1.0
+*/
+
+#include "moc_qaudioencodercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qaudioencodercontrol.h b/src/multimedia/qaudioencodercontrol.h
new file mode 100644
index 000000000..2e3a4bf87
--- /dev/null
+++ b/src/multimedia/qaudioencodercontrol.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAUDIOENCODERCONTROL_H
+#define QAUDIOENCODERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediarecorder.h"
+#include <QtCore/qlist.h>
+#include <QtCore/qpair.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QStringList;
+class QAudioFormat;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QAudioEncoderControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QAudioEncoderControl();
+
+ virtual QStringList supportedAudioCodecs() const = 0;
+ virtual QString codecDescription(const QString &codecName) const = 0;
+
+ virtual QList<int> supportedSampleRates(const QAudioEncoderSettings &settings,
+ bool *continuous = 0) const = 0;
+
+ virtual QAudioEncoderSettings audioSettings() const = 0;
+ virtual void setAudioSettings(const QAudioEncoderSettings&) = 0;
+
+ virtual QStringList supportedEncodingOptions(const QString &codec) const = 0;
+ virtual QVariant encodingOption(const QString &codec, const QString &name) const = 0;
+ virtual void setEncodingOption(
+ const QString &codec, const QString &name, const QVariant &value) = 0;
+
+protected:
+ QAudioEncoderControl(QObject *parent = 0);
+};
+
+#define QAudioEncoderControl_iid "com.nokia.Qt.QAudioEncoderControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QAudioEncoderControl, QAudioEncoderControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QAUDIOCAPTUREPROPERTIESCONTROL_H
diff --git a/src/multimedia/qaudioendpointselector.cpp b/src/multimedia/qaudioendpointselector.cpp
new file mode 100644
index 000000000..ba02c8d15
--- /dev/null
+++ b/src/multimedia/qaudioendpointselector.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudioendpointselector.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAudioEndpointSelector
+
+ \brief The QAudioEndpointSelector class provides an audio endpoint selector media control.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ The QAudioEndpointSelector class provides descriptions of the audio
+ endpoints available on a system and allows one to be selected as the audio
+ of a media service.
+
+ The interface name of QAudioEndpointSelector is \c com.nokia.Qt.QAudioEndpointSelector/1.0 as
+ defined in QAudioEndpointSelector_iid.
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ \macro QAudioEndpointSelector_iid
+
+ \c com.nokia.Qt.QAudioEndpointSelector/1.0
+
+ Defines the interface name of the QAudioEndpointSelector class.
+
+ \relates QAudioEndpointSelector
+*/
+
+/*!
+ Constructs a new audio endpoint selector with the given \a parent.
+*/
+QAudioEndpointSelector::QAudioEndpointSelector(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys an audio endpoint selector.
+*/
+QAudioEndpointSelector::~QAudioEndpointSelector()
+{
+}
+
+/*!
+ \fn QList<QString> QAudioEndpointSelector::availableEndpoints() const
+
+ Returns a list of the names of the available audio endpoints.
+ \since 1.0
+*/
+
+/*!
+ \fn QString QAudioEndpointSelector::endpointDescription(const QString& name) const
+
+ Returns the description of the endpoint \a name.
+ \since 1.0
+*/
+
+/*!
+ \fn QString QAudioEndpointSelector::defaultEndpoint() const
+
+ Returns the name of the default audio endpoint.
+ \since 1.0
+*/
+
+/*!
+ \fn QString QAudioEndpointSelector::activeEndpoint() const
+
+ Returns the name of the currently selected audio endpoint.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEndpointSelector::setActiveEndpoint(const QString& name)
+
+ Set the active audio endpoint to \a name.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEndpointSelector::activeEndpointChanged(const QString& name)
+
+ Signals that the audio endpoint has changed to \a name.
+ \since 1.0
+*/
+
+/*!
+ \fn QAudioEndpointSelector::availableEndpointsChanged()
+
+ Signals that list of available endpoints has changed.
+ \since 1.0
+*/
+
+#include "moc_qaudioendpointselector.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qaudioendpointselector.h b/src/multimedia/qaudioendpointselector.h
new file mode 100644
index 000000000..00250bc54
--- /dev/null
+++ b/src/multimedia/qaudioendpointselector.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAUDIOENDPOINTSELECTOR_H
+#define QAUDIOENDPOINTSELECTOR_H
+
+#include <qaudio.h>
+#include <qmediacontrol.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QAudioEndpointSelector : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QAudioEndpointSelector();
+
+ virtual QList<QString> availableEndpoints() const = 0;
+ virtual QString endpointDescription(const QString& name) const = 0;
+ virtual QString defaultEndpoint() const = 0;
+ virtual QString activeEndpoint() const = 0;
+
+public Q_SLOTS:
+ virtual void setActiveEndpoint(const QString& name) = 0;
+
+Q_SIGNALS:
+ void activeEndpointChanged(const QString& name);
+ void availableEndpointsChanged();
+
+protected:
+ QAudioEndpointSelector(QObject *parent = 0);
+};
+
+#define QAudioEndpointSelector_iid "com.nokia.Qt.QAudioEndpointSelector/1.0"
+Q_MEDIA_DECLARE_CONTROL(QAudioEndpointSelector, QAudioEndpointSelector_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QAUDIOENDPOINTSELECTOR_H
diff --git a/src/multimedia/qaudionamespace.qdoc b/src/multimedia/qaudionamespace.qdoc
new file mode 100644
index 000000000..86300b065
--- /dev/null
+++ b/src/multimedia/qaudionamespace.qdoc
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+/*!
+ \namespace QAudio
+ \brief The QAudio namespace contains enums used by the audio classes.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+*/
+
+/*
+ \enum QAudio::Error
+
+ Error states
+
+ \value NoError No errors have occurred
+ \value OpenError An error opening the audio device
+ \value IOError An error occurred during read/write of audio device
+ \value UnderrunError Audio data is not being fed to the audio device at a fast enough rate
+ \value FatalError A non-recoverable error has occurred, the audio device is not usable at this time.
+*/
+
+/*
+ \enum QAudio::State
+
+ Audio processing states
+
+ \value ActiveState Audio data is being processed, this state is set after start() is called
+ and while audio data is available to be processed.
+ \value SuspendedState The audio device is in a suspended state, this state will only be entered
+ after suspend() is called.
+ \value StoppedState The audio device is closed, not processing any audio data
+ \value IdleState The QIODevice passed in has no data and audio system's buffer is empty, this state
+ is set after start() is called and while no audio data is available to be processed.
+*/
+
+/*
+ \enum QAudio::Mode
+
+ Audio I/O modes
+
+ \value AudioOutput audio output device
+ \value AudioInput audio input device
+*/
diff --git a/src/multimedia/qcamera.cpp b/src/multimedia/qcamera.cpp
new file mode 100644
index 000000000..2b187262b
--- /dev/null
+++ b/src/multimedia/qcamera.cpp
@@ -0,0 +1,1035 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+
+#include <qcamera.h>
+
+#include <qmediaobject_p.h>
+#include <qcameracontrol.h>
+#include <qcameralockscontrol.h>
+#include <qcameraexposurecontrol.h>
+#include <qcamerafocuscontrol.h>
+#include <qmediarecordercontrol.h>
+#include <qcameraimageprocessingcontrol.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qvideodevicecontrol.h>
+#include <qvideosurfaceoutput_p.h>
+
+QT_USE_NAMESPACE
+
+namespace
+{
+class CameraRegisterMetaTypes
+{
+public:
+ CameraRegisterMetaTypes()
+ {
+ qRegisterMetaType<QCamera::Error>("QCamera::Error");
+ qRegisterMetaType<QCamera::State>("QCamera::State");
+ qRegisterMetaType<QCamera::Status>("QCamera::Status");
+ qRegisterMetaType<QCamera::CaptureMode>("QCamera::CaptureMode");
+ qRegisterMetaType<QCamera::LockType>("QCamera::LockType");
+ qRegisterMetaType<QCamera::LockStatus>("QCamera::LockStatus");
+ qRegisterMetaType<QCamera::LockChangeReason>("QCamera::LockChangeReason");
+ }
+} _registerCameraMetaTypes;
+}
+
+
+/*!
+ \class QCamera
+
+
+ \brief The QCamera class provides interface for system camera devices.
+
+ \inmodule QtMultimedia
+ \ingroup camera
+ \since 1.1
+
+ QCamera can be used with QVideoWidget for viewfinder display,
+ QMediaRecorder for video recording and QCameraImageCapture for image taking.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Request control
+
+*/
+
+
+class QCameraPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QCamera)
+public:
+ QCameraPrivate():
+ QMediaObjectPrivate(),
+ provider(0),
+ control(0),
+ deviceControl(0),
+ viewfinder(0),
+ capture(0),
+ state(QCamera::UnloadedState),
+ error(QCamera::NoError),
+ supportedLocks(QCamera::NoLock),
+ requestedLocks(QCamera::NoLock),
+ lockStatus(QCamera::Unlocked),
+ lockChangeReason(QCamera::UserRequest),
+ supressLockChangedSignal(false),
+ restartPending(false)
+ {
+ }
+
+ void initControls();
+
+ QMediaServiceProvider *provider;
+
+ QCameraControl *control;
+ QVideoDeviceControl *deviceControl;
+ QCameraLocksControl *locksControl;
+
+ QCameraExposure *cameraExposure;
+ QCameraFocus *cameraFocus;
+ QCameraImageProcessing *imageProcessing;
+
+ QObject *viewfinder;
+ QObject *capture;
+
+ QCamera::State state;
+
+ QCamera::Error error;
+ QString errorString;
+
+ QCamera::LockTypes supportedLocks;
+ QCamera::LockTypes requestedLocks;
+
+ QCamera::LockStatus lockStatus;
+ QCamera::LockChangeReason lockChangeReason;
+ bool supressLockChangedSignal;
+
+ bool restartPending;
+
+ QVideoSurfaceOutput surfaceViewfinder;
+
+ void _q_error(int error, const QString &errorString);
+ void unsetError() { error = QCamera::NoError; errorString.clear(); }
+
+ void setState(QCamera::State);
+
+ void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason);
+ void _q_updateState(QCamera::State newState);
+ void _q_preparePropertyChange(int changeType);
+ void _q_restartCamera();
+ void updateLockStatus();
+};
+
+
+void QCameraPrivate::_q_error(int error, const QString &errorString)
+{
+ Q_Q(QCamera);
+
+ this->error = QCamera::Error(error);
+ this->errorString = errorString;
+
+ qWarning() << "Camera error:" << errorString;
+
+ emit q->error(this->error);
+}
+
+void QCameraPrivate::setState(QCamera::State newState)
+{
+ Q_Q(QCamera);
+
+ unsetError();
+
+ if (!control) {
+ _q_error(QCamera::ServiceMissingError, q_ptr->tr("The camera service is missing"));
+ return;
+ }
+
+ if (state == newState)
+ return;
+
+ restartPending = false;
+ state = newState;
+ control->setState(state);
+ emit q->stateChanged(state);
+}
+
+void QCameraPrivate::_q_updateState(QCamera::State newState)
+{
+ Q_Q(QCamera);
+
+ //omit changins state to Loaded when the camera is temporarily
+ //stopped to apply shanges
+ if (restartPending)
+ return;
+
+ if (newState != state) {
+ qDebug() << "Camera state changed:" << newState;
+ state = newState;
+ emit q->stateChanged(state);
+ }
+}
+
+void QCameraPrivate::_q_preparePropertyChange(int changeType)
+{
+ if (!control)
+ return;
+
+ QCamera::Status status = control->status();
+
+ //all the changes are allowed until the camera is starting
+ if (control->state() != QCamera::ActiveState)
+ return;
+
+ if (control->canChangeProperty(QCameraControl::PropertyChangeType(changeType), status))
+ return;
+
+ restartPending = true;
+ control->setState(QCamera::LoadedState);
+ QMetaObject::invokeMethod(q_ptr, "_q_restartCamera", Qt::QueuedConnection);
+}
+
+void QCameraPrivate::_q_restartCamera()
+{
+ if (restartPending) {
+ restartPending = false;
+ control->setState(QCamera::ActiveState);
+ }
+}
+
+void QCameraPrivate::initControls()
+{
+ Q_Q(QCamera);
+
+ supportedLocks = 0;
+
+ if (service) {
+ control = qobject_cast<QCameraControl *>(service->requestControl(QCameraControl_iid));
+ locksControl = qobject_cast<QCameraLocksControl *>(service->requestControl(QCameraLocksControl_iid));
+ deviceControl = qobject_cast<QVideoDeviceControl*>(service->requestControl(QVideoDeviceControl_iid));
+
+ if (control) {
+ q->connect(control, SIGNAL(stateChanged(QCamera::State)), q, SLOT(_q_updateState(QCamera::State)));
+ q->connect(control, SIGNAL(statusChanged(QCamera::Status)), q, SIGNAL(statusChanged(QCamera::Status)));
+ q->connect(control, SIGNAL(captureModeChanged(QCamera::CaptureMode)),
+ q, SIGNAL(captureModeChanged(QCamera::CaptureMode)));
+ q->connect(control, SIGNAL(error(int,QString)), q, SLOT(_q_error(int,QString)));
+
+ }
+
+ if (locksControl) {
+ q->connect(locksControl, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)),
+ q, SLOT(_q_updateLockStatus(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
+ supportedLocks = locksControl->supportedLocks();
+ }
+
+ error = QCamera::NoError;
+ } else {
+ control = 0;
+ locksControl = 0;
+ deviceControl = 0;
+
+ error = QCamera::ServiceMissingError;
+ errorString = QCamera::tr("The camera service is missing");
+ }
+}
+
+void QCameraPrivate::updateLockStatus()
+{
+ Q_Q(QCamera);
+
+ QCamera::LockStatus oldStatus = lockStatus;
+
+ QMap<QCamera::LockStatus, int> lockStatusPriority;
+ lockStatusPriority.insert(QCamera::Locked, 1);
+ lockStatusPriority.insert(QCamera::Searching, 2);
+ lockStatusPriority.insert(QCamera::Unlocked, 3);
+
+ lockStatus = requestedLocks ? QCamera::Locked : QCamera::Unlocked;
+ int priority = 0;
+
+ QList<QCamera::LockStatus> lockStatuses;
+
+ if (requestedLocks & QCamera::LockFocus)
+ lockStatuses << q->lockStatus(QCamera::LockFocus);
+
+ if (requestedLocks & QCamera::LockExposure)
+ lockStatuses << q->lockStatus(QCamera::LockExposure);
+
+ if (requestedLocks & QCamera::LockWhiteBalance)
+ lockStatuses << q->lockStatus(QCamera::LockWhiteBalance);
+
+
+ foreach (QCamera::LockStatus currentStatus, lockStatuses) {
+ int currentPriority = lockStatusPriority.value(currentStatus, -1);
+ if (currentPriority > priority) {
+ priority = currentPriority;
+ lockStatus = currentStatus;
+ }
+ }
+
+ if (!supressLockChangedSignal && oldStatus != lockStatus) {
+ emit q->lockStatusChanged(lockStatus, lockChangeReason);
+
+ if (lockStatus == QCamera::Locked)
+ emit q->locked();
+ else if (lockStatus == QCamera::Unlocked && lockChangeReason == QCamera::LockFailed)
+ emit q->lockFailed();
+ }
+/*
+ qDebug() << "Requested locks:" << (requestedLocks & QCamera::LockExposure ? 'e' : ' ')
+ << (requestedLocks & QCamera::LockFocus ? 'f' : ' ')
+ << (requestedLocks & QCamera::LockWhiteBalance ? 'w' : ' ');
+ qDebug() << "Lock status: f:" << q->lockStatus(QCamera::LockFocus)
+ << " e:" << q->lockStatus(QCamera::LockExposure)
+ << " w:" << q->lockStatus(QCamera::LockWhiteBalance)
+ << " composite:" << lockStatus;
+*/
+}
+
+void QCameraPrivate::_q_updateLockStatus(QCamera::LockType type, QCamera::LockStatus status, QCamera::LockChangeReason reason)
+{
+ Q_Q(QCamera);
+ lockChangeReason = reason;
+ updateLockStatus();
+ emit q->lockStatusChanged(type, status, reason);
+}
+
+
+/*!
+ Construct a QCamera from service \a provider and \a parent.
+*/
+
+QCamera::QCamera(QObject *parent, QMediaServiceProvider *provider):
+ QMediaObject(*new QCameraPrivate, parent, provider->requestService(Q_MEDIASERVICE_CAMERA))
+{
+ Q_D(QCamera);
+ d->provider = provider;
+ d->initControls();
+ d->cameraExposure = new QCameraExposure(this);
+ d->cameraFocus = new QCameraFocus(this);
+ d->imageProcessing = new QCameraImageProcessing(this);
+}
+
+/*!
+ Construct a QCamera from device name \a device and \a parent.
+*/
+
+QCamera::QCamera(const QByteArray& device, QObject *parent):
+ QMediaObject(*new QCameraPrivate, parent,
+ QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA, QMediaServiceProviderHint(device)))
+{
+ Q_D(QCamera);
+ d->provider = QMediaServiceProvider::defaultServiceProvider();
+ d->initControls();
+
+ if (d->service != 0) {
+ //pass device name to service
+ if (d->deviceControl) {
+ QString deviceName = QString::fromLatin1(device);
+
+ for (int i=0; i<d->deviceControl->deviceCount(); i++) {
+ if (d->deviceControl->deviceName(i) == deviceName) {
+ d->deviceControl->setSelectedDevice(i);
+ break;
+ }
+ }
+ }
+ }
+
+ d->cameraExposure = new QCameraExposure(this);
+ d->cameraFocus = new QCameraFocus(this);
+ d->imageProcessing = new QCameraImageProcessing(this);
+}
+
+/*!
+ Destroys the camera object.
+*/
+
+QCamera::~QCamera()
+{
+ Q_D(QCamera);
+ delete d->cameraExposure;
+ d->cameraExposure = 0;
+ delete d->cameraFocus;
+ d->cameraFocus = 0;
+ delete d->imageProcessing;
+ d->imageProcessing = 0;
+
+ if (d->service) {
+ if (d->control)
+ d->service->releaseControl(d->control);
+ if (d->locksControl)
+ d->service->releaseControl(d->locksControl);
+ if (d->deviceControl)
+ d->service->releaseControl(d->deviceControl);
+
+ d->provider->releaseService(d->service);
+ }
+}
+
+
+/*!
+ Return true if the camera service is ready to use.
+ \since 1.1
+*/
+bool QCamera::isAvailable() const
+{
+ return availabilityError() == QtMultimedia::NoError;
+}
+
+/*!
+ Returns the error state of the camera service.
+ \since 1.1
+*/
+
+QtMultimedia::AvailabilityError QCamera::availabilityError() const
+{
+ Q_D(const QCamera);
+ if (d->control == NULL)
+ return QtMultimedia::ServiceMissingError;
+
+ if (d->deviceControl && d->deviceControl->deviceCount() == 0)
+ return QtMultimedia::ResourceError;
+
+ if (d->error != QCamera::NoError)
+ return QtMultimedia::ResourceError;
+
+ return QtMultimedia::NoError;
+}
+
+
+/*!
+ Returns the camera exposure control object.
+ \since 1.1
+*/
+QCameraExposure *QCamera::exposure() const
+{
+ return d_func()->cameraExposure;
+}
+
+/*!
+ Returns the camera focus control object.
+ \since 1.1
+*/
+QCameraFocus *QCamera::focus() const
+{
+ return d_func()->cameraFocus;
+}
+
+/*!
+ Returns the camera image processing control object.
+ \since 1.1
+*/
+QCameraImageProcessing *QCamera::imageProcessing() const
+{
+ return d_func()->imageProcessing;
+}
+
+/*!
+ Sets the QVideoWidget based camera \a viewfinder.
+ The previously set viewfinder is detached.
+ \since 1.1
+*/
+
+// QVideoWidget is forward declared
+void QCamera::setViewfinder(QVideoWidget *viewfinder)
+{
+ Q_D(QCamera);
+ d->_q_preparePropertyChange(QCameraControl::Viewfinder);
+
+ if (d->viewfinder)
+ unbind(d->viewfinder);
+
+ // We don't know (in this library) that QVideoWidget inherits QObject
+ QObject *viewFinderObject = reinterpret_cast<QObject*>(viewfinder);
+
+ d->viewfinder = viewFinderObject && bind(viewFinderObject) ? viewFinderObject : 0;
+}
+
+/*!
+ Sets the QGraphicsVideoItem based camera \a viewfinder.
+ The previously set viewfinder is detached.
+ \since 1.1
+*/
+// QGraphicsVideoItem is forward declared
+void QCamera::setViewfinder(QGraphicsVideoItem *viewfinder)
+{
+ Q_D(QCamera);
+ d->_q_preparePropertyChange(QCameraControl::Viewfinder);
+
+ if (d->viewfinder)
+ unbind(d->viewfinder);
+
+ // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
+ // but QObject inheritance depends on QObject coming first, so try this out.
+ QObject *viewFinderObject = reinterpret_cast<QObject*>(viewfinder);
+
+ d->viewfinder = viewFinderObject && bind(viewFinderObject) ? viewFinderObject : 0;
+}
+
+/*!
+ Sets a video \a surface as the viewfinder of a camera.
+
+ If a viewfinder has already been set on the camera the new surface
+ will replace it.
+ \since 1.2
+*/
+
+void QCamera::setViewfinder(QAbstractVideoSurface *surface)
+{
+ Q_D(QCamera);
+
+ d->surfaceViewfinder.setVideoSurface(surface);
+
+ if (d->viewfinder != &d->surfaceViewfinder) {
+ if (d->viewfinder)
+ unbind(d->viewfinder);
+
+ d->viewfinder = bind(&d->surfaceViewfinder) ? &d->surfaceViewfinder : 0;
+ }
+}
+
+/*!
+ Returns the error state of the object.
+ \since 1.1
+*/
+
+QCamera::Error QCamera::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns a string describing a camera's error state.
+ \since 1.1
+*/
+QString QCamera::errorString() const
+{
+ return d_func()->errorString;
+}
+
+
+/*!
+ Returns true if the capture \a mode is suported.
+ \since 1.1
+*/
+bool QCamera::isCaptureModeSupported(QCamera::CaptureMode mode) const
+{
+ return d_func()->control ? d_func()->control->isCaptureModeSupported(mode) : false;
+}
+
+/*!
+ \property QCamera::captureMode
+
+ The type of media (video or still images),
+ the camera is configured to capture.
+
+ It's allowed to change capture mode in any camera state,
+ but if the camera is currently active,
+ chaging capture mode is likely to lead to camera status
+ chaged to QCamera::LoadedStatus, QCamera::LoadingStatus,
+ and when the camera is ready to QCamera::ActiveStatus.
+ \since 1.1
+*/
+
+QCamera::CaptureMode QCamera::captureMode() const
+{
+ return d_func()->control ? d_func()->control->captureMode() : QCamera::CaptureStillImage;
+}
+
+void QCamera::setCaptureMode(QCamera::CaptureMode mode)
+{
+ Q_D(QCamera);
+
+ if (mode != captureMode()) {
+ if (d->control) {
+ d->_q_preparePropertyChange(QCameraControl::CaptureMode);
+ d->control->setCaptureMode(mode);
+ }
+ }
+}
+
+
+/*!
+ Starts the camera.
+
+ State is changed to QCamera::ActiveState if camera is started
+ successfully, otherwise error() signal is emitted.
+
+ While the camera state is changed to QCamera::ActiveState,
+ starting the camera service can be asynchronous with the actual
+ status reported with QCamera::status property.
+ \since 1.1
+*/
+void QCamera::start()
+{
+ Q_D(QCamera);
+ d->setState(QCamera::ActiveState);
+}
+
+/*!
+ Stops the camera.
+ The camera state is changed from QCamera::ActiveState to QCamera::LoadedState.
+ \since 1.1
+*/
+void QCamera::stop()
+{
+ Q_D(QCamera);
+ d->setState(QCamera::LoadedState);
+}
+
+/*!
+ Open the camera device.
+ The camera state is changed to QCamera::LoadedStatus.
+
+ It's not necessary to explcitly load the camera,
+ unless unless the application have to read the supported camera
+ settings and change the default depending on the camera capabilities.
+
+ In all the other cases it's possible to start the camera directly
+ from unloaded state.
+ \since 1.1
+*/
+void QCamera::load()
+{
+ Q_D(QCamera);
+ d->setState(QCamera::LoadedState);
+}
+
+/*!
+ Close the camera device and deallocate the related resources.
+ The camera state is changed to QCamera::UnloadedStatus.
+ \since 1.1
+*/
+void QCamera::unload()
+{
+ Q_D(QCamera);
+ d->setState(QCamera::UnloadedState);
+}
+
+
+/*!
+ Returns a list of camera device's available from the default service provider.
+ \since 1.1
+*/
+
+QList<QByteArray> QCamera::availableDevices()
+{
+ return QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA));
+}
+
+/*!
+ Returns the description of the \a device.
+ \since 1.1
+*/
+
+QString QCamera::deviceDescription(const QByteArray &device)
+{
+ return QMediaServiceProvider::defaultServiceProvider()->deviceDescription(QByteArray(Q_MEDIASERVICE_CAMERA), device);
+}
+
+QCamera::State QCamera::state() const
+{
+ return d_func()->state;
+}
+
+QCamera::Status QCamera::status() const
+{
+ if(d_func()->control)
+ return (QCamera::Status)d_func()->control->status();
+
+ return QCamera::UnavailableStatus;
+}
+
+
+/*!
+ Returns the lock types, camera supports.
+ \since 1.1
+*/
+QCamera::LockTypes QCamera::supportedLocks() const
+{
+ return d_func()->supportedLocks;
+}
+
+/*!
+ Returns the requested lock types.
+ \since 1.1
+*/
+QCamera::LockTypes QCamera::requestedLocks() const
+{
+ return d_func()->requestedLocks;
+}
+
+/*!
+ Returns the status of requested camera settings locks.
+ \since 1.1
+*/
+QCamera::LockStatus QCamera::lockStatus() const
+{
+ return d_func()->lockStatus;
+}
+
+/*!
+ Returns the status of camera settings \a lock.
+ \since 1.1
+*/
+QCamera::LockStatus QCamera::lockStatus(QCamera::LockType lockType) const
+{
+ const QCameraPrivate *d = d_func();
+
+ if (!(lockType & d->supportedLocks))
+ return lockType & d->requestedLocks ? QCamera::Locked : QCamera::Unlocked;
+
+ if (!(lockType & d->requestedLocks))
+ return QCamera::Unlocked;
+
+ if (d->locksControl)
+ return d->locksControl->lockStatus(lockType);
+
+ return QCamera::Unlocked;
+}
+
+/*!
+ \fn void QCamera::searchAndLock(QCamera::LockTypes locks)
+
+ Locks the camera settings with the requested \a locks, including focusing in the single autofocus mode,
+ exposure and white balance if the exposure and white balance modes are not manual.
+
+ The camera settings are usually locked before taking one or multiple still images,
+ in responce to the shutter button being half pressed.
+
+ The QCamera::locked() signal is emitted when camera settings are successfully locked,
+ otherwise QCamera::lockFailed() is emitted.
+
+ QCamera also emits lockStatusChanged(QCamera::LockType, QCamera::LockStatus)
+ on individual lock status changes and lockStatusChanged(QCamera::LockStatus) signal on composite status changes.
+
+ Locking serves two roles: it initializes calculation of automatic parameter
+ (focusing, calculating the correct exposure and white balance) and allows
+ to keep some or all of those parameters during number of shots.
+
+ If the camera doesn't support keeping one of parameters between shots, the related
+ lock state changes to QCamera::Unlocked.
+
+ It's also acceptable to relock already locked settings,
+ depending on the lock parameter this initiates new focusing, exposure or white balance calculation.
+ \since 1.1
+ */
+void QCamera::searchAndLock(QCamera::LockTypes locks)
+{
+ Q_D(QCamera);
+
+ QCamera::LockStatus oldStatus = d->lockStatus;
+ d->supressLockChangedSignal = true;
+
+ d->requestedLocks |= locks;
+
+ locks &= d->supportedLocks;
+
+ if (d->locksControl)
+ d->locksControl->searchAndLock(locks);
+
+ d->supressLockChangedSignal = false;
+
+ d->lockStatus = oldStatus;
+ d->updateLockStatus();
+}
+
+/*!
+ Lock all the supported camera settings.
+ \since 1.1
+ */
+void QCamera::searchAndLock()
+{
+ searchAndLock(LockExposure | LockWhiteBalance | LockFocus);
+}
+
+/*!
+ Unlocks the camera settings specified with \a locks or cancel the current locking if one is active.
+ \since 1.1
+ */
+void QCamera::unlock(QCamera::LockTypes locks)
+{
+ Q_D(QCamera);
+
+ QCamera::LockStatus oldStatus = d->lockStatus;
+ d->supressLockChangedSignal = true;
+
+ d->requestedLocks &= ~locks;
+
+ locks &= d->supportedLocks;
+
+ if (d->locksControl)
+ d->locksControl->unlock(locks);
+
+ d->supressLockChangedSignal = false;
+
+ d->lockStatus = oldStatus;
+ d->updateLockStatus();
+}
+
+/*!
+ Unlock all the requested camera locks.
+ \since 1.1
+ */
+void QCamera::unlock()
+{
+ unlock(d_func()->requestedLocks);
+}
+
+
+/*!
+ \enum QCamera::State
+ \value UnloadedState
+ The initial camera state, with camera not loaded,
+ the camera capabilities except of supported capture modes
+ are unknown.
+
+ While the supported settings are unknown in this state,
+ it's allowed to set the camera capture settings like codec,
+ resolution, or frame rate.
+
+ \value LoadedState
+ The camera is loaded and ready to be configured.
+
+ In the Idle state it's allowed to query camera capabilities,
+ set capture resolution, codecs, etc.
+
+ The viewfinder is not active in the loaded state.
+
+ \value ActiveState
+ In the active state as soon as camera is started
+ the viewfinder displays video frames and the
+ camera is ready for capture.
+*/
+
+
+/*!
+ \property QCamera::state
+ \brief The current state of the camera object.
+ \since 1.1
+*/
+
+/*!
+ \enum QCamera::Status
+ \value ActiveStatus
+ The camera has been started and can produce data.
+ The viewfinder displays video frames in active state.
+
+ Depending on backend, changing some camera settings like
+ capture mode, codecs or resolution in ActiveState may lead
+ to changing the camera status to LoadedStatus and StartingStatus while
+ the settings are applied and back to ActiveStatus when the camera is ready.
+
+ \value StartingStatus
+ The camera is starting in result of state transition to QCamera::ActiveState.
+ The camera service is not ready to capture yet.
+
+ \value StandbyStatus
+ The camera is in the power saving standby mode.
+ The camera may come to the standby mode after some time of inactivity
+ in the QCamera::LoadedState state.
+
+ \value LoadedStatus
+ The camera is loaded and ready to be configured.
+ This status indicates the camera device is opened and
+ it's possible to query for supported image and video capture settings,
+ like resolution, framerate and codecs.
+
+ \value LoadingStatus
+ The camera device loading in result of state transition from
+ QCamera::UnloadedState to QCamera::LoadedState or QCamera::ActiveState.
+
+ \value UnloadedStatus
+ The initial camera status, with camera not loaded.
+ The camera capabilities including supported capture settings may be unknown.
+
+ \value UnavailableStatus
+ The camera or camera backend is not available.
+*/
+
+
+/*!
+ \property QCamera::status
+ \brief The current status of the camera object.
+ \since 1.1
+*/
+
+
+/*!
+ \enum QCamera::CaptureMode
+ \value CaptureStillImage Camera is configured for still frames capture.
+ \value CaptureVideo Camera is configured for video capture.
+ \since 1.1
+*/
+
+/*!
+ \enum QCamera::LockType
+
+ \value NoLock
+ \value LockExposure
+ Lock camera exposure.
+ \value LockWhiteBalance
+ Lock the white balance.
+ \value LockFocus
+ Lock camera focus.
+*/
+
+
+/*!
+ \property QCamera::lockStatus
+ \brief The overall status for all the requested camera locks.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCamera::locked()
+
+ Signals all the requested camera settings are locked.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCamera::lockFailed()
+
+ Signals locking of at least one requested camera settings failed.
+ \since 1.1
+*/
+
+/*!
+ \fn QCamera::lockStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason)
+
+ Signals the overall \a status for all the requested camera locks was changed with specified \a reason.
+ \since 1.1
+*/
+
+/*!
+ \fn QCamera::lockStatusChanged(QCamera::LockType lock, QCamera::LockStatus status, QCamera::LockChangeReason reason)
+ Signals the \a lock \a status was changed with specified \a reason.
+ \since 1.1
+*/
+
+/*!
+ \enum QCamera::LockStatus
+ \value Unlocked
+ The application is not interested in camera settings value.
+ The camera may keep this parameter without changes, this is common with camera focus,
+ or adjust exposure and white balance constantly to keep the viewfinder image nice.
+
+ \value Searching
+ The application has requested the camera focus, exposure or white balance lock with
+ QCamera::searchAndLock(). This state indicates the camera is focusing or calculating exposure and white balance.
+
+ \value Locked
+ The camera focus, exposure or white balance is locked.
+ The camera is ready to capture, application may check the exposure parameters.
+
+ The locked state usually means the requested parameter stays the same,
+ except of the cases when the parameter is requested to be constantly updated.
+ For example in continuous focusing mode, the focus is considered locked as long
+ and the object is in focus, even while the actual focusing distance may be constantly changing.
+*/
+
+/*!
+ \enum QCamera::LockChangeReason
+
+ \value UserRequest
+ The lock status changed in result of user request, usually to unlock camera settings.
+ \value LockAcquired
+ The lock status successfuly changed to QCamera::Locked.
+ \value LockFailed
+ The camera failed to acquire the requested lock in result of
+ autofocus failure, exposure out of supported range, etc.
+ \value LockLost
+ The camera is not able to maintain the requested lock any more.
+ Lock status is changed to QCamera::Unlocked.
+ \value LockTemporaryLost
+ The lock is lost, but the camera is working hard to reacquire it.
+ This value may be used in continuous focusing mode,
+ when the camera loses the focus, the focus lock state is changed to Qcamera::Searching
+ with LockTemporaryLost reason.
+*/
+
+/*!
+ \enum QCamera::Error
+
+ \value NoError No errors have occurred.
+ \value CameraError An error has occurred.
+ \value InvalidRequestError System resource doesn't support requested functionality.
+ \value ServiceMissingError No camera service available.
+ \value NotSupportedFeatureError The feature is not supported.
+*/
+
+/*!
+ \fn void QCamera::error(QCamera::Error value)
+
+ Signal emitted when error state changes to \a value.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCamera::captureModeChanged(QCamera::CaptureMode mode)
+
+ Signals the capture \a mode has changed.
+ \since 1.1
+*/
+
+/*!
+ \fn QCamera::stateChanged(QCamera::State state)
+
+ Signals the camera \a state has changed.
+
+ Usually the state changes is caused by calling
+ load(), unload(), start() and stop(),
+ but the state can also be changed change as a result of camera error.
+ \since 1.1
+*/
+
+/*!
+ \fn QCamera::statusChanged(QCamera::Status status)
+
+ Signals the camera \a status has changed.
+
+ \since 1.1
+*/
+
+
+#include "moc_qcamera.cpp"
diff --git a/src/multimedia/qcamera.h b/src/multimedia/qcamera.h
new file mode 100644
index 000000000..da009e161
--- /dev/null
+++ b/src/multimedia/qcamera.h
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERA_H
+#define QCAMERA_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+#include <qmediaservice.h>
+
+#include <qcameraexposure.h>
+#include <qcamerafocus.h>
+#include <qcameraimageprocessing.h>
+
+#include <qmediaserviceprovider.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoSurface;
+class QVideoWidget;
+class QGraphicsVideoItem;
+
+class QCameraPrivate;
+class Q_MULTIMEDIA_EXPORT QCamera : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QCamera::State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(QCamera::Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QCamera::CaptureMode captureMode READ captureMode WRITE setCaptureMode NOTIFY captureModeChanged)
+ Q_PROPERTY(QCamera::LockStatus lockStatus READ lockStatus NOTIFY lockStatusChanged)
+
+ Q_ENUMS(Status)
+ Q_ENUMS(State)
+ Q_ENUMS(CaptureMode)
+ Q_ENUMS(Error)
+ Q_ENUMS(LockStatus)
+ Q_ENUMS(LockChangeReason)
+ Q_ENUMS(LockType)
+public:
+ enum Status {
+ UnavailableStatus,
+ UnloadedStatus,
+ LoadingStatus,
+ LoadedStatus,
+ StandbyStatus,
+ StartingStatus,
+ ActiveStatus
+ };
+
+ enum State {
+ UnloadedState,
+ LoadedState,
+ ActiveState
+ };
+
+ enum CaptureMode
+ {
+ CaptureStillImage,
+ CaptureVideo
+ };
+
+ enum Error
+ {
+ NoError,
+ CameraError,
+ InvalidRequestError,
+ ServiceMissingError,
+ NotSupportedFeatureError
+ };
+
+ enum LockStatus
+ {
+ Unlocked,
+ Searching,
+ Locked
+ };
+
+ enum LockChangeReason {
+ UserRequest,
+ LockAcquired,
+ LockFailed,
+ LockLost,
+ LockTemporaryLost
+ };
+
+ enum LockType
+ {
+ NoLock = 0,
+ LockExposure = 0x01,
+ LockWhiteBalance = 0x02,
+ LockFocus = 0x04
+ };
+ Q_DECLARE_FLAGS(LockTypes, LockType)
+
+ QCamera(QObject *parent = 0, QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider());
+ QCamera(const QByteArray& device, QObject *parent = 0);
+ ~QCamera();
+
+ static QList<QByteArray> availableDevices();
+ static QString deviceDescription(const QByteArray &device);
+
+ bool isAvailable() const;
+ QtMultimedia::AvailabilityError availabilityError() const;
+
+ State state() const;
+ Status status() const;
+
+ CaptureMode captureMode() const;
+ bool isCaptureModeSupported(CaptureMode mode) const;
+
+ QCameraExposure *exposure() const;
+ QCameraFocus *focus() const;
+ QCameraImageProcessing *imageProcessing() const;
+
+ void setViewfinder(QVideoWidget *viewfinder);
+ void setViewfinder(QGraphicsVideoItem *viewfinder);
+ void setViewfinder(QAbstractVideoSurface *surface);
+
+ Error error() const;
+ QString errorString() const;
+
+ QCamera::LockTypes supportedLocks() const;
+ QCamera::LockTypes requestedLocks() const;
+
+ QCamera::LockStatus lockStatus() const;
+ QCamera::LockStatus lockStatus(QCamera::LockType lock) const;
+
+public Q_SLOTS:
+ void setCaptureMode(QCamera::CaptureMode mode);
+
+ void load();
+ void unload();
+
+ void start();
+ void stop();
+
+ void searchAndLock();
+ void unlock();
+
+ void searchAndLock(QCamera::LockTypes locks);
+ void unlock(QCamera::LockTypes locks);
+
+Q_SIGNALS:
+ void stateChanged(QCamera::State);
+ void captureModeChanged(QCamera::CaptureMode);
+ void statusChanged(QCamera::Status);
+
+ void locked();
+ void lockFailed();
+
+ void lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason);
+ void lockStatusChanged(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason);
+
+ void error(QCamera::Error);
+
+private:
+ Q_DISABLE_COPY(QCamera)
+ Q_DECLARE_PRIVATE(QCamera)
+ Q_PRIVATE_SLOT(d_func(), void _q_preparePropertyChange(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_restartCamera())
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateState(QCamera::State))
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCamera::LockTypes)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCamera::State)
+Q_DECLARE_METATYPE(QCamera::Status)
+Q_DECLARE_METATYPE(QCamera::Error)
+Q_DECLARE_METATYPE(QCamera::CaptureMode)
+Q_DECLARE_METATYPE(QCamera::LockType)
+Q_DECLARE_METATYPE(QCamera::LockStatus)
+Q_DECLARE_METATYPE(QCamera::LockChangeReason)
+
+Q_MEDIA_ENUM_DEBUG(QCamera, State)
+Q_MEDIA_ENUM_DEBUG(QCamera, Status)
+Q_MEDIA_ENUM_DEBUG(QCamera, Error)
+Q_MEDIA_ENUM_DEBUG(QCamera, CaptureMode)
+Q_MEDIA_ENUM_DEBUG(QCamera, LockType)
+Q_MEDIA_ENUM_DEBUG(QCamera, LockStatus)
+Q_MEDIA_ENUM_DEBUG(QCamera, LockChangeReason)
+
+QT_END_HEADER
+
+#endif // QCAMERA_H
diff --git a/src/multimedia/qcameracapturebufferformatcontrol.cpp b/src/multimedia/qcameracapturebufferformatcontrol.cpp
new file mode 100644
index 000000000..536c8b329
--- /dev/null
+++ b/src/multimedia/qcameracapturebufferformatcontrol.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameracapturebufferformatcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraCaptureBufferFormatControl
+
+ \brief The QCameraCaptureBufferFormatControl class provides a control for setting the capture buffer format.
+
+ The format is of type QVideoFrame::PixelFormat.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+
+ The interface name of QCameraCaptureBufferFormatControl is \c com.nokia.Qt.QCameraCaptureBufferFormatControl/1.0 as
+ defined in QCameraCaptureBufferFormatControl_iid.
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ \macro QCameraCaptureBufferFormatControl_iid
+
+ \c com.nokia.Qt.QCameraCaptureBufferFormatControl/1.0
+
+ Defines the interface name of the QCameraCaptureBufferFormatControl class.
+
+ \relates QCameraCaptureBufferFormatControl
+*/
+
+/*!
+ Constructs a new image buffer capture format control object with the given \a parent
+*/
+QCameraCaptureBufferFormatControl::QCameraCaptureBufferFormatControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys an image buffer capture format control.
+*/
+QCameraCaptureBufferFormatControl::~QCameraCaptureBufferFormatControl()
+{
+}
+
+/*!
+ \fn QCameraCaptureBufferFormatControl::supportedBufferFormats() const
+
+ Returns the list of the supported buffer capture formats.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureBufferFormatControl::bufferFormat() const
+
+ Returns the current buffer capture format.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format)
+
+ Sets the buffer capture \a format.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureBufferFormatControl::bufferFormatChanged(QVideoFrame::PixelFormat format)
+
+ Signals the buffer image capture format changed to \a format.
+ \since 1.2
+*/
+
+#include "moc_qcameracapturebufferformatcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameracapturebufferformatcontrol.h b/src/multimedia/qcameracapturebufferformatcontrol.h
new file mode 100644
index 000000000..81079a77d
--- /dev/null
+++ b/src/multimedia/qcameracapturebufferformatcontrol.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERACAPTUREBUFFERFORMATCONTROL_H
+#define QCAMERACAPTUREBUFFERFORMATCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qcameraimagecapture.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraCaptureBufferFormatControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ ~QCameraCaptureBufferFormatControl();
+
+ virtual QList<QVideoFrame::PixelFormat> supportedBufferFormats() const = 0;
+ virtual QVideoFrame::PixelFormat bufferFormat() const = 0;
+ virtual void setBufferFormat(QVideoFrame::PixelFormat format) = 0;
+
+Q_SIGNALS:
+ void bufferFormatChanged(QVideoFrame::PixelFormat);
+
+protected:
+ QCameraCaptureBufferFormatControl(QObject* parent = 0);
+};
+
+#define QCameraCaptureBufferFormatControl_iid "com.nokia.Qt.QCameraCaptureBufferFormatControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraCaptureBufferFormatControl, QCameraCaptureBufferFormatControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
+
diff --git a/src/multimedia/qcameracapturedestinationcontrol.cpp b/src/multimedia/qcameracapturedestinationcontrol.cpp
new file mode 100644
index 000000000..5072ae774
--- /dev/null
+++ b/src/multimedia/qcameracapturedestinationcontrol.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameracapturedestinationcontrol.h>
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraCaptureDestinationControl
+
+ \brief The QCameraCaptureDestinationControl class provides a control for setting capture destination.
+
+ Depending on backend capabilities capture to file, buffer or both can be supported.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+
+
+
+ The interface name of QCameraCaptureDestinationControl is \c com.nokia.Qt.QCameraCaptureDestinationControl/1.0 as
+ defined in QCameraCaptureDestinationControl_iid.
+
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ \macro QCameraCaptureDestinationControl_iid
+
+ \c com.nokia.Qt.QCameraCaptureDestinationControl/1.0
+
+ Defines the interface name of the QCameraCaptureDestinationControl class.
+
+ \relates QCameraCaptureDestinationControl
+*/
+
+/*!
+ Constructs a new image capture destination control object with the given \a parent
+*/
+QCameraCaptureDestinationControl::QCameraCaptureDestinationControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys an image capture destination control.
+*/
+QCameraCaptureDestinationControl::~QCameraCaptureDestinationControl()
+{
+}
+
+/*!
+ \fn QCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+
+ Returns true if the capture \a destination is supported; and false if it is not.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureDestinationControl::captureDestination() const
+
+ Returns the current capture \a destination. The default destination is QCameraImageCapture::CaptureToFile.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+
+ Sets the capture \a destination.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraCaptureDestinationControl::captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination)
+
+ Signals the image capture \a destination changed.
+ \since 1.2
+*/
+
+#include "moc_qcameracapturedestinationcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameracapturedestinationcontrol.h b/src/multimedia/qcameracapturedestinationcontrol.h
new file mode 100644
index 000000000..cdd769a4d
--- /dev/null
+++ b/src/multimedia/qcameracapturedestinationcontrol.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERACAPTUREDESTINATIONCONTROL_H
+#define QCAMERACAPTUREDESTINATIONCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qcameraimagecapture.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraCaptureDestinationControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ ~QCameraCaptureDestinationControl();
+
+ virtual bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const = 0;
+ virtual QCameraImageCapture::CaptureDestinations captureDestination() const = 0;
+ virtual void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) = 0;
+
+Q_SIGNALS:
+ void captureDestinationChanged(QCameraImageCapture::CaptureDestinations);
+
+protected:
+ QCameraCaptureDestinationControl(QObject* parent = 0);
+};
+
+#define QCameraCaptureDestinationControl_iid "com.nokia.Qt.QCameraCaptureDestinationControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraCaptureDestinationControl, QCameraCaptureDestinationControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
+
diff --git a/src/multimedia/qcameracontrol.cpp b/src/multimedia/qcameracontrol.cpp
new file mode 100644
index 000000000..df5c44cc1
--- /dev/null
+++ b/src/multimedia/qcameracontrol.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameracontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraControl
+
+
+
+ \brief The QCameraControl class is an abstract base class for
+ classes that control still cameras or video cameras.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+ This service is provided by a QMediaService object via
+ QMediaService::control(). It is used by QCamera.
+
+ The interface name of QCameraControl is \c com.nokia.Qt.QCameraControl/1.0 as
+ defined in QCameraControl_iid.
+
+
+
+ \sa QMediaService::requestControl(), QCamera
+*/
+
+/*!
+ \macro QCameraControl_iid
+
+ \c com.nokia.Qt.QCameraControl/1.0
+
+ Defines the interface name of the QCameraControl class.
+
+ \relates QCameraControl
+*/
+
+/*!
+ Constructs a camera control object with \a parent.
+*/
+
+QCameraControl::QCameraControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destruct the camera control object.
+*/
+
+QCameraControl::~QCameraControl()
+{
+}
+
+/*!
+ \fn QCameraControl::state() const
+
+ Returns the state of the camera service.
+
+ \since 1.1
+ \sa QCamera::state
+*/
+
+/*!
+ \fn QCameraControl::setState(QCamera::State state)
+
+ Sets the camera \a state.
+
+ State changes are synchronous and indicate user intention,
+ while camera status is used as a feedback mechanism to inform application about backend status.
+ Status changes are reported asynchronously with QCameraControl::statusChanged() signal.
+
+ \since 1.1
+ \sa QCamera::State
+*/
+
+/*!
+ \fn void QCameraControl::stateChanged(QCamera::State state)
+
+ Signal emitted when the camera \a state changes.
+
+ In most cases the state chage is caused by QCameraControl::setState(),
+ but if critical error has occurred the state changes to QCamera::UnloadedState.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraControl::status() const
+
+ Returns the status of the camera service.
+
+ \since 1.1
+ \sa QCamera::state
+*/
+
+/*!
+ \fn void QCameraControl::statusChanged(QCamera::Status status)
+
+ Signal emitted when the camera \a status changes.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraControl::error(int error, const QString &errorString)
+
+ Signal emitted when an error occurs with error code \a error and
+ a description of the error \a errorString.
+ \since 1.1
+*/
+
+/*!
+ \fn Camera::CaptureMode QCameraControl::captureMode() const = 0
+
+ Returns the current capture mode.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraControl::setCaptureMode(QCamera::CaptureMode mode) = 0;
+
+ Sets the current capture \a mode.
+
+ The capture mode changes are synchronous and allowed in any camera state.
+
+ If the capture mode is changed while camera is active,
+ it's recommended to change status to QCamera::LoadedStatus
+ and start activating the camera in the next event loop
+ with the status changed to QCamera::StartingStatus.
+ This allows the capture settings to be applied before camera is started.
+ Than change the status to QCamera::StartedStatus when the capture mode change is done.
+ \since 1.1
+*/
+
+/*!
+ \fn bool QCameraControl::isCaptureModeSupported(QCamera::CaptureMode mode) const = 0;
+
+ Returns true if the capture \a mode is suported.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraControl::captureModeChanged(QCamera::CaptureMode mode)
+
+ Signal emitted when the camera capture \a mode changes.
+ \since 1.1
+ */
+
+/*!
+ \fn bool QCameraControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const
+
+ Returns true if backend can effectively apply changing camera properties of \a changeType type
+ while the camera state is QCamera::Active and camera status matches \a status parameter.
+
+ If backend doesn't support applying this change in the active state, it will be stopped
+ before the settings are changed and restarted after.
+ Otherwise the backend should apply the change in the current state,
+ with the camera status indicating the progress, if necessary.
+ \since 1.1
+*/
+
+/*!
+ \enum QCameraControl::PropertyChangeType
+
+ \value CaptureMode Indicates the capture mode is changed.
+ \value ImageEncodingSettings Image encoder settings are changed, including resolution.
+ \value VideoEncodingSettings
+ Video encoder settings are changed, including audio, video and container settings.
+ \value Viewfinder Viewfinder is changed.
+*/
+
+#include "moc_qcameracontrol.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qcameracontrol.h b/src/multimedia/qcameracontrol.h
new file mode 100644
index 000000000..dfc2b3743
--- /dev/null
+++ b/src/multimedia/qcameracontrol.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERACONTROL_H
+#define QCAMERACONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcamera.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ enum PropertyChangeType {
+ CaptureMode = 1,
+ ImageEncodingSettings = 2,
+ VideoEncodingSettings = 3,
+ Viewfinder = 4
+ };
+
+ ~QCameraControl();
+
+ virtual QCamera::State state() const = 0;
+ virtual void setState(QCamera::State state) = 0;
+
+ virtual QCamera::Status status() const = 0;
+
+ virtual QCamera::CaptureMode captureMode() const = 0;
+ virtual void setCaptureMode(QCamera::CaptureMode) = 0;
+ virtual bool isCaptureModeSupported(QCamera::CaptureMode mode) const = 0;
+
+ virtual bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const = 0;
+
+Q_SIGNALS:
+ void stateChanged(QCamera::State);
+ void statusChanged(QCamera::Status);
+ void error(int error, const QString &errorString);
+ void captureModeChanged(QCamera::CaptureMode);
+
+protected:
+ QCameraControl(QObject* parent = 0);
+};
+
+#define QCameraControl_iid "com.nokia.Qt.QCameraControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraControl, QCameraControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERACONTROL_H
+
diff --git a/src/multimedia/qcameraexposure.cpp b/src/multimedia/qcameraexposure.cpp
new file mode 100644
index 000000000..580b1cad9
--- /dev/null
+++ b/src/multimedia/qcameraexposure.cpp
@@ -0,0 +1,646 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+
+#include <qcameraexposure.h>
+#include <qcamera.h>
+
+#include <qmediaobject_p.h>
+#include <qcameraexposurecontrol.h>
+#include <qcameraflashcontrol.h>
+#include <qmetaobject.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraExposure
+
+
+ \brief The QCameraExposure class provides interface for exposure related camera settings.
+
+ \inmodule QtMultimedia
+ \ingroup camera
+ \since 1.1
+
+*/
+
+//#define DEBUG_EXPOSURE_CHANGES 1
+
+#ifdef DEBUG_EXPOSURE_CHANGES
+#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
+#endif
+
+namespace
+{
+class CameraExposureRegisterMetaTypes
+{
+public:
+ CameraExposureRegisterMetaTypes()
+ {
+ qRegisterMetaType<QCameraExposure::ExposureMode>("QCameraExposure::ExposureMode");
+ qRegisterMetaType<QCameraExposure::FlashModes>("QCameraExposure::FlashModes");
+ qRegisterMetaType<QCameraExposure::MeteringMode>("QCameraExposure::MeteringMode");
+ }
+} _registerCameraExposureMetaTypes;
+}
+
+
+
+class QCameraExposurePrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QCameraExposure)
+public:
+ void initControls();
+ QCameraExposure *q_ptr;
+
+ QCamera *camera;
+ QCameraExposureControl *exposureControl;
+ QCameraFlashControl *flashControl;
+
+ void _q_exposureParameterChanged(int parameter);
+ void _q_exposureParameterRangeChanged(int parameter);
+};
+
+void QCameraExposurePrivate::initControls()
+{
+ Q_Q(QCameraExposure);
+
+ QMediaService *service = camera->service();
+ exposureControl = 0;
+ flashControl = 0;
+ if (service) {
+ exposureControl = qobject_cast<QCameraExposureControl *>(service->requestControl(QCameraExposureControl_iid));
+ flashControl = qobject_cast<QCameraFlashControl *>(service->requestControl(QCameraFlashControl_iid));
+ }
+ if (exposureControl) {
+ q->connect(exposureControl, SIGNAL(exposureParameterChanged(int)),
+ q, SLOT(_q_exposureParameterChanged(int)));
+ q->connect(exposureControl, SIGNAL(exposureParameterRangeChanged(int)),
+ q, SLOT(_q_exposureParameterRangeChanged(int)));
+ }
+
+ if (flashControl)
+ q->connect(flashControl, SIGNAL(flashReady(bool)), q, SIGNAL(flashReady(bool)));
+}
+
+void QCameraExposurePrivate::_q_exposureParameterChanged(int parameter)
+{
+ Q_Q(QCameraExposure);
+
+#if DEBUG_EXPOSURE_CHANGES
+ qDebug() << "Exposure parameter changed:"
+ << ENUM_NAME(QCameraExposureControl, "ExposureParameter", parameter)
+ << exposureControl->exposureParameter(QCameraExposureControl::ExposureParameter(parameter));
+#endif
+
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ emit q->isoSensitivityChanged(q->isoSensitivity());
+ break;
+ case QCameraExposureControl::Aperture:
+ emit q->apertureChanged(q->aperture());
+ break;
+ case QCameraExposureControl::ShutterSpeed:
+ emit q->shutterSpeedChanged(q->shutterSpeed());
+ break;
+ case QCameraExposureControl::ExposureCompensation:
+ emit q->exposureCompensationChanged(q->exposureCompensation());
+ break;
+ }
+}
+
+void QCameraExposurePrivate::_q_exposureParameterRangeChanged(int parameter)
+{
+ Q_Q(QCameraExposure);
+
+ switch (parameter) {
+ case QCameraExposureControl::Aperture:
+ emit q->apertureRangeChanged();
+ break;
+ case QCameraExposureControl::ShutterSpeed:
+ emit q->shutterSpeedRangeChanged();
+ break;
+ }
+}
+
+/*!
+ Construct a QCameraExposure from service \a provider and \a parent.
+*/
+
+QCameraExposure::QCameraExposure(QCamera *parent):
+ QObject(parent), d_ptr(new QCameraExposurePrivate)
+{
+ Q_D(QCameraExposure);
+ d->camera = parent;
+ d->q_ptr = this;
+ d->initControls();
+}
+
+
+/*!
+ Destroys the camera exposure object.
+*/
+
+QCameraExposure::~QCameraExposure()
+{
+ Q_D(QCameraExposure);
+ if (d->exposureControl)
+ d->camera->service()->releaseControl(d->exposureControl);
+}
+
+/*!
+ Returns true if exposure settings are supported by this camera.
+ \since 1.1
+*/
+bool QCameraExposure::isAvailable() const
+{
+ return d_func()->exposureControl != 0;
+}
+
+
+/*!
+ \property QCameraExposure::flashMode
+ \brief The flash mode being used.
+
+ Usually the single QCameraExposure::FlashMode flag is used,
+ but some non conflicting flags combination are also allowed,
+ like QCameraExposure::FlashManual | QCameraExposure::FlashSlowSyncRearCurtain.
+
+ \since 1.1
+ \sa QCameraExposure::isFlashModeSupported(), QCameraExposure::isFlashReady()
+*/
+
+QCameraExposure::FlashModes QCameraExposure::flashMode() const
+{
+ return d_func()->flashControl ? d_func()->flashControl->flashMode() : QCameraExposure::FlashOff;
+}
+
+void QCameraExposure::setFlashMode(QCameraExposure::FlashModes mode)
+{
+ if (d_func()->flashControl)
+ d_func()->flashControl->setFlashMode(mode);
+}
+
+/*!
+ Returns true if the flash \a mode is supported.
+ \since 1.1
+*/
+
+bool QCameraExposure::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+{
+ return d_func()->flashControl ? d_func()->flashControl->isFlashModeSupported(mode) : false;
+}
+
+/*!
+ Returns true if flash is charged.
+*/
+
+bool QCameraExposure::isFlashReady() const
+{
+ return d_func()->flashControl ? d_func()->flashControl->isFlashReady() : false;
+}
+
+
+/*!
+ \property QCameraExposure::exposureMode
+ \brief The exposure mode being used.
+
+ \since 1.1
+ \sa QCameraExposure::isExposureModeSupported()
+*/
+
+QCameraExposure::ExposureMode QCameraExposure::exposureMode() const
+{
+ return d_func()->exposureControl ? d_func()->exposureControl->exposureMode() : QCameraExposure::ExposureAuto;
+}
+
+void QCameraExposure::setExposureMode(QCameraExposure::ExposureMode mode)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureMode(mode);
+}
+
+/*!
+ Returns true if the exposure \a mode is supported.
+ \since 1.1
+*/
+
+bool QCameraExposure::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+{
+ return d_func()->exposureControl ?
+ d_func()->exposureControl->isExposureModeSupported(mode) : false;
+}
+
+/*!
+ \property QCameraExposure::exposureCompensation
+ \brief Exposure compensation in EV units.
+
+ Exposure compensation property allows to adjust the automatically calculated exposure.
+ \since 1.1
+*/
+
+qreal QCameraExposure::exposureCompensation() const
+{
+ if (d_func()->exposureControl)
+ return d_func()->exposureControl->exposureParameter(QCameraExposureControl::ExposureCompensation).toReal();
+ else
+ return 0;
+}
+
+void QCameraExposure::setExposureCompensation(qreal ev)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::ExposureCompensation, QVariant(ev));
+}
+
+/*!
+ \property QCameraExposure::meteringMode
+ \brief The metering mode being used.
+
+ \since 1.1
+ \sa QCameraExposure::isMeteringModeSupported()
+*/
+
+QCameraExposure::MeteringMode QCameraExposure::meteringMode() const
+{
+ return d_func()->exposureControl ? d_func()->exposureControl->meteringMode() : QCameraExposure::MeteringMatrix;
+}
+
+void QCameraExposure::setMeteringMode(QCameraExposure::MeteringMode mode)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setMeteringMode(mode);
+}
+
+/*!
+ Returns true if the metering \a mode is supported.
+ \since 1.1
+*/
+bool QCameraExposure::isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
+{
+ return d_func()->exposureControl ? d_func()->exposureControl->isMeteringModeSupported(mode) : false;
+}
+
+int QCameraExposure::isoSensitivity() const
+{
+ if (d_func()->exposureControl)
+ return d_func()->exposureControl->exposureParameter(QCameraExposureControl::ISO).toInt();
+
+ return -1;
+}
+
+/*!
+ Returns the list of ISO senitivities camera supports.
+
+ If the camera supports arbitrary ISO sensitivities within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+ \since 1.1
+*/
+QList<int> QCameraExposure::supportedIsoSensitivities(bool *continuous) const
+{
+ QList<int> res;
+ QCameraExposureControl *control = d_func()->exposureControl;
+
+ if (!control)
+ return res;
+
+ foreach (const QVariant &value,
+ control->supportedParameterRange(QCameraExposureControl::ISO)) {
+ bool ok = false;
+ int intValue = value.toInt(&ok);
+ if (ok)
+ res.append(intValue);
+ else
+ qWarning() << "Incompatible ISO value type, int is expected";
+ }
+
+ if (continuous)
+ *continuous = control->exposureParameterFlags(QCameraExposureControl::ISO) &
+ QCameraExposureControl::ContinuousRange;
+
+ return res;
+}
+
+/*!
+ \fn QCameraExposure::setManualIsoSensitivity(int iso)
+ Sets the manual sensitivity to \a iso
+ \since 1.1
+*/
+
+void QCameraExposure::setManualIsoSensitivity(int iso)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::ISO, QVariant(iso));
+}
+
+/*!
+ \fn QCameraExposure::setAutoIsoSensitivity()
+ Turn on auto sensitivity
+ \since 1.1
+*/
+
+void QCameraExposure::setAutoIsoSensitivity()
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::ISO, QVariant());
+}
+
+/*!
+ \property QCameraExposure::shutterSpeed
+ \brief Camera's shutter speed in seconds.
+
+ \since 1.1
+ \sa supportedShutterSpeeds(), setAutoShutterSpeed(), setManualShutterSpeed()
+*/
+
+/*!
+ \fn QCameraExposure::shutterSpeedChanged(qreal speed)
+
+ Signals that a camera's shutter \a speed has changed.
+ \since 1.1
+*/
+
+/*!
+ \property QCameraExposure::isoSensitivity
+ \brief The sensor ISO sensitivity.
+
+ \sa supportedIsoSensitivities(), setAutoIsoSensitivity(), setManualIsoSensitivity()
+ \since 1.1
+*/
+
+/*!
+ \property QCameraExposure::aperture
+ \brief Lens aperture is specified as an F number, the ratio of the focal length to effective aperture diameter.
+
+ \since 1.1
+ \sa supportedApertures(), setAutoAperture(), setManualAperture()
+*/
+
+
+qreal QCameraExposure::aperture() const
+{
+ if (d_func()->exposureControl)
+ return d_func()->exposureControl->exposureParameter(QCameraExposureControl::Aperture).toReal();
+
+ return -1.0;
+}
+
+/*!
+ Returns the list of aperture values camera supports.
+ The apertures list can change depending on the focal length,
+ in such a case the apertureRangeChanged() signal is emitted.
+
+ If the camera supports arbitrary aperture values within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+ \since 1.1
+*/
+QList<qreal> QCameraExposure::supportedApertures(bool * continuous) const
+{
+ QList<qreal> res;
+ QCameraExposureControl *control = d_func()->exposureControl;
+
+ if (!control)
+ return res;
+
+ foreach (const QVariant &value,
+ control->supportedParameterRange(QCameraExposureControl::Aperture)) {
+ bool ok = false;
+ qreal realValue = value.toReal(&ok);
+ if (ok)
+ res.append(realValue);
+ else
+ qWarning() << "Incompatible aperture value type, qreal is expected";
+ }
+
+ if (continuous)
+ *continuous = control->exposureParameterFlags(QCameraExposureControl::Aperture) &
+ QCameraExposureControl::ContinuousRange;
+
+ return res;
+}
+
+/*!
+ \fn QCameraExposure::setManualAperture(qreal aperture)
+ Sets the manual camera \a aperture value.
+ \since 1.1
+*/
+
+void QCameraExposure::setManualAperture(qreal aperture)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::Aperture, QVariant(aperture));
+}
+
+/*!
+ \fn QCameraExposure::setAutoAperture()
+ Turn on auto aperture
+ \since 1.1
+*/
+
+void QCameraExposure::setAutoAperture()
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::Aperture, QVariant());
+}
+
+/*!
+ Returns the current shutter speed in seconds.
+ \since 1.1
+*/
+
+qreal QCameraExposure::shutterSpeed() const
+{
+ if (d_func()->exposureControl)
+ return d_func()->exposureControl->exposureParameter(QCameraExposureControl::ShutterSpeed).toReal();
+
+ return -1.0;
+}
+
+/*!
+ Returns the list of shutter speed values in seconds camera supports.
+
+ If the camera supports arbitrary shutter speed values within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+ \since 1.1
+*/
+QList<qreal> QCameraExposure::supportedShutterSpeeds(bool *continuous) const
+{
+ QList<qreal> res;
+
+ QCameraExposureControl *control = d_func()->exposureControl;
+ if (!control)
+ return res;
+
+ foreach (const QVariant &value,
+ control->supportedParameterRange(QCameraExposureControl::ShutterSpeed)) {
+ bool ok = false;
+ qreal realValue = value.toReal(&ok);
+ if (ok)
+ res.append(realValue);
+ else
+ qWarning() << "Incompatible shutter speed value type, qreal is expected";
+ }
+
+ if (continuous)
+ *continuous = control->exposureParameterFlags(QCameraExposureControl::ShutterSpeed) &
+ QCameraExposureControl::ContinuousRange;
+
+ return res;
+}
+
+/*!
+ Set the manual shutter speed to \a seconds
+ \since 1.1
+*/
+
+void QCameraExposure::setManualShutterSpeed(qreal seconds)
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::ShutterSpeed, QVariant(seconds));
+}
+
+/*!
+ Turn on auto shutter speed
+ \since 1.1
+*/
+
+void QCameraExposure::setAutoShutterSpeed()
+{
+ if (d_func()->exposureControl)
+ d_func()->exposureControl->setExposureParameter(QCameraExposureControl::ShutterSpeed, QVariant());
+}
+
+
+/*!
+ \enum QCameraExposure::FlashMode
+
+ \value FlashOff Flash is Off.
+ \value FlashOn Flash is On.
+ \value FlashAuto Automatic flash.
+ \value FlashRedEyeReduction Red eye reduction flash.
+ \value FlashFill Use flash to fillin shadows.
+ \value FlashTorch Constant light source, useful for focusing and video capture.
+ \value FlashSlowSyncFrontCurtain
+ Use the flash in conjunction with a slow shutter speed.
+ This mode allows better exposure of distant objects and/or motion blur effect.
+ \value FlashSlowSyncRearCurtain
+ The similar mode to FlashSlowSyncFrontCurtain but flash is fired at the end of exposure.
+ \value FlashManual Flash power is manualy set.
+*/
+
+/*!
+ \enum QCameraExposure::ExposureMode
+
+ \value ExposureManual Manual mode.
+ \value ExposureAuto Automatic mode.
+ \value ExposureNight Night mode.
+ \value ExposureBacklight Backlight exposure mode.
+ \value ExposureSpotlight Spotlight exposure mode.
+ \value ExposureSports Spots exposure mode.
+ \value ExposureSnow Snow exposure mode.
+ \value ExposureBeach Beach exposure mode.
+ \value ExposureLargeAperture Use larger aperture with small depth of field.
+ \value ExposureSmallAperture Use smaller aperture.
+ \value ExposurePortrait Portrait exposure mode.
+ \value ExposureModeVendor The base value for device specific exposure modes.
+*/
+
+/*!
+ \enum QCameraExposure::MeteringMode
+
+ \value MeteringAverage Center weighted average metering mode.
+ \value MeteringSpot Spot metering mode.
+ \value MeteringMatrix Matrix metering mode.
+*/
+
+/*!
+ \property QCameraExposure::flashReady
+ \brief Indicates if the flash is charged and ready to use.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposure::flashReady(bool ready)
+
+ Signal the flash \a ready status has changed.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposure::apertureChanged(qreal value)
+
+ Signal emitted when aperature changes to \a value.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposure::apertureRangeChanged()
+
+ Signal emitted when aperature range has changed.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraExposure::shutterSpeedRangeChanged()
+
+ Signal emitted when the shutter speed range has changed.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraExposure::isoSensitivityChanged(int value)
+
+ Signal emitted when sensitivity changes to \a value.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposure::exposureCompensationChanged(qreal value)
+
+ Signal emitted when the exposure compensation changes to \a value.
+ \since 1.1
+*/
+
+#include "moc_qcameraexposure.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qcameraexposure.h b/src/multimedia/qcameraexposure.h
new file mode 100644
index 000000000..088e7c036
--- /dev/null
+++ b/src/multimedia/qcameraexposure.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAEXPOSURE_H
+#define QCAMERAEXPOSURE_H
+
+#include <qmediaobject.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QCamera;
+class QCameraExposurePrivate;
+
+class Q_MULTIMEDIA_EXPORT QCameraExposure : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal aperture READ aperture NOTIFY apertureChanged)
+ Q_PROPERTY(qreal shutterSpeed READ shutterSpeed NOTIFY shutterSpeedChanged)
+ Q_PROPERTY(int isoSensitivity READ isoSensitivity NOTIFY isoSensitivityChanged)
+ Q_PROPERTY(qreal exposureCompensation READ exposureCompensation WRITE setExposureCompensation NOTIFY exposureCompensationChanged)
+ Q_PROPERTY(bool flashReady READ isFlashReady NOTIFY flashReady)
+ Q_PROPERTY(QCameraExposure::FlashModes flashMode READ flashMode WRITE setFlashMode)
+ Q_PROPERTY(QCameraExposure::ExposureMode exposureMode READ exposureMode WRITE setExposureMode)
+ Q_PROPERTY(QCameraExposure::MeteringMode meteringMode READ meteringMode WRITE setMeteringMode)
+
+ Q_ENUMS(FlashMode)
+ Q_ENUMS(ExposureMode)
+ Q_ENUMS(MeteringMode)
+public:
+ enum FlashMode {
+ FlashAuto = 0x1,
+ FlashOff = 0x2,
+ FlashOn = 0x4,
+ FlashRedEyeReduction = 0x8,
+ FlashFill = 0x10,
+ FlashTorch = 0x20,
+ FlashSlowSyncFrontCurtain = 0x40,
+ FlashSlowSyncRearCurtain = 0x80,
+ FlashManual = 0x100
+ };
+ Q_DECLARE_FLAGS(FlashModes, FlashMode)
+
+ enum ExposureMode {
+ ExposureAuto = 0,
+ ExposureManual = 1,
+ ExposurePortrait = 2,
+ ExposureNight = 3,
+ ExposureBacklight = 4,
+ ExposureSpotlight = 5,
+ ExposureSports = 6,
+ ExposureSnow = 7,
+ ExposureBeach = 8,
+ ExposureLargeAperture = 9,
+ ExposureSmallAperture = 10,
+ ExposureModeVendor = 1000
+ };
+
+ enum MeteringMode {
+ MeteringMatrix = 1,
+ MeteringAverage = 2,
+ MeteringSpot = 3
+ };
+
+ bool isAvailable() const;
+
+ FlashModes flashMode() const;
+ bool isFlashModeSupported(FlashModes mode) const;
+ bool isFlashReady() const;
+
+ ExposureMode exposureMode() const;
+ bool isExposureModeSupported(ExposureMode mode) const;
+
+ qreal exposureCompensation() const;
+
+ MeteringMode meteringMode() const;
+
+ bool isMeteringModeSupported(MeteringMode mode) const;
+
+ int isoSensitivity() const;
+ QList<int> supportedIsoSensitivities(bool *continuous = 0) const;
+
+ qreal aperture() const;
+ QList<qreal> supportedApertures(bool *continuous = 0) const;
+
+ qreal shutterSpeed() const;
+ QList<qreal> supportedShutterSpeeds(bool *continuous = 0) const;
+
+public Q_SLOTS:
+ void setFlashMode(FlashModes mode);
+ void setExposureMode(ExposureMode mode);
+
+ void setExposureCompensation(qreal ev);
+
+ void setMeteringMode(MeteringMode mode);
+
+ void setManualIsoSensitivity(int iso);
+ void setAutoIsoSensitivity();
+
+ void setManualAperture(qreal aperture);
+ void setAutoAperture();
+
+ void setManualShutterSpeed(qreal seconds);
+ void setAutoShutterSpeed();
+
+Q_SIGNALS:
+ void flashReady(bool);
+
+ void apertureChanged(qreal);
+ void apertureRangeChanged();
+ void shutterSpeedChanged(qreal);
+ void shutterSpeedRangeChanged();
+ void isoSensitivityChanged(int);
+ void exposureCompensationChanged(qreal);
+
+private:
+ friend class QCamera;
+ explicit QCameraExposure(QCamera *parent = 0);
+ virtual ~QCameraExposure();
+
+ Q_DISABLE_COPY(QCameraExposure)
+ Q_DECLARE_PRIVATE(QCameraExposure)
+ Q_PRIVATE_SLOT(d_func(), void _q_exposureParameterChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_exposureParameterRangeChanged(int))
+ QCameraExposurePrivate *d_ptr;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCameraExposure::FlashModes)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCameraExposure::ExposureMode)
+Q_DECLARE_METATYPE(QCameraExposure::FlashModes)
+Q_DECLARE_METATYPE(QCameraExposure::MeteringMode)
+
+Q_MEDIA_ENUM_DEBUG(QCameraExposure, ExposureMode)
+Q_MEDIA_ENUM_DEBUG(QCameraExposure, FlashMode)
+Q_MEDIA_ENUM_DEBUG(QCameraExposure, MeteringMode)
+
+QT_END_HEADER
+
+#endif // QCAMERAEXPOSURE_H
diff --git a/src/multimedia/qcameraexposurecontrol.cpp b/src/multimedia/qcameraexposurecontrol.cpp
new file mode 100644
index 000000000..4a6f655f8
--- /dev/null
+++ b/src/multimedia/qcameraexposurecontrol.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameraexposurecontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraExposureControl
+
+ \brief The QCameraExposureControl class allows controlling camera exposure parameters.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+ You can adjust a number of parameters that will affect images and video taken with
+ the corresponding QCamera object.
+
+ There are a number of different parameters that can be adjusted, including:
+
+ \table
+ \row
+ \header
+ \
+
+ \endtable
+
+ The interface name of QCameraExposureControl is \c com.nokia.Qt.QCameraExposureControl/1.0 as
+ defined in QCameraExposureControl_iid.
+
+ \sa QCamera
+*/
+
+/*!
+ \macro QCameraExposureControl_iid
+
+ \c com.nokia.Qt.QCameraExposureControl/1.0
+
+ Defines the interface name of the QCameraExposureControl class.
+
+ \relates QCameraExposureControl
+*/
+
+/*!
+ Constructs a camera exposure control object with \a parent.
+*/
+QCameraExposureControl::QCameraExposureControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys the camera control object.
+*/
+QCameraExposureControl::~QCameraExposureControl()
+{
+}
+
+/*!
+ \fn QCamera::ExposureMode QCameraExposureControl::exposureMode() const
+
+ Returns the exposure mode.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraExposureControl::setExposureMode(QCameraExposure::ExposureMode mode)
+
+ Set the exposure mode to \a mode.
+ \since 1.1
+*/
+
+
+/*!
+ \fn bool QCameraExposureControl::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+
+ Returns true if the exposure \a mode is supported.
+ \since 1.1
+*/
+
+
+/*!
+ \fn QCameraExposure::MeteringMode QCameraExposureControl::meteringMode() const
+ Returns the current metering mode.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposureControl::setMeteringMode(QCameraExposure::MeteringMode mode)
+
+ Set the metering mode to \a mode.
+ \since 1.1
+*/
+
+
+/*!
+ \fn bool QCameraExposureControl::isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
+ Returns true if the metering \a mode is supported.
+ \since 1.1
+*/
+
+/*!
+ \enum QCameraExposureControl::ExposureParameter
+ \value InvalidParameter
+ Parameter is invalid.
+ \value ISO
+ Camera ISO sensitivity, specified as integer value.
+ \value Aperture
+ Lens aperture is specified as an qreal F number.
+ The supported apertures list can change depending on the focal length,
+ in such a case the exposureParameterRangeChanged() signal is emitted.
+ \value ShutterSpeed
+ Shutter speed in seconds, specified as qreal.
+ \value ExposureCompensation
+ Exposure compensation, specified as qreal EV value.
+ \value FlashPower
+ Manual flash power, specified as qreal value.
+ Accepted power range is [0..1.0],
+ with 0 value means no flash and 1.0 corresponds to full flash power.
+
+ This value is only used in the \l{QCameraExposure::FlashManual}{manual flash mode}.
+ \value FlashCompensation
+ Flash compensation, specified as qreal EV value.
+ \value ExtendedExposureParameter
+ The base value for platform specific extended parameters.
+ For such parameters the sequential values starting from ExtendedExposureParameter shuld be used.
+*/
+
+/*!
+ \enum QCameraExposureControl::ParameterFlag
+ \value AutomaticValue
+ Use the automatic values for parameters.
+ \value ReadOnly
+ Parameters are read only.
+ \value ContinuousRange
+ Parameters are continuous in their range.
+*/
+
+/*!
+ \fn QCameraExposureControl::isParameterSupported(ExposureParameter parameter) const
+
+ Returns true is exposure \a parameter is supported by backend.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraExposureControl::exposureParameter(ExposureParameter parameter) const
+
+ Returns the exposure \a parameter value, or invalid QVariant() if the value is unknown or not supported.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraExposureControl::exposureParameterFlags(ExposureParameter parameter) const
+
+ Returns the properties of exposure \a parameter.
+ \since 1.1
+*/
+
+
+/*!
+ \fn QCameraExposureControl::supportedParameterRange(ExposureParameter parameter) const
+
+ Returns the list of supported \a parameter values;
+ \since 1.1
+*/
+
+/*!
+ \fn bool QCameraExposureControl::setExposureParameter(ExposureParameter parameter, const QVariant& value)
+
+ Set the exposure \a parameter to \a value.
+ If a null or invalid QVariant is passed, backend should choose the value automatically,
+ and if possible report the actual value to user with QCameraExposureControl::exposureParameter().
+
+ Returns true if parameter is supported and value is correct.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraExposureControl::extendedParameterName(ExposureParameter parameter)
+
+ Returns the extended exposure \a parameter name.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposureControl::flashReady(bool ready)
+
+ Signal emitted when flash state changes, flash is charged \a ready.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraExposureControl::exposureParameterChanged(int parameter)
+
+ Signal emitted when the exposure \a parameter has changed.
+ \since 1.1
+*/
+
+/*!
+
+ \fn void QCameraExposureControl::exposureParameterRangeChanged(int parameter)
+
+ Signal emitted when the exposure \a parameter range has changed.
+ \since 1.1
+*/
+
+
+#include "moc_qcameraexposurecontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameraexposurecontrol.h b/src/multimedia/qcameraexposurecontrol.h
new file mode 100644
index 000000000..ff60784bf
--- /dev/null
+++ b/src/multimedia/qcameraexposurecontrol.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAEXPOSURECONTROL_H
+#define QCAMERAEXPOSURECONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcameraexposure.h>
+#include <qcamera.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraExposureControl : public QMediaControl
+{
+ Q_OBJECT
+ Q_ENUMS(ExposureParameter)
+
+public:
+ ~QCameraExposureControl();
+
+ enum ExposureParameter {
+ InvalidParameter = 0,
+ ISO = 1,
+ Aperture = 2,
+ ShutterSpeed = 3,
+ ExposureCompensation = 4,
+ FlashPower = 5,
+ FlashCompensation = 6,
+ ExtendedExposureParameter = 1000
+ };
+
+ enum ParameterFlag {
+ AutomaticValue = 0x01,
+ ReadOnly = 0x02,
+ ContinuousRange = 0x04
+ };
+ Q_DECLARE_FLAGS(ParameterFlags, ParameterFlag)
+
+ virtual QCameraExposure::ExposureMode exposureMode() const = 0;
+ virtual void setExposureMode(QCameraExposure::ExposureMode mode) = 0;
+ virtual bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const = 0;
+
+ virtual QCameraExposure::MeteringMode meteringMode() const = 0;
+ virtual void setMeteringMode(QCameraExposure::MeteringMode mode) = 0;
+ virtual bool isMeteringModeSupported(QCameraExposure::MeteringMode mode) const = 0;
+
+ virtual bool isParameterSupported(ExposureParameter parameter) const = 0;
+ virtual QVariant exposureParameter(ExposureParameter parameter) const = 0;
+ virtual ParameterFlags exposureParameterFlags(ExposureParameter parameter) const = 0;
+ virtual QVariantList supportedParameterRange(ExposureParameter parameter) const = 0;
+ virtual bool setExposureParameter(ExposureParameter parameter, const QVariant& value) = 0;
+
+ virtual QString extendedParameterName(ExposureParameter parameter) = 0;
+
+Q_SIGNALS:
+ void flashReady(bool);
+
+ void exposureParameterChanged(int parameter);
+ void exposureParameterRangeChanged(int parameter);
+
+protected:
+ QCameraExposureControl(QObject* parent = 0);
+};
+
+#define QCameraExposureControl_iid "com.nokia.Qt.QCameraExposureControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraExposureControl, QCameraExposureControl_iid)
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCameraExposureControl::ParameterFlags)
+
+Q_MEDIA_ENUM_DEBUG(QCameraExposureControl, ExposureParameter)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERAEXPOSURECONTROL_H
+
diff --git a/src/multimedia/qcameraflashcontrol.cpp b/src/multimedia/qcameraflashcontrol.cpp
new file mode 100644
index 000000000..34dcbdeb5
--- /dev/null
+++ b/src/multimedia/qcameraflashcontrol.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameraflashcontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraFlashControl
+
+ \brief The QCameraFlashControl class allows controlling a camera's flash.
+
+ \ingroup multimedia-serv
+ \inmodule QtMultimedia
+ \since 1.1
+
+ \inmodule QtMultimedia
+
+ You can set the type of flash effect used when an image is captured, and test to see
+ if the flash hardware is ready to fire.
+
+ You can retrieve this control from the camera object in the usual way:
+
+ Some camera devices may not have flash hardware, or may not be configurable. In that
+ case, there will be no QCameraFlashControl available.
+
+ The interface name of QCameraFlashControl is \c com.nokia.Qt.QCameraFlashControl/1.0 as
+ defined in QCameraFlashControl_iid.
+
+ \sa QCamera
+*/
+
+/*!
+ \macro QCameraFlashControl_iid
+
+ \c com.nokia.Qt.QCameraFlashControl/1.0
+
+ Defines the interface name of the QCameraFlashControl class.
+
+ \relates QCameraFlashControl
+*/
+
+/*!
+ Constructs a camera flash control object with \a parent.
+*/
+QCameraFlashControl::QCameraFlashControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys the camera control object.
+*/
+QCameraFlashControl::~QCameraFlashControl()
+{
+}
+
+/*!
+ \fn QCamera::FlashModes QCameraFlashControl::flashMode() const
+
+ Returns the current flash mode.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode)
+
+ Set the current flash \a mode.
+
+ Usually a single QCameraExposure::FlashMode flag is used,
+ but some non conflicting flags combination are also allowed,
+ like QCameraExposure::FlashManual | QCameraExposure::FlashSlowSyncRearCurtain.
+ \since 1.1
+*/
+
+
+/*!
+ \fn QCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+
+ Return true if the reqested flash \a mode is supported.
+ Some QCameraExposure::FlashMode values can be combined,
+ for example QCameraExposure::FlashManual | QCameraExposure::FlashSlowSyncRearCurtain
+ \since 1.1
+*/
+
+/*!
+ \fn bool QCameraFlashControl::isFlashReady() const
+
+ Returns true if flash is charged.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFlashControl::flashReady(bool ready)
+
+ Signal emitted when flash state changes to \a ready.
+ \since 1.1
+*/
+
+#include "moc_qcameraflashcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameraflashcontrol.h b/src/multimedia/qcameraflashcontrol.h
new file mode 100644
index 000000000..89b3b9d06
--- /dev/null
+++ b/src/multimedia/qcameraflashcontrol.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAFLASHCONTROL_H
+#define QCAMERAFLASHCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcameraexposure.h>
+#include <qcamera.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraFlashControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QCameraFlashControl();
+
+ virtual QCameraExposure::FlashModes flashMode() const = 0;
+ virtual void setFlashMode(QCameraExposure::FlashModes mode) = 0;
+ virtual bool isFlashModeSupported(QCameraExposure::FlashModes mode) const = 0;
+
+ virtual bool isFlashReady() const = 0;
+
+Q_SIGNALS:
+ void flashReady(bool);
+
+protected:
+ QCameraFlashControl(QObject* parent = 0);
+};
+
+#define QCameraFlashControl_iid "com.nokia.Qt.QCameraFlashControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraFlashControl, QCameraFlashControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERAFLASHCONTROL_H
+
diff --git a/src/multimedia/qcamerafocus.cpp b/src/multimedia/qcamerafocus.cpp
new file mode 100644
index 000000000..22a0bbcc9
--- /dev/null
+++ b/src/multimedia/qcamerafocus.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+
+#include <qcamera.h>
+#include <qcamerafocus.h>
+
+#include <qmediaobject_p.h>
+#include <qcameracontrol.h>
+#include <qcameraexposurecontrol.h>
+#include <qcamerafocuscontrol.h>
+#include <qmediarecordercontrol.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qvideodevicecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace
+{
+class CameraFocusRegisterMetaTypes
+{
+public:
+ CameraFocusRegisterMetaTypes()
+ {
+ qRegisterMetaType<QCameraFocus::FocusModes>("QCameraFocus::FocusModes");
+ qRegisterMetaType<QCameraFocus::FocusPointMode>("QCameraFocus::FocusPointMode");
+ }
+} _registerCameraFocusMetaTypes;
+}
+
+
+class QCameraFocusZoneData : public QSharedData
+{
+public:
+ QCameraFocusZoneData():
+ status(QCameraFocusZone::Invalid)
+ {
+
+ }
+
+ QCameraFocusZoneData(const QRectF &_area, QCameraFocusZone::FocusZoneStatus _status):
+ area(_area),
+ status(_status)
+ {
+
+ }
+
+
+ QCameraFocusZoneData(const QCameraFocusZoneData &other):
+ QSharedData(other),
+ area(other.area),
+ status(other.status)
+ {
+ }
+
+ QCameraFocusZoneData& operator=(const QCameraFocusZoneData &other)
+ {
+ area = other.area;
+ status = other.status;
+ return *this;
+ }
+
+ QRectF area;
+ QCameraFocusZone::FocusZoneStatus status;
+};
+
+QCameraFocusZone::QCameraFocusZone()
+ :d(new QCameraFocusZoneData)
+{
+
+}
+
+QCameraFocusZone::QCameraFocusZone(const QRectF &area, QCameraFocusZone::FocusZoneStatus status)
+ :d(new QCameraFocusZoneData(area, status))
+{
+}
+
+QCameraFocusZone::QCameraFocusZone(const QCameraFocusZone &other)
+ :d(other.d)
+{
+
+}
+
+QCameraFocusZone::~QCameraFocusZone()
+{
+
+}
+
+QCameraFocusZone& QCameraFocusZone::operator=(const QCameraFocusZone &other)
+{
+ d = other.d;
+ return *this;
+}
+
+bool QCameraFocusZone::operator==(const QCameraFocusZone &other) const
+{
+ return d == other.d ||
+ (d->area == other.d->area && d->status == other.d->status);
+}
+
+bool QCameraFocusZone::operator!=(const QCameraFocusZone &other) const
+{
+ return !(*this == other);
+}
+
+bool QCameraFocusZone::isValid() const
+{
+ return d->status != Invalid && !d->area.isValid();
+}
+
+QRectF QCameraFocusZone::area() const
+{
+ return d->area;
+}
+
+QCameraFocusZone::FocusZoneStatus QCameraFocusZone::status() const
+{
+ return d->status;
+}
+
+void QCameraFocusZone::setStatus(QCameraFocusZone::FocusZoneStatus status)
+{
+ d->status = status;
+}
+
+
+/*!
+ \class QCameraFocus
+
+
+ \brief The QCameraFocus class provides interface for
+ focus and zoom related camera settings.
+
+ \inmodule QtMultimedia
+ \ingroup camera
+ \since 1.1
+
+*/
+
+
+class QCameraFocusPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QCameraFocus)
+public:
+ void initControls();
+
+ QCameraFocus *q_ptr;
+
+ QCamera *camera;
+ QCameraFocusControl *focusControl;
+};
+
+
+void QCameraFocusPrivate::initControls()
+{
+ Q_Q(QCameraFocus);
+
+ focusControl = 0;
+
+ QMediaService *service = camera->service();
+ if (service)
+ focusControl = qobject_cast<QCameraFocusControl *>(service->requestControl(QCameraFocusControl_iid));
+
+ if (focusControl) {
+ q->connect(focusControl, SIGNAL(opticalZoomChanged(qreal)), q, SIGNAL(opticalZoomChanged(qreal)));
+ q->connect(focusControl, SIGNAL(digitalZoomChanged(qreal)), q, SIGNAL(digitalZoomChanged(qreal)));
+ q->connect(focusControl, SIGNAL(maximumOpticalZoomChanged(qreal)),
+ q, SIGNAL(maximumOpticalZoomChanged(qreal)));
+ q->connect(focusControl, SIGNAL(maximumDigitalZoomChanged(qreal)),
+ q, SIGNAL(maximumDigitalZoomChanged(qreal)));
+ q->connect(focusControl, SIGNAL(focusZonesChanged()), q, SIGNAL(focusZonesChanged()));
+ }
+}
+
+/*!
+ Construct a QCameraFocus for \a camera.
+*/
+
+QCameraFocus::QCameraFocus(QCamera *camera):
+ QObject(camera), d_ptr(new QCameraFocusPrivate)
+{
+ Q_D(QCameraFocus);
+ d->camera = camera;
+ d->q_ptr = this;
+ d->initControls();
+}
+
+
+/*!
+ Destroys the camera focus object.
+*/
+
+QCameraFocus::~QCameraFocus()
+{
+}
+
+/*!
+ Returns true if focus related settings are supported by this camera.
+ \since 1.1
+*/
+bool QCameraFocus::isAvailable() const
+{
+ return d_func()->focusControl != 0;
+}
+
+/*!
+ \property QCameraFocus::focusMode
+ \brief The current camera focus mode.
+
+ \since 1.1
+ \sa QCameraFocus::isFocusModeSupported()
+*/
+
+QCameraFocus::FocusMode QCameraFocus::focusMode() const
+{
+ return d_func()->focusControl ? d_func()->focusControl->focusMode() : QCameraFocus::AutoFocus;
+}
+
+void QCameraFocus::setFocusMode(QCameraFocus::FocusMode mode)
+{
+ if (d_func()->focusControl)
+ d_func()->focusControl->setFocusMode(mode);
+}
+
+/*!
+ Returns true if the focus \a mode is supported by camera.
+ \since 1.1
+*/
+
+bool QCameraFocus::isFocusModeSupported(QCameraFocus::FocusMode mode) const
+{
+ return d_func()->focusControl ? d_func()->focusControl->isFocusModeSupported(mode) : false;
+}
+
+/*!
+ \property QCameraFocus::focusPointMode
+ \brief The current camera focus point selection mode.
+
+ \sa QCameraFocus::isFocusPointModeSupported()
+ \since 1.1
+*/
+
+QCameraFocus::FocusPointMode QCameraFocus::focusPointMode() const
+{
+ return d_func()->focusControl ?
+ d_func()->focusControl->focusPointMode() :
+ QCameraFocus::FocusPointAuto;
+}
+
+void QCameraFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+{
+ if (d_func()->focusControl)
+ d_func()->focusControl->setFocusPointMode(mode);
+ else
+ qWarning("Focus points mode selection is not supported");
+}
+
+/*!
+ Returns true if focus point \a mode is supported.
+ \since 1.1
+ */
+bool QCameraFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+{
+ return d_func()->focusControl ?
+ d_func()->focusControl->isFocusPointModeSupported(mode) :
+ false;
+
+}
+
+/*!
+ \property QCameraFocus::customFocusPoint
+
+ Position of custom focus point, in relative frame coordinates:
+ QPointF(0,0) points to the left top frame point, QPointF(0.5,0.5) points to the frame center.
+
+ Custom focus point is used only in FocusPointCustom focus mode.
+ \since 1.1
+ */
+
+QPointF QCameraFocus::customFocusPoint() const
+{
+ return d_func()->focusControl ?
+ d_func()->focusControl->customFocusPoint() :
+ QPointF(0.5,0.5);
+}
+
+void QCameraFocus::setCustomFocusPoint(const QPointF &point)
+{
+ if (d_func()->focusControl)
+ d_func()->focusControl->setCustomFocusPoint(point);
+ else
+ qWarning("Focus points selection is not supported");
+
+}
+
+/*!
+ \property QCameraFocus::focusZones
+
+ Returns the list of active focus zones.
+
+ If QCamera::FocusPointAuto or QCamera::FocusPointFaceDetection focus mode is selected
+ this method returns the list of zones the camera is actually focused on.
+
+ The coordinates system is the same as for custom focus points:
+ QPointF(0,0) points to the left top frame point, QPointF(0.5,0.5) points to the frame center.
+ \since 1.1
+ */
+QCameraFocusZoneList QCameraFocus::focusZones() const
+{
+ return d_func()->focusControl ?
+ d_func()->focusControl->focusZones() :
+ QCameraFocusZoneList();
+}
+
+/*!
+ Returns the maximum optical zoom
+ \since 1.1
+*/
+
+qreal QCameraFocus::maximumOpticalZoom() const
+{
+ return d_func()->focusControl ? d_func()->focusControl->maximumOpticalZoom() : 1.0;
+}
+
+/*!
+ Returns the maximum digital zoom
+ \since 1.1
+*/
+
+qreal QCameraFocus::maximumDigitalZoom() const
+{
+ return d_func()->focusControl ? d_func()->focusControl->maximumDigitalZoom() : 1.0;
+}
+
+/*!
+ \property QCameraFocus::opticalZoom
+ \brief The current optical zoom value.
+
+ \since 1.1
+ \sa QCameraFocus::digitalZoom
+*/
+
+qreal QCameraFocus::opticalZoom() const
+{
+ return d_func()->focusControl ? d_func()->focusControl->opticalZoom() : 1.0;
+}
+
+/*!
+ \property QCameraFocus::digitalZoom
+ \brief The current digital zoom value.
+
+ \since 1.1
+ \sa QCameraFocus::opticalZoom
+*/
+qreal QCameraFocus::digitalZoom() const
+{
+ return d_func()->focusControl ? d_func()->focusControl->digitalZoom() : 1.0;
+}
+
+
+/*!
+ Set the camera \a optical and \a digital zoom values.
+ \since 1.1
+*/
+void QCameraFocus::zoomTo(qreal optical, qreal digital)
+{
+ if (d_func()->focusControl)
+ d_func()->focusControl->zoomTo(optical, digital);
+ else
+ qWarning("The camera doesn't support zooming.");
+}
+
+/*!
+ \enum QCameraFocus::FocusMode
+
+ \value ManualFocus Manual or fixed focus mode.
+ \value AutoFocus One-shot auto focus mode.
+ \value ContinuousFocus Continuous auto focus mode.
+ \value InfinityFocus Focus strictly to infinity.
+ \value HyperfocalFocus Focus to hyperfocal distance, with with the maximum depth of field achieved.
+ All objects at distances from half of this
+ distance out to infinity will be acceptably sharp.
+ \value MacroFocus One shot auto focus to objects close to camera.
+*/
+
+/*!
+ \enum QCameraFocus::FocusPointMode
+
+ \value FocusPointAuto Automatically select one or multiple focus points.
+ \value FocusPointCenter Focus to the frame center.
+ \value FocusPointFaceDetection Focus on faces in the frame.
+ \value FocusPointCustom Focus to the custom point, defined by QCameraFocus::customFocusPoint property.
+*/
+
+/*!
+ \fn void QCameraFocus::opticalZoomChanged(qreal value)
+
+ Signal emitted when optical zoom value changes to new \a value.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocus::digitalZoomChanged(qreal value)
+
+ Signal emitted when digital zoom value changes to new \a value.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocus::maximumOpticalZoomChanged(qreal zoom)
+
+ Signal emitted when the maximum supported optical \a zoom value changed.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocus::maximumDigitalZoomChanged(qreal zoom)
+
+ Signal emitted when the maximum supported digital \a zoom value changed.
+
+ The maximum supported zoom value can depend on other camera settings,
+ like capture mode or resolution.
+ \since 1.1
+*/
+
+
+
+/*!
+ \fn QCameraFocus::focusZonesChanged()
+
+ Signal is emitted when the set of zones, camera focused on is changed.
+
+ Usually the zones list is changed when the camera is focused.
+ \since 1.1
+*/
+
+
+#include "moc_qcamerafocus.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qcamerafocus.h b/src/multimedia/qcamerafocus.h
new file mode 100644
index 000000000..064af7aa1
--- /dev/null
+++ b/src/multimedia/qcamerafocus.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAFOCUS_H
+#define QCAMERAFOCUS_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qshareddata.h>
+
+#include <qmediaobject.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QCamera;
+
+class QCameraFocusZoneData;
+
+class Q_MULTIMEDIA_EXPORT QCameraFocusZone {
+public:
+ enum FocusZoneStatus {
+ Invalid,
+ Unused,
+ Selected,
+ Focused
+ };
+
+ QCameraFocusZone();
+ QCameraFocusZone(const QRectF &area, FocusZoneStatus status = Selected);
+ QCameraFocusZone(const QCameraFocusZone &other);
+
+ QCameraFocusZone& operator=(const QCameraFocusZone &other);
+ bool operator==(const QCameraFocusZone &other) const;
+ bool operator!=(const QCameraFocusZone &other) const;
+
+ ~QCameraFocusZone();
+
+ bool isValid() const;
+
+ QRectF area() const;
+
+ FocusZoneStatus status() const;
+ void setStatus(FocusZoneStatus status);
+
+private:
+ QSharedDataPointer<QCameraFocusZoneData> d;
+};
+
+typedef QList<QCameraFocusZone> QCameraFocusZoneList;
+
+
+class QCameraFocusPrivate;
+class Q_MULTIMEDIA_EXPORT QCameraFocus : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(FocusMode focusMode READ focusMode WRITE setFocusMode)
+ Q_PROPERTY(FocusPointMode focusPointMode READ focusPointMode WRITE setFocusPointMode)
+ Q_PROPERTY(QPointF customFocusPoint READ customFocusPoint WRITE setCustomFocusPoint)
+ Q_PROPERTY(QCameraFocusZoneList focusZones READ focusZones NOTIFY focusZonesChanged)
+ Q_PROPERTY(qreal opticalZoom READ opticalZoom NOTIFY opticalZoomChanged)
+ Q_PROPERTY(qreal digitalZoom READ digitalZoom NOTIFY digitalZoomChanged)
+
+ Q_ENUMS(FocusMode)
+ Q_ENUMS(FocusPointMode)
+public:
+ enum FocusMode {
+ ManualFocus = 0x1,
+ HyperfocalFocus = 0x02,
+ InfinityFocus = 0x04,
+ AutoFocus = 0x8,
+ ContinuousFocus = 0x10,
+ MacroFocus = 0x20
+ };
+ Q_DECLARE_FLAGS(FocusModes, FocusMode)
+
+ enum FocusPointMode {
+ FocusPointAuto,
+ FocusPointCenter,
+ FocusPointFaceDetection,
+ FocusPointCustom
+ };
+
+ bool isAvailable() const;
+
+ FocusMode focusMode() const;
+ void setFocusMode(FocusMode mode);
+ bool isFocusModeSupported(FocusMode mode) const;
+
+ FocusPointMode focusPointMode() const;
+ void setFocusPointMode(FocusPointMode mode);
+ bool isFocusPointModeSupported(FocusPointMode) const;
+ QPointF customFocusPoint() const;
+ void setCustomFocusPoint(const QPointF &point);
+
+ QCameraFocusZoneList focusZones() const;
+
+ qreal maximumOpticalZoom() const;
+ qreal maximumDigitalZoom() const;
+ qreal opticalZoom() const;
+ qreal digitalZoom() const;
+
+ void zoomTo(qreal opticalZoom, qreal digitalZoom);
+
+Q_SIGNALS:
+ void opticalZoomChanged(qreal);
+ void digitalZoomChanged(qreal);
+
+ void focusZonesChanged();
+
+ void maximumOpticalZoomChanged(qreal);
+ void maximumDigitalZoomChanged(qreal);
+
+private:
+ friend class QCamera;
+ QCameraFocus(QCamera *camera);
+ ~QCameraFocus();
+
+ Q_DISABLE_COPY(QCameraFocus)
+ Q_DECLARE_PRIVATE(QCameraFocus)
+ QCameraFocusPrivate *d_ptr;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCameraFocus::FocusModes)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCameraFocus::FocusModes)
+Q_DECLARE_METATYPE(QCameraFocus::FocusPointMode)
+
+Q_MEDIA_ENUM_DEBUG(QCameraFocus, FocusMode)
+Q_MEDIA_ENUM_DEBUG(QCameraFocus, FocusPointMode)
+
+QT_END_HEADER
+
+#endif // QCAMERAFOCUS_H
diff --git a/src/multimedia/qcamerafocuscontrol.cpp b/src/multimedia/qcamerafocuscontrol.cpp
new file mode 100644
index 000000000..93c466814
--- /dev/null
+++ b/src/multimedia/qcamerafocuscontrol.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcamerafocuscontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraFocusControl
+
+
+ \brief The QCameraFocusControl class supplies control for
+ focusing related camera parameters.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+ The interface name of QCameraFocusControl is \c com.nokia.Qt.QCameraFocusControl/1.0 as
+ defined in QCameraFocusControl_iid.
+
+
+ \sa QMediaService::requestControl(), QCamera
+*/
+
+/*!
+ \macro QCameraFocusControl_iid
+
+ \c com.nokia.Qt.QCameraFocusControl/1.0
+
+ Defines the interface name of the QCameraFocusControl class.
+
+ \relates QCameraFocusControl
+*/
+
+/*!
+ Constructs a camera control object with \a parent.
+*/
+
+QCameraFocusControl::QCameraFocusControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destruct the camera control object.
+*/
+
+QCameraFocusControl::~QCameraFocusControl()
+{
+}
+
+
+/*!
+ \fn QCameraFocus::FocusMode QCameraFocusControl::focusMode() const
+
+ Returns the focus mode being used.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraFocusControl::setFocusMode(QCameraFocus::FocusMode mode)
+
+ Set the focus mode to \a mode.
+ \since 1.1
+*/
+
+
+/*!
+ \fn bool QCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusMode mode) const
+
+ Returns true if focus \a mode is supported.
+ \since 1.1
+*/
+
+
+/*!
+ \fn qreal QCameraFocusControl::maximumOpticalZoom() const
+
+ Returns the maximum optical zoom value, or 1.0 if optical zoom is not supported.
+ \since 1.1
+*/
+
+
+/*!
+ \fn qreal QCameraFocusControl::maximumDigitalZoom() const
+
+ Returns the maximum digital zoom value, or 1.0 if digital zoom is not supported.
+ \since 1.1
+*/
+
+
+/*!
+ \fn qreal QCameraFocusControl::opticalZoom() const
+
+ Return the current optical zoom value.
+ \since 1.1
+*/
+
+/*!
+ \fn qreal QCameraFocusControl::digitalZoom() const
+
+ Return the current digital zoom value.
+ \since 1.1
+*/
+
+
+/*!
+ \fn void QCameraFocusControl::zoomTo(qreal optical, qreal digital)
+
+ Sets \a optical and \a digital zoom values.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraFocusControl::focusPointMode() const
+
+ Returns the camera focus point selection mode.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+
+ Sets the camera focus point selection \a mode.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+
+ Returns true if the camera focus point \a mode is supported.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraFocusControl::customFocusPoint() const
+
+ Return the position of custom focus point, in relative frame coordinates:
+ QPointF(0,0) points to the left top frame point, QPointF(0.5,0.5) points to the frame center.
+
+ Custom focus point is used only in FocusPointCustom focus mode.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraFocusControl::setCustomFocusPoint(const QPointF &point)
+
+ Sets the custom focus \a point.
+
+ If camera supports fixed set of focus points,
+ it should use the nearest supported focus point,
+ and return the actual focus point with QCameraFocusControl::focusZones().
+
+ \since 1.1
+ \sa QCameraFocusControl::customFocusPoint(), QCameraFocusControl::focusZones()
+*/
+
+/*!
+ \fn QCameraFocusControl::focusZones() const
+
+ Returns the list of zones, the camera is using for focusing or focused on.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocusControl::opticalZoomChanged(qreal zoom)
+
+ Signal emitted when the optical \a zoom value changed.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocusControl::digitalZoomChanged(qreal zoom)
+
+ Signal emitted when the digital \a zoom value changed.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocusControl::maximumOpticalZoomChanged(qreal zoom)
+
+ Signal emitted when the maximum supported optical \a zoom value changed.
+ \since 1.1
+*/
+
+/*!
+ \fn void QCameraFocusControl::maximumDigitalZoomChanged(qreal zoom)
+
+ Signal emitted when the maximum supported digital \a zoom value changed.
+
+ The maximum supported zoom value can depend on other camera settings,
+ like capture mode or resolution.
+ \since 1.1
+*/
+
+
+/*!
+ \fn QCameraFocusControl::focusZonesChanged()
+
+ Signal is emitted when the set of zones, camera focused on is changed.
+
+ Usually the zones list is changed when the camera is focused.
+
+ \since 1.1
+ \sa QCameraFocusControl::focusZones()
+*/
+
+
+
+#include "moc_qcamerafocuscontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcamerafocuscontrol.h b/src/multimedia/qcamerafocuscontrol.h
new file mode 100644
index 000000000..20ffe6af1
--- /dev/null
+++ b/src/multimedia/qcamerafocuscontrol.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAFOCUSCONTROL_H
+#define QCAMERAFOCUSCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcamerafocus.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraFocusControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QCameraFocusControl();
+
+ virtual QCameraFocus::FocusMode focusMode() const = 0;
+ virtual void setFocusMode(QCameraFocus::FocusMode mode) = 0;
+ virtual bool isFocusModeSupported(QCameraFocus::FocusMode mode) const = 0;
+
+ virtual qreal maximumOpticalZoom() const = 0;
+ virtual qreal maximumDigitalZoom() const = 0;
+ virtual qreal opticalZoom() const = 0;
+ virtual qreal digitalZoom() const = 0;
+
+ virtual void zoomTo(qreal optical, qreal digital) = 0;
+
+ virtual QCameraFocus::FocusPointMode focusPointMode() const = 0;
+ virtual void setFocusPointMode(QCameraFocus::FocusPointMode mode) = 0;
+ virtual bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const = 0;
+ virtual QPointF customFocusPoint() const = 0;
+ virtual void setCustomFocusPoint(const QPointF &point) = 0;
+
+ virtual QCameraFocusZoneList focusZones() const = 0;
+
+Q_SIGNALS:
+ void opticalZoomChanged(qreal opticalZoom);
+ void digitalZoomChanged(qreal digitalZoom);
+ void focusZonesChanged();
+ void maximumOpticalZoomChanged(qreal);
+ void maximumDigitalZoomChanged(qreal);
+
+protected:
+ QCameraFocusControl(QObject* parent = 0);
+};
+
+#define QCameraFocusControl_iid "com.nokia.Qt.QCameraFocusingControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraFocusControl, QCameraFocusControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERAFOCUSCONTROL_H
+
diff --git a/src/multimedia/qcameraimagecapture.cpp b/src/multimedia/qcameraimagecapture.cpp
new file mode 100644
index 000000000..6b399b684
--- /dev/null
+++ b/src/multimedia/qcameraimagecapture.cpp
@@ -0,0 +1,681 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qcameraimagecapture.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qmediaencodersettings.h>
+#include <qcameracapturedestinationcontrol.h>
+#include <qcameracapturebufferformatcontrol.h>
+
+#include <qimageencodercontrol.h>
+#include <qmediaobject_p.h>
+#include <qmediaservice.h>
+#include <qcamera.h>
+#include <qcameracontrol.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmetaobject.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraImageCapture
+ \inmodule QtMultimedia
+ \ingroup camera
+ \since 1.1
+
+
+ \brief The QCameraImageCapture class is used for the recording of media content.
+
+ The QCameraImageCapture class is a high level images recording class.
+ It's not intended to be used alone but for accessing the media
+ recording functions of other media objects, like QCamera.
+
+ \snippet doc/src/snippets/multimedia-snippets/camera.cpp Camera
+
+ \snippet doc/src/snippets/multimedia-snippets/camera.cpp Camera keys
+
+ \sa QCamera
+*/
+
+namespace
+{
+class MediaRecorderRegisterMetaTypes
+{
+public:
+ MediaRecorderRegisterMetaTypes()
+ {
+ qRegisterMetaType<QCameraImageCapture::Error>("QCameraImageCapture::Error");
+ qRegisterMetaType<QCameraImageCapture::CaptureDestination>("QCameraImageCapture::CaptureDestination");
+ qRegisterMetaType<QCameraImageCapture::CaptureDestinations>("QCameraImageCapture::CaptureDestinations");
+ }
+} _registerRecorderMetaTypes;
+}
+
+
+class QCameraImageCapturePrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QCameraImageCapture)
+public:
+ QCameraImageCapturePrivate();
+
+ QMediaObject *mediaObject;
+
+ QCameraImageCaptureControl *control;
+ QImageEncoderControl *encoderControl;
+ QCameraCaptureDestinationControl *captureDestinationControl;
+ QCameraCaptureBufferFormatControl *bufferFormatControl;
+
+ QCameraImageCapture::Error error;
+ QString errorString;
+
+ void _q_error(int id, int error, const QString &errorString);
+ void _q_readyChanged(bool);
+ void _q_serviceDestroyed();
+
+ void unsetError() { error = QCameraImageCapture::NoError; errorString.clear(); }
+
+ QCameraImageCapture *q_ptr;
+};
+
+QCameraImageCapturePrivate::QCameraImageCapturePrivate():
+ mediaObject(0),
+ control(0),
+ encoderControl(0),
+ captureDestinationControl(0),
+ bufferFormatControl(0),
+ error(QCameraImageCapture::NoError)
+{
+}
+
+void QCameraImageCapturePrivate::_q_error(int id, int error, const QString &errorString)
+{
+ Q_Q(QCameraImageCapture);
+
+ this->error = QCameraImageCapture::Error(error);
+ this->errorString = errorString;
+
+ emit q->error(id, this->error, errorString);
+}
+
+void QCameraImageCapturePrivate::_q_readyChanged(bool ready)
+{
+ Q_Q(QCameraImageCapture);
+ emit q->readyForCaptureChanged(ready);
+}
+
+void QCameraImageCapturePrivate::_q_serviceDestroyed()
+{
+ mediaObject = 0;
+ control = 0;
+ encoderControl = 0;
+ captureDestinationControl = 0;
+ bufferFormatControl = 0;
+}
+
+/*!
+ Constructs a media recorder which records the media produced by \a mediaObject.
+
+ The \a parent is passed to QMediaObject.
+*/
+
+QCameraImageCapture::QCameraImageCapture(QMediaObject *mediaObject, QObject *parent):
+ QObject(parent), d_ptr(new QCameraImageCapturePrivate)
+{
+ Q_D(QCameraImageCapture);
+
+ d->q_ptr = this;
+
+ if (mediaObject)
+ mediaObject->bind(this);
+}
+
+/*!
+ Destroys images capture object.
+*/
+
+QCameraImageCapture::~QCameraImageCapture()
+{
+ Q_D(QCameraImageCapture);
+
+ if (d->mediaObject)
+ d->mediaObject->unbind(this);
+}
+
+/*!
+ \reimp
+ \since 1.1
+*/
+QMediaObject *QCameraImageCapture::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+/*!
+ \reimp
+ \since 1.1
+*/
+bool QCameraImageCapture::setMediaObject(QMediaObject *mediaObject)
+{
+ Q_D(QCameraImageCapture);
+
+ if (d->mediaObject) {
+ if (d->control) {
+ disconnect(d->control, SIGNAL(imageExposed(int)),
+ this, SIGNAL(imageExposed(int)));
+ disconnect(d->control, SIGNAL(imageCaptured(int,QImage)),
+ this, SIGNAL(imageCaptured(int,QImage)));
+ disconnect(d->control, SIGNAL(imageAvailable(int,QVideoFrame)),
+ this, SIGNAL(imageAvailable(int,QVideoFrame)));
+ disconnect(d->control, SIGNAL(imageMetadataAvailable(int,QtMultimedia::MetaData,QVariant)),
+ this, SIGNAL(imageMetadataAvailable(int,QtMultimedia::MetaData,QVariant)));
+ disconnect(d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)),
+ this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
+ disconnect(d->control, SIGNAL(imageSaved(int,QString)),
+ this, SIGNAL(imageSaved(int,QString)));
+ disconnect(d->control, SIGNAL(readyForCaptureChanged(bool)),
+ this, SLOT(_q_readyChanged(bool)));
+ disconnect(d->control, SIGNAL(error(int,int,QString)),
+ this, SLOT(_q_error(int,int,QString)));
+
+ if (d->captureDestinationControl) {
+ disconnect(d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
+ this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+ }
+
+ if (d->bufferFormatControl) {
+ disconnect(d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)),
+ this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)));
+ }
+
+ QMediaService *service = d->mediaObject->service();
+ service->releaseControl(d->control);
+ if (d->encoderControl)
+ service->releaseControl(d->encoderControl);
+ if (d->captureDestinationControl)
+ service->releaseControl(d->captureDestinationControl);
+ if (d->bufferFormatControl)
+ service->releaseControl(d->bufferFormatControl);
+
+ disconnect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
+ }
+ }
+
+ d->mediaObject = mediaObject;
+
+ if (d->mediaObject) {
+ QMediaService *service = mediaObject->service();
+ if (service) {
+ d->control = qobject_cast<QCameraImageCaptureControl*>(service->requestControl(QCameraImageCaptureControl_iid));
+
+ if (d->control) {
+ d->encoderControl = qobject_cast<QImageEncoderControl *>(service->requestControl(QImageEncoderControl_iid));
+ d->captureDestinationControl = qobject_cast<QCameraCaptureDestinationControl *>(
+ service->requestControl(QCameraCaptureDestinationControl_iid));
+ d->bufferFormatControl = qobject_cast<QCameraCaptureBufferFormatControl *>(
+ service->requestControl(QCameraCaptureBufferFormatControl_iid));
+
+ connect(d->control, SIGNAL(imageExposed(int)),
+ this, SIGNAL(imageExposed(int)));
+ connect(d->control, SIGNAL(imageCaptured(int,QImage)),
+ this, SIGNAL(imageCaptured(int,QImage)));
+ connect(d->control, SIGNAL(imageMetadataAvailable(int,QtMultimedia::MetaData,QVariant)),
+ this, SIGNAL(imageMetadataAvailable(int,QtMultimedia::MetaData,QVariant)));
+ connect(d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)),
+ this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
+ connect(d->control, SIGNAL(imageAvailable(int,QVideoFrame)),
+ this, SIGNAL(imageAvailable(int,QVideoFrame)));
+ connect(d->control, SIGNAL(imageSaved(int, QString)),
+ this, SIGNAL(imageSaved(int, QString)));
+ connect(d->control, SIGNAL(readyForCaptureChanged(bool)),
+ this, SLOT(_q_readyChanged(bool)));
+ connect(d->control, SIGNAL(error(int,int,QString)),
+ this, SLOT(_q_error(int,int,QString)));
+
+ if (d->captureDestinationControl) {
+ connect(d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
+ this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+ }
+
+ if (d->bufferFormatControl) {
+ connect(d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)),
+ this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)));
+ }
+
+ connect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
+
+ return true;
+ }
+ }
+ }
+
+ // without QCameraImageCaptureControl discard the media object
+ d->mediaObject = 0;
+ d->control = 0;
+ d->encoderControl = 0;
+ d->captureDestinationControl = 0;
+ d->bufferFormatControl = 0;
+
+ return false;
+}
+
+/*!
+ Returns true if the images capture service ready to use.
+ \since 1.1
+*/
+bool QCameraImageCapture::isAvailable() const
+{
+ if (d_func()->control != NULL)
+ return true;
+ else
+ return false;
+}
+
+/*!
+ Returns the availability error code.
+ \since 1.1
+*/
+QtMultimedia::AvailabilityError QCameraImageCapture::availabilityError() const
+{
+ if (d_func()->control != NULL)
+ return QtMultimedia::NoError;
+ else
+ return QtMultimedia::ServiceMissingError;
+}
+
+/*!
+ Returns the current error state.
+
+ \since 1.1
+ \sa errorString()
+*/
+
+QCameraImageCapture::Error QCameraImageCapture::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns a string describing the current error state.
+
+ \since 1.1
+ \sa error()
+*/
+
+QString QCameraImageCapture::errorString() const
+{
+ return d_func()->errorString;
+}
+
+
+/*!
+ Returns a list of supported image codecs.
+ \since 1.1
+*/
+QStringList QCameraImageCapture::supportedImageCodecs() const
+{
+ return d_func()->encoderControl ?
+ d_func()->encoderControl->supportedImageCodecs() : QStringList();
+}
+
+/*!
+ Returns a description of an image \a codec.
+ \since 1.1
+*/
+QString QCameraImageCapture::imageCodecDescription(const QString &codec) const
+{
+ return d_func()->encoderControl ?
+ d_func()->encoderControl->imageCodecDescription(codec) : QString();
+}
+
+/*!
+ Returns a list of resolutions images can be encoded at.
+
+ If non null image \a settings parameter is passed,
+ the returned list is reduced to resolution supported with partial settings like image codec or quality applied.
+
+ If the encoder supports arbitrary resolutions within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+
+ \since 1.1
+ \sa QImageEncoderSettings::resolution()
+*/
+QList<QSize> QCameraImageCapture::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ return d_func()->encoderControl ?
+ d_func()->encoderControl->supportedResolutions(settings, continuous) : QList<QSize>();
+}
+
+/*!
+ Returns the image encoder settings being used.
+
+ \since 1.1
+ \sa setEncodingSettings()
+*/
+
+QImageEncoderSettings QCameraImageCapture::encodingSettings() const
+{
+ return d_func()->encoderControl ?
+ d_func()->encoderControl->imageSettings() : QImageEncoderSettings();
+}
+
+/*!
+ Sets the image encoding \a settings.
+
+ If some parameters are not specified, or null settings are passed,
+ the encoder choose the default encoding parameters.
+
+ \since 1.1
+ \sa encodingSettings()
+*/
+
+void QCameraImageCapture::setEncodingSettings(const QImageEncoderSettings &settings)
+{
+ Q_D(QCameraImageCapture);
+
+ if (d->encoderControl) {
+ QCamera *camera = qobject_cast<QCamera*>(d->mediaObject);
+ if (camera && camera->captureMode() == QCamera::CaptureStillImage) {
+ QMetaObject::invokeMethod(camera,
+ "_q_preparePropertyChange",
+ Qt::DirectConnection,
+ Q_ARG(int, QCameraControl::ImageEncodingSettings));
+ }
+
+ d->encoderControl->setImageSettings(settings);
+ }
+}
+
+/*!
+ Returns the list of supported buffer image capture formats.
+
+ \since 1.1
+ \sa bufferFormat() setBufferFormat()
+*/
+QList<QVideoFrame::PixelFormat> QCameraImageCapture::supportedBufferFormats() const
+{
+ if (d_func()->bufferFormatControl)
+ return d_func()->bufferFormatControl->supportedBufferFormats();
+ else
+ return QList<QVideoFrame::PixelFormat>();
+}
+
+/*!
+ Returns the buffer image capture format being used.
+
+ \since 1.2
+ \sa supportedBufferCaptureFormats() setBufferCaptureFormat()
+*/
+QVideoFrame::PixelFormat QCameraImageCapture::bufferFormat() const
+{
+ if (d_func()->bufferFormatControl)
+ return d_func()->bufferFormatControl->bufferFormat();
+ else
+ return QVideoFrame::Format_Invalid;
+}
+
+/*!
+ Sets the buffer image capture format to be used.
+
+ \since 1.2
+ \sa bufferCaptureFormat() supportedBufferCaptureFormats() captureDestination()
+*/
+void QCameraImageCapture::setBufferFormat(const QVideoFrame::PixelFormat format)
+{
+ if (d_func()->bufferFormatControl)
+ d_func()->bufferFormatControl->setBufferFormat(format);
+}
+
+/*!
+ Returns true if the image capture \a destination is supported; otherwise returns false.
+
+ \since 1.2
+ \sa captureDestination() setCaptureDestination()
+*/
+bool QCameraImageCapture::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+ if (d_func()->captureDestinationControl)
+ return d_func()->captureDestinationControl->isCaptureDestinationSupported(destination);
+ else
+ return destination == CaptureToFile;
+}
+
+/*!
+ Returns the image capture destination being used.
+
+ \since 1.2
+ \sa isCaptureDestinationSupported() setCaptureDestination()
+*/
+QCameraImageCapture::CaptureDestinations QCameraImageCapture::captureDestination() const
+{
+ if (d_func()->captureDestinationControl)
+ return d_func()->captureDestinationControl->captureDestination();
+ else
+ return CaptureToFile;
+}
+
+/*!
+ Sets the capture \a destination to be used.
+
+ \since 1.2
+ \sa isCaptureDestinationSupported() captureDestination()
+*/
+void QCameraImageCapture::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+ Q_D(QCameraImageCapture);
+
+ if (d->captureDestinationControl)
+ d->captureDestinationControl->setCaptureDestination(destination);
+}
+
+/*!
+ \property QCameraImageCapture::readyForCapture
+ Indicates the service is ready to capture a an image immediately.
+ \since 1.1
+*/
+
+bool QCameraImageCapture::isReadyForCapture() const
+{
+ if (d_func()->control)
+ return d_func()->control->isReadyForCapture();
+ else
+ return false;
+}
+
+/*!
+ \fn QCameraImageCapture::readyForCaptureChanged(bool ready)
+
+ Signals that a camera's \a ready for capture state has changed.
+ \since 1.1
+*/
+
+
+/*!
+ Capture the image and save it to \a file.
+ This operation is asynchronous in majority of cases,
+ followed by signals QCameraImageCapture::imageCaptured(), QCameraImageCapture::imageSaved()
+ or QCameraImageCapture::error().
+
+ If an empty \a file is passed, the camera backend choses
+ the default location and naming scheme for photos on the system,
+ if only file name without full path is specified, the image will be saved to
+ the default directory, with a full path reported with imageCaptured() and imageSaved() signals.
+
+ QCameraImageCapture::capture returns the capture Id parameter, used with
+ imageExposed(), imageCaptured() and imageSaved() signals.
+ \since 1.1
+*/
+int QCameraImageCapture::capture(const QString &file)
+{
+ Q_D(QCameraImageCapture);
+
+ d->unsetError();
+
+ if (d->control) {
+ return d->control->capture(file);
+ } else {
+ d->error = NotSupportedFeatureError;
+ d->errorString = tr("Device does not support images capture.");
+
+ emit error(-1, d->error, d->errorString);
+ }
+
+ return -1;
+}
+
+/*!
+ Cancel incomplete capture requests.
+ Already captured and queused for proicessing images may be discarded.
+ \since 1.1
+*/
+void QCameraImageCapture::cancelCapture()
+{
+ Q_D(QCameraImageCapture);
+
+ d->unsetError();
+
+ if (d->control) {
+ d->control->cancelCapture();
+ } else {
+ d->error = NotSupportedFeatureError;
+ d->errorString = tr("Device does not support images capture.");
+
+ emit error(-1, d->error, d->errorString);
+ }
+}
+
+
+/*!
+ \enum QCameraImageCapture::Error
+
+ \value NoError No Errors.
+ \value NotReadyError The service is not ready for capture yet.
+ \value ResourceError Device is not ready or not available.
+ \value NotSupportedFeatureError Device does not support stillimages capture.
+ \value FormatError Current format is not supported.
+ \value OutOfSpaceError No space left on device.
+*/
+
+/*!
+ \enum QCameraImageCapture::DriveMode
+
+ \value SingleImageCapture Drive mode is capturing a single picture.
+*/
+
+/*!
+ \fn QCameraImageCapture::error(int id, QCameraImageCapture::Error error, const QString &errorString)
+
+ Signals that the capture request \a id has failed with an \a error
+ and \a errorString description.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCapture::bufferFormatChanged(QVideoFrame::PixelFormat format)
+
+ Signal emitted when the buffer \a format for the buffer image capture has changed.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCapture::captureDestinationChanged(CaptureDestinations destination)
+
+ Signal emitted when the capture \a destination has changed.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCapture::imageExposed(int id)
+
+ Signal emitted when the frame with request \a id was exposed.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCapture::imageCaptured(int id, const QImage &preview);
+
+ Signal emitted when the frame with request \a id was captured, but not processed and saved yet.
+ Frame \a preview can be displayed to user.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCapture::imageMetadataAvailable(int id, QtMultimedia::MetaData key, const QVariant &value)
+
+ Signals that a metadata for an image with request \a id is available.
+ This signal is emitted for metadata \a value with a \a key listed in QtMultimedia::MetaData enum.
+
+ This signal is emitted between imageExposed and imageSaved signals.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCapture::imageMetadataAvailable(int id, const QString &key, const QVariant &value)
+
+ Signals that a metadata for an image with request \a id is available.
+ This signal is emitted for extended metadata \a value with a \a key not listed in QtMultimedia::MetaData enum.
+
+ This signal is emitted between imageExposed and imageSaved signals.
+ \since 1.2
+*/
+
+
+/*!
+ \fn QCameraImageCapture::imageAvailable(int id, const QVideoFrame &buffer)
+
+ Signal emitted when the frame with request \a id is available as \a buffer.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCapture::imageSaved(int id, const QString &fileName)
+
+ Signal emitted when the frame with request \a id was saved to \a fileName.
+ \since 1.1
+*/
+
+
+#include "moc_qcameraimagecapture.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameraimagecapture.h b/src/multimedia/qcameraimagecapture.h
new file mode 100644
index 000000000..bc4162287
--- /dev/null
+++ b/src/multimedia/qcameraimagecapture.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAIMAGECAPTURE_H
+#define QCAMERAIMAGECAPTURE_H
+
+#include <qmediaobject.h>
+#include <qmediaencodersettings.h>
+#include <qmediabindableinterface.h>
+#include <qvideoframe.h>
+
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QSize;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class QImageEncoderSettings;
+
+class QCameraImageCapturePrivate;
+class Q_MULTIMEDIA_EXPORT QCameraImageCapture : public QObject, public QMediaBindableInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaBindableInterface)
+ Q_ENUMS(Error)
+ Q_ENUMS(CaptureDestination)
+ Q_PROPERTY(bool readyForCapture READ isReadyForCapture NOTIFY readyForCaptureChanged)
+public:
+ enum Error
+ {
+ NoError,
+ NotReadyError,
+ ResourceError,
+ OutOfSpaceError,
+ NotSupportedFeatureError,
+ FormatError
+ };
+
+ enum DriveMode
+ {
+ SingleImageCapture
+ };
+
+ enum CaptureDestination
+ {
+ CaptureToFile = 0x01,
+ CaptureToBuffer = 0x02
+ };
+ Q_DECLARE_FLAGS(CaptureDestinations, CaptureDestination)
+
+ QCameraImageCapture(QMediaObject *mediaObject, QObject *parent = 0);
+ ~QCameraImageCapture();
+
+ bool isAvailable() const;
+ QtMultimedia::AvailabilityError availabilityError() const;
+
+ QMediaObject *mediaObject() const;
+
+ Error error() const;
+ QString errorString() const;
+
+ bool isReadyForCapture() const;
+
+ QStringList supportedImageCodecs() const;
+ QString imageCodecDescription(const QString &codecName) const;
+
+ QList<QSize> supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(),
+ bool *continuous = 0) const;
+
+ QImageEncoderSettings encodingSettings() const;
+ void setEncodingSettings(const QImageEncoderSettings& settings);
+
+ QList<QVideoFrame::PixelFormat> supportedBufferFormats() const;
+ QVideoFrame::PixelFormat bufferFormat() const;
+ void setBufferFormat(QVideoFrame::PixelFormat format);
+
+ bool isCaptureDestinationSupported(CaptureDestinations destination) const;
+ CaptureDestinations captureDestination() const;
+ void setCaptureDestination(CaptureDestinations destination);
+
+public Q_SLOTS:
+ int capture(const QString &location = QString());
+ void cancelCapture();
+
+Q_SIGNALS:
+ void error(int id, QCameraImageCapture::Error error, const QString &errorString);
+
+ void readyForCaptureChanged(bool);
+ void bufferFormatChanged(QVideoFrame::PixelFormat);
+ void captureDestinationChanged(QCameraImageCapture::CaptureDestinations);
+
+ void imageExposed(int id);
+ void imageCaptured(int id, const QImage &preview);
+ void imageMetadataAvailable(int id, QtMultimedia::MetaData key, const QVariant &value);
+ void imageMetadataAvailable(int id, const QString &key, const QVariant &value);
+ void imageAvailable(int id, const QVideoFrame &image);
+ void imageSaved(int id, const QString &fileName);
+
+protected:
+ bool setMediaObject(QMediaObject *);
+
+ QCameraImageCapturePrivate *d_ptr;
+private:
+ Q_DISABLE_COPY(QCameraImageCapture)
+ Q_DECLARE_PRIVATE(QCameraImageCapture)
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_readyChanged(bool))
+ Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed())
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCameraImageCapture::CaptureDestinations)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCameraImageCapture::Error)
+Q_DECLARE_METATYPE(QCameraImageCapture::CaptureDestination)
+Q_DECLARE_METATYPE(QCameraImageCapture::CaptureDestinations)
+
+Q_MEDIA_ENUM_DEBUG(QCameraImageCapture, Error)
+Q_MEDIA_ENUM_DEBUG(QCameraImageCapture, CaptureDestination)
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/multimedia/qcameraimagecapturecontrol.cpp b/src/multimedia/qcameraimagecapturecontrol.cpp
new file mode 100644
index 000000000..ad4c55edb
--- /dev/null
+++ b/src/multimedia/qcameraimagecapturecontrol.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameraimagecapturecontrol.h>
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraImageCaptureControl
+
+ \brief The QCameraImageCaptureControl class provides a control interface
+ for image capture services.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+
+
+ The interface name of QCameraImageCaptureControl is \c com.nokia.Qt.QCameraImageCaptureControl/1.0 as
+ defined in QCameraImageCaptureControl_iid.
+
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ \macro QCameraImageCaptureControl_iid
+
+ \c com.nokia.Qt.QCameraImageCaptureControl/1.0
+
+ Defines the interface name of the QCameraImageCaptureControl class.
+
+ \relates QCameraImageCaptureControl
+*/
+
+/*!
+ Constructs a new image capture control object with the given \a parent
+*/
+QCameraImageCaptureControl::QCameraImageCaptureControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys an image capture control.
+*/
+QCameraImageCaptureControl::~QCameraImageCaptureControl()
+{
+}
+
+/*!
+ \fn QCameraImageCaptureControl::isReadyForCapture() const
+
+ Identifies if a capture control is ready to perform a capture
+ immediately (all the resources necessary for image capture are allocated,
+ hardware initialized, flash is charged, etc).
+
+ Returns true if the camera is ready for capture; and false if it is not.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::readyForCaptureChanged(bool ready)
+
+ Signals that a capture control's \a ready state has changed.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::capture(const QString &fileName)
+
+ Initiates the capture of an image to \a fileName.
+ The \a fileName can be relative or empty,
+ in this case the service should use the system specific place
+ and file naming scheme.
+
+ Returns the capture request id number, which is used later
+ with imageExposed(), imageCaptured() and imageSaved() signals.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::cancelCapture()
+
+ Cancel pending capture requests.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageExposed(int requestId)
+
+ Signals that an image with it \a requestId
+ has just been exposed.
+ This signal can be used for the shutter sound or other indicaton.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageCaptured(int requestId, const QImage &preview)
+
+ Signals that an image with it \a requestId
+ has been captured and a \a preview is available.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageMetadataAvailable(int id, QtMultimedia::MetaData key, const QVariant &value)
+
+ Signals that a metadata for an image with request \a id is available.
+ This signal is emitted for metadata \a value with a \a key listed in QtMultimedia::MetaData enum.
+
+ This signal should be emitted between imageExposed and imageSaved signals.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageMetadataAvailable(int id, const QString &key, const QVariant &value)
+
+ Signals that a metadata for an image with request \a id is available.
+ This signal is emitted for extended metadata \a value with a \a key not listed in QtMultimedia::MetaData enum.
+
+ This signal should be emitted between imageExposed and imageSaved signals.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageAvailable(int requestId, const QVideoFrame &buffer)
+
+ Signals that a captured \a buffer with a \a requestId is available.
+ \since 1.2
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::imageSaved(int requestId, const QString &fileName)
+
+ Signals that a captured image with a \a requestId has been saved
+ to \a fileName.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::driveMode() const
+
+ Returns the current camera drive mode.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+
+ Sets the current camera drive \a mode.
+ \since 1.1
+*/
+
+
+/*!
+ \fn QCameraImageCaptureControl::error(int id, int error, const QString &errorString)
+
+ Signals the capture request \a id failed with \a error code and message \a errorString.
+
+ \since 1.1
+ \sa QCameraImageCapture::Error
+*/
+
+
+#include "moc_qcameraimagecapturecontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameraimagecapturecontrol.h b/src/multimedia/qcameraimagecapturecontrol.h
new file mode 100644
index 000000000..0459c1417
--- /dev/null
+++ b/src/multimedia/qcameraimagecapturecontrol.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAIMAGECAPTURECONTROL_H
+#define QCAMERAIMAGECAPTURECONTROL_H
+
+#include <qmediacontrol.h>
+#include <qcameraimagecapture.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QImage;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QCameraImageCaptureControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QCameraImageCaptureControl();
+
+ virtual bool isReadyForCapture() const = 0;
+
+ virtual QCameraImageCapture::DriveMode driveMode() const = 0;
+ virtual void setDriveMode(QCameraImageCapture::DriveMode mode) = 0;
+
+ virtual int capture(const QString &fileName) = 0;
+ virtual void cancelCapture() = 0;
+
+Q_SIGNALS:
+ void readyForCaptureChanged(bool);
+
+ void imageExposed(int id);
+ void imageCaptured(int id, const QImage &preview);
+ void imageMetadataAvailable(int id, QtMultimedia::MetaData key, const QVariant &value);
+ void imageMetadataAvailable(int id, const QString &key, const QVariant &value);
+ void imageAvailable(int id, const QVideoFrame &buffer);
+ void imageSaved(int id, const QString &fileName);
+
+ void error(int id, int error, const QString &errorString);
+
+protected:
+ QCameraImageCaptureControl(QObject* parent = 0);
+};
+
+#define QCameraImageCaptureControl_iid "com.nokia.Qt.QCameraImageCaptureControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraImageCaptureControl, QCameraImageCaptureControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERAIMAGECAPTURECONTROL_H
+
diff --git a/src/multimedia/qcameraimageprocessing.cpp b/src/multimedia/qcameraimageprocessing.cpp
new file mode 100644
index 000000000..600dfd885
--- /dev/null
+++ b/src/multimedia/qcameraimageprocessing.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+
+#include <qcameraimageprocessing.h>
+
+#include <qmediaobject_p.h>
+#include <qcameracontrol.h>
+#include <qcameraexposurecontrol.h>
+#include <qcamerafocuscontrol.h>
+#include <qmediarecordercontrol.h>
+#include <qcameraimageprocessingcontrol.h>
+#include <qcameraimagecapturecontrol.h>
+#include <qvideodevicecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraImageProcessing
+
+
+ \brief The QCameraImageProcessing class provides interface for
+ focus and zoom related camera settings.
+
+ \inmodule QtMultimedia
+ \ingroup camera
+ \since 1.1
+
+*/
+
+
+class QCameraImageProcessingPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QCameraImageProcessing)
+public:
+ void initControls();
+
+ QCameraImageProcessing *q_ptr;
+
+ QCamera *camera;
+ QCameraImageProcessingControl *imageControl;
+};
+
+
+void QCameraImageProcessingPrivate::initControls()
+{
+ imageControl = 0;
+
+ QMediaService *service = camera->service();
+ if (service)
+ imageControl = qobject_cast<QCameraImageProcessingControl *>(service->requestControl(QCameraImageProcessingControl_iid));
+}
+
+/*!
+ Construct a QCameraImageProcessing for \a camera.
+*/
+
+QCameraImageProcessing::QCameraImageProcessing(QCamera *camera):
+ QObject(camera), d_ptr(new QCameraImageProcessingPrivate)
+{
+ Q_D(QCameraImageProcessing);
+ d->camera = camera;
+ d->q_ptr = this;
+ d->initControls();
+}
+
+
+/*!
+ Destroys the camera focus object.
+*/
+
+QCameraImageProcessing::~QCameraImageProcessing()
+{
+}
+
+
+/*!
+ Returns true if image processing related settings are supported by this camera.
+ \since 1.1
+*/
+bool QCameraImageProcessing::isAvailable() const
+{
+ return d_func()->imageControl != 0;
+}
+
+
+/*!
+ Returns the white balance mode being used.
+ \since 1.1
+*/
+
+QCameraImageProcessing::WhiteBalanceMode QCameraImageProcessing::whiteBalanceMode() const
+{
+ return d_func()->imageControl ? d_func()->imageControl->whiteBalanceMode() : QCameraImageProcessing::WhiteBalanceAuto;
+}
+
+/*!
+ Sets the white balance to \a mode.
+ \since 1.1
+*/
+
+void QCameraImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
+{
+ if (d_func()->imageControl)
+ d_func()->imageControl->setWhiteBalanceMode(mode);
+}
+
+/*!
+ Returns true if the white balance \a mode is supported.
+ \since 1.1
+*/
+
+bool QCameraImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
+{
+ return d_func()->imageControl ? d_func()->imageControl->isWhiteBalanceModeSupported(mode) : false;
+}
+
+/*!
+ Returns the current color temperature if the
+ manual white balance is active, otherwise the
+ return value is undefined.
+ \since 1.1
+*/
+
+int QCameraImageProcessing::manualWhiteBalance() const
+{
+ QVariant value;
+
+ if (d_func()->imageControl)
+ value = d_func()->imageControl->processingParameter(QCameraImageProcessingControl::ColorTemperature);
+
+ return value.toInt();
+}
+
+/*!
+ Sets manual white balance to \a colorTemperature
+ \since 1.1
+*/
+
+void QCameraImageProcessing::setManualWhiteBalance(int colorTemperature)
+{
+ if (d_func()->imageControl) {
+ d_func()->imageControl->setProcessingParameter(
+ QCameraImageProcessingControl::ColorTemperature,
+ QVariant(colorTemperature));
+ }
+}
+
+/*!
+ Return the contrast.
+ \since 1.1
+*/
+int QCameraImageProcessing::contrast() const
+{
+ QVariant value;
+
+ if (d_func()->imageControl)
+ value = d_func()->imageControl->processingParameter(QCameraImageProcessingControl::Contrast);
+
+ return value.toInt();
+}
+
+/*!
+ Set the contrast to \a value.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+ \since 1.1
+*/
+void QCameraImageProcessing::setContrast(int value)
+{
+ if (d_func()->imageControl)
+ d_func()->imageControl->setProcessingParameter(QCameraImageProcessingControl::Contrast,
+ QVariant(value));
+}
+
+/*!
+ Returns the saturation value.
+ \since 1.1
+*/
+int QCameraImageProcessing::saturation() const
+{
+ QVariant value;
+
+ if (d_func()->imageControl)
+ value = d_func()->imageControl->processingParameter(QCameraImageProcessingControl::Saturation);
+
+ return value.toInt();
+}
+
+/*!
+ Sets the saturation value to \a value.
+
+ Valid saturation values range between -100 and 100, the default is 0.
+ \since 1.1
+*/
+
+void QCameraImageProcessing::setSaturation(int value)
+{
+ if (d_func()->imageControl)
+ d_func()->imageControl->setProcessingParameter(QCameraImageProcessingControl::Saturation,
+ QVariant(value));
+}
+
+/*!
+ Identifies if sharpening is supported.
+
+ Returns true if sharpening is supported; and false if it is not.
+ \since 1.1
+*/
+bool QCameraImageProcessing::isSharpeningSupported() const
+{
+ if (d_func()->imageControl)
+ return d_func()->imageControl->isProcessingParameterSupported(QCameraImageProcessingControl::Sharpening);
+ else
+ return false;
+}
+
+/*!
+ Returns the sharpening level.
+ \since 1.1
+*/
+int QCameraImageProcessing::sharpeningLevel() const
+{
+ QVariant value;
+
+ if (d_func()->imageControl)
+ value = d_func()->imageControl->processingParameter(QCameraImageProcessingControl::Sharpening);
+
+ if (value.isNull())
+ return -1;
+ else
+ return value.toInt();
+}
+
+/*!
+ Sets the sharpening \a level.
+
+ Valid sharpening level values range between -1 for default sharpening level,
+ 0 for sharpening disabled and 100 for maximum sharpening applied.
+ \since 1.1
+*/
+
+void QCameraImageProcessing::setSharpeningLevel(int level)
+{
+ Q_D(QCameraImageProcessing);
+ if (d->imageControl)
+ d->imageControl->setProcessingParameter(QCameraImageProcessingControl::Sharpening,
+ level == -1 ? QVariant() : QVariant(level));
+}
+
+/*!
+ Returns true if denoising is supported.
+ \since 1.1
+*/
+bool QCameraImageProcessing::isDenoisingSupported() const
+{
+ if (d_func()->imageControl)
+ return d_func()->imageControl->isProcessingParameterSupported(QCameraImageProcessingControl::Denoising);
+ else
+ return false;
+}
+
+/*!
+ Returns the denoising level.
+ \since 1.1
+*/
+int QCameraImageProcessing::denoisingLevel() const
+{
+ QVariant value;
+
+ if (d_func()->imageControl)
+ value = d_func()->imageControl->processingParameter(QCameraImageProcessingControl::Denoising);
+
+ if (value.isNull())
+ return -1;
+ else
+ return value.toInt();
+}
+
+/*!
+ Sets the denoising \a level.
+
+ Valid denoising level values range between -1 for default denoising level,
+ 0 for denoising disabled and 100 for maximum denoising applied.
+ \since 1.1
+*/
+void QCameraImageProcessing::setDenoisingLevel(int level)
+{
+ Q_D(QCameraImageProcessing);
+ if (d->imageControl)
+ d->imageControl->setProcessingParameter(QCameraImageProcessingControl::Denoising,
+ level == -1 ? QVariant() : QVariant(level));
+}
+
+
+/*!
+ \enum QCameraImageProcessing::WhiteBalanceMode
+
+ \value WhiteBalanceManual Manual white balance. In this mode the white balance should be set with
+ setManualWhiteBalance()
+ \value WhiteBalanceAuto Auto white balance mode.
+ \value WhiteBalanceSunlight Sunlight white balance mode.
+ \value WhiteBalanceCloudy Cloudy white balance mode.
+ \value WhiteBalanceShade Shade white balance mode.
+ \value WhiteBalanceTungsten Tungsten white balance mode.
+ \value WhiteBalanceFluorescent Fluorescent white balance mode.
+ \value WhiteBalanceFlash Flash white balance mode.
+ \value WhiteBalanceSunset Sunset white balance mode.
+ \value WhiteBalanceVendor Vendor defined white balance mode.
+*/
+
+#include "moc_qcameraimageprocessing.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qcameraimageprocessing.h b/src/multimedia/qcameraimageprocessing.h
new file mode 100644
index 000000000..42a7eb589
--- /dev/null
+++ b/src/multimedia/qcameraimageprocessing.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAIMAGEPROCESSING_H
+#define QCAMERAIMAGEPROCESSING_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+#include <qmediaservice.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QCamera;
+
+class QCameraImageProcessingPrivate;
+class Q_MULTIMEDIA_EXPORT QCameraImageProcessing : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(WhiteBalanceMode)
+public:
+ enum WhiteBalanceMode {
+ WhiteBalanceAuto = 0,
+ WhiteBalanceManual = 1,
+ WhiteBalanceSunlight = 2,
+ WhiteBalanceCloudy = 3,
+ WhiteBalanceShade = 4,
+ WhiteBalanceTungsten = 5,
+ WhiteBalanceFluorescent = 6,
+ WhiteBalanceFlash = 7,
+ WhiteBalanceSunset = 8,
+ WhiteBalanceVendor = 1000
+ };
+
+ bool isAvailable() const;
+
+ WhiteBalanceMode whiteBalanceMode() const;
+ void setWhiteBalanceMode(WhiteBalanceMode mode);
+ bool isWhiteBalanceModeSupported(WhiteBalanceMode mode) const;
+ int manualWhiteBalance() const;
+ void setManualWhiteBalance(int colorTemperature);
+
+ int contrast() const;
+ void setContrast(int value);
+
+ int saturation() const;
+ void setSaturation(int value);
+
+ bool isSharpeningSupported() const;
+ int sharpeningLevel() const;
+ void setSharpeningLevel(int value);
+
+ bool isDenoisingSupported() const;
+ int denoisingLevel() const;
+ void setDenoisingLevel(int value);
+
+private:
+ friend class QCamera;
+ QCameraImageProcessing(QCamera *camera);
+ ~QCameraImageProcessing();
+
+ Q_DISABLE_COPY(QCameraImageProcessing)
+ Q_DECLARE_PRIVATE(QCameraImageProcessing)
+ QCameraImageProcessingPrivate *d_ptr;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCameraImageProcessing::WhiteBalanceMode)
+
+Q_MEDIA_ENUM_DEBUG(QCameraImageProcessing, WhiteBalanceMode)
+
+QT_END_HEADER
+
+#endif // QCAMERAIMAGEPROCESSING_H
diff --git a/src/multimedia/qcameraimageprocessingcontrol.cpp b/src/multimedia/qcameraimageprocessingcontrol.cpp
new file mode 100644
index 000000000..5e318cc83
--- /dev/null
+++ b/src/multimedia/qcameraimageprocessingcontrol.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameraimageprocessingcontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraImageProcessingControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+
+ \brief The QCameraImageProcessingControl class provides an abstract class
+ for controlling image processing parameters, like white balance,
+ contrast, saturation, sharpening and denoising.
+
+ The interface name of QCameraImageProcessingControl is \c com.nokia.Qt.QCameraImageProcessingControl/1.0 as
+ defined in QCameraImageProcessingControl_iid.
+
+
+
+ \sa QMediaService::requestControl(), QCamera
+*/
+
+/*!
+ \macro QCameraImageProcessingControl_iid
+
+ \c com.nokia.Qt.QCameraImageProcessingControl/1.0
+
+ Defines the interface name of the QCameraImageProcessingControl class.
+
+ \relates QCameraImageProcessingControl
+*/
+
+/*!
+ Constructs an image processing control object with \a parent.
+*/
+
+QCameraImageProcessingControl::QCameraImageProcessingControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destruct the image processing control object.
+*/
+
+QCameraImageProcessingControl::~QCameraImageProcessingControl()
+{
+}
+
+
+/*!
+ \fn QCameraImageProcessingControl::whiteBalanceMode() const
+ Return the white balance mode being used.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageProcessingControl::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
+ Set the white balance mode to \a mode
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageProcessingControl::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
+ Returns true if the white balance \a mode is supported.
+ The backend should support at least QCameraImageProcessing::WhiteBalanceAuto mode.
+ \since 1.1
+*/
+
+/*!
+ \fn bool QCameraImageProcessingControl::isProcessingParameterSupported(ProcessingParameter parameter) const
+
+ Returns true if the camera supports adjusting image processing \a parameter.
+
+ Usually the the supported settings is static,
+ but some parameter may not be available depending on other
+ camera settings, like presets.
+ In such case the currently supported parameters should be returned.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageProcessingControl::processingParameter(ProcessingParameter parameter) const
+ Returns the image processing \a parameter value.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraImageProcessingControl::setProcessingParameter(ProcessingParameter parameter, QVariant value)
+
+ Sets the image processing \a parameter \a value.
+ Passing the null or invalid QVariant value allows
+ backend to choose the suitable parameter value.
+
+ The valid values range depends on the parameter type,
+ for contrast, saturation and brightness value should be
+ between -100 and 100, the default is 0,
+
+ For sharpening and denoising the range is 0..100,
+ 0 for sharpening or denoising disabled
+ and 100 for maximum sharpening/denoising applied.
+ \since 1.1
+*/
+
+/*!
+ \enum QCameraImageProcessingControl::ProcessingParameter
+
+ \value Contrast
+ Image contrast.
+ \value Saturation
+ Image saturation.
+ \value Brightness
+ Image brightness.
+ \value Sharpening
+ Amount of sharpening applied.
+ \value Denoising
+ Amount of denoising applied.
+ \value ColorTemperature
+ Color temperature in K. This value is used when the manual white balance mode is selected.
+ \value ExtendedParameter
+ The base value for platform specific extended parameters.
+ */
+
+#include "moc_qcameraimageprocessingcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qcameraimageprocessingcontrol.h b/src/multimedia/qcameraimageprocessingcontrol.h
new file mode 100644
index 000000000..8c739287c
--- /dev/null
+++ b/src/multimedia/qcameraimageprocessingcontrol.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERAIMAGEPROCESSINGCONTROL_H
+#define QCAMERAIMAGEPROCESSINGCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcamera.h>
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraImageProcessingControl : public QMediaControl
+{
+ Q_OBJECT
+ Q_ENUMS(ProcessingParameter)
+
+public:
+ ~QCameraImageProcessingControl();
+
+ enum ProcessingParameter {
+ Contrast = 0,
+ Saturation = 1,
+ Brightness = 2,
+ Sharpening = 3,
+ Denoising = 4,
+ ColorTemperature = 5,
+ ExtendedParameter = 1000
+ };
+
+ virtual QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const = 0;
+ virtual void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode) = 0;
+ virtual bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode) const = 0;
+
+ virtual bool isProcessingParameterSupported(ProcessingParameter) const = 0;
+ virtual QVariant processingParameter(ProcessingParameter parameter) const = 0;
+ virtual void setProcessingParameter(ProcessingParameter parameter, QVariant value) = 0;
+
+protected:
+ QCameraImageProcessingControl(QObject* parent = 0);
+};
+
+#define QCameraImageProcessingControl_iid "com.nokia.Qt.QCameraImageProcessingControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraImageProcessingControl, QCameraImageProcessingControl_iid)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCameraImageProcessingControl::ProcessingParameter)
+
+Q_MEDIA_ENUM_DEBUG(QCameraImageProcessingControl, ProcessingParameter)
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/multimedia/qcameralockscontrol.cpp b/src/multimedia/qcameralockscontrol.cpp
new file mode 100644
index 000000000..289a07bf5
--- /dev/null
+++ b/src/multimedia/qcameralockscontrol.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcameralockscontrol.h>
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCameraLocksControl
+
+
+
+ \brief The QCameraLocksControl class is an abstract base class for
+ classes that control still cameras or video cameras.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.1
+
+ This service is provided by a QMediaService object via
+ QMediaService::control(). It is used by QCamera.
+
+ The interface name of QCameraLocksControl is \c com.nokia.Qt.QCameraLocksControl/1.0 as
+ defined in QCameraLocksControl_iid.
+
+
+ \sa QMediaService::requestControl(), QCamera
+*/
+
+/*!
+ \macro QCameraLocksControl_iid
+
+ \c com.nokia.Qt.QCameraLocksControl/1.0
+
+ Defines the interface name of the QCameraLocksControl class.
+
+ \relates QCameraLocksControl
+*/
+
+/*!
+ Constructs a camera locks control object with \a parent.
+*/
+
+QCameraLocksControl::QCameraLocksControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destruct the camera locks control object.
+*/
+
+QCameraLocksControl::~QCameraLocksControl()
+{
+}
+
+/*!
+ \fn QCameraLocksControl::supportedLocks() const
+
+ Returns the lock types, the camera supports.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraLocksControl::lockStatus(QCamera::LockType lock) const
+
+ Returns the camera \a lock status.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraLocksControl::searchAndLock(QCamera::LockTypes locks)
+
+ Request camera \a locks.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraLocksControl::unlock(QCamera::LockTypes locks)
+
+ Unlock camera \a locks.
+ \since 1.1
+*/
+
+/*!
+ \fn QCameraLocksControl::lockStatusChanged(QCamera::LockType lock, QCamera::LockStatus status, QCamera::LockChangeReason reason)
+
+ Signals the \a lock \a status was changed with a specified \a reason.
+ \since 1.1
+*/
+
+
+
+#include "moc_qcameralockscontrol.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qcameralockscontrol.h b/src/multimedia/qcameralockscontrol.h
new file mode 100644
index 000000000..93120ee1a
--- /dev/null
+++ b/src/multimedia/qcameralockscontrol.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCAMERALOCKSCONTROL_H
+#define QCAMERALOCKSCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qcamera.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QCameraLocksControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ ~QCameraLocksControl();
+
+ virtual QCamera::LockTypes supportedLocks() const = 0;
+
+ virtual QCamera::LockStatus lockStatus(QCamera::LockType lock) const = 0;
+
+ virtual void searchAndLock(QCamera::LockTypes locks) = 0;
+ virtual void unlock(QCamera::LockTypes locks) = 0;
+
+Q_SIGNALS:
+ void lockStatusChanged(QCamera::LockType type, QCamera::LockStatus status, QCamera::LockChangeReason reason);
+
+protected:
+ QCameraLocksControl(QObject* parent = 0);
+};
+
+#define QCameraLocksControl_iid "com.nokia.Qt.QCameraLocksControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QCameraLocksControl, QCameraLocksControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QCAMERALOCKSCONTROL_H
+
diff --git a/src/multimedia/qimageencodercontrol.cpp b/src/multimedia/qimageencodercontrol.cpp
new file mode 100644
index 000000000..ee62a502d
--- /dev/null
+++ b/src/multimedia/qimageencodercontrol.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qimageencodercontrol.h"
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QImageEncoderControl
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ \brief The QImageEncoderControl class provides access to the settings of a media service that
+ performs image encoding.
+
+ If a QMediaService supports encoding image data it will implement QImageEncoderControl.
+ This control allows to \l {setImageSettings()}{set image encoding settings} and
+ provides functions for quering supported image \l {supportedImageCodecs()}{codecs} and
+ \l {supportedResolutions()}{resolutions}.
+
+ The interface name of QImageEncoderControl is \c com.nokia.Qt.QImageEncoderControl/1.0 as
+ defined in QImageEncoderControl_iid.
+
+ \sa QImageEncoderSettings, QMediaService::requestControl()
+*/
+
+/*!
+ \macro QImageEncoderControl_iid
+
+ \c com.nokia.Qt.QImageEncoderControl/1.0
+
+ Defines the interface name of the QImageEncoderControl class.
+
+ \relates QImageEncoderControl
+*/
+
+/*!
+ Constructs a new image encoder control object with the given \a parent
+*/
+QImageEncoderControl::QImageEncoderControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys the image encoder control.
+*/
+QImageEncoderControl::~QImageEncoderControl()
+{
+}
+
+/*!
+ \fn QImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(),
+ bool *continuous = 0) const
+
+ Returns a list of supported resolutions.
+
+ If non null image \a settings parameter is passed,
+ the returned list is reduced to resolutions supported with partial settings applied.
+ It can be used to query the list of resolutions, supported by specific image codec.
+
+ If the encoder supports arbitrary resolutions within the supported resolutions range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+ \since 1.0
+*/
+
+/*!
+ \fn QImageEncoderControl::supportedImageCodecs() const
+
+ Returns a list of supported image codecs.
+ \since 1.0
+*/
+
+/*!
+ \fn QImageEncoderControl::imageCodecDescription(const QString &codec) const
+
+ Returns a description of an image \a codec.
+ \since 1.0
+*/
+
+/*!
+ \fn QImageEncoderControl::imageSettings() const
+
+ Returns the currently used image encoder settings.
+
+ The returned value may be different tha passed to QImageEncoderControl::setImageSettings()
+ if the settings contains the default or undefined parameters.
+ In this case if the undefined parameters are already resolved, they should be returned.
+ \since 1.0
+*/
+
+/*!
+ \fn QImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
+
+ Sets the selected image encoder \a settings.
+ \since 1.0
+*/
+
+#include "moc_qimageencodercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qimageencodercontrol.h b/src/multimedia/qimageencodercontrol.h
new file mode 100644
index 000000000..c8a8261a4
--- /dev/null
+++ b/src/multimedia/qimageencodercontrol.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QIMAGEENCODERCONTROL_H
+#define QIMAGEENCODERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediarecorder.h"
+#include "qmediaencodersettings.h"
+
+#include <QtCore/qsize.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QByteArray;
+class QStringList;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QImageEncoderControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QImageEncoderControl();
+
+ virtual QStringList supportedImageCodecs() const = 0;
+ virtual QString imageCodecDescription(const QString &codecName) const = 0;
+
+ virtual QList<QSize> supportedResolutions(const QImageEncoderSettings &settings,
+ bool *continuous = 0) const = 0;
+
+ virtual QImageEncoderSettings imageSettings() const = 0;
+ virtual void setImageSettings(const QImageEncoderSettings &settings) = 0;
+
+protected:
+ QImageEncoderControl(QObject *parent = 0);
+};
+
+#define QImageEncoderControl_iid "com.nokia.Qt.QImageEncoderControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QImageEncoderControl, QImageEncoderControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qlocalmediaplaylistprovider.cpp b/src/multimedia/qlocalmediaplaylistprovider.cpp
new file mode 100644
index 000000000..84d54ecfd
--- /dev/null
+++ b/src/multimedia/qlocalmediaplaylistprovider.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlocalmediaplaylistprovider.h"
+#include "qmediaplaylistprovider_p.h"
+#include "qmediacontent.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLocalMediaPlaylistProviderPrivate: public QMediaPlaylistProviderPrivate
+{
+public:
+ QList<QMediaContent> resources;
+};
+
+QLocalMediaPlaylistProvider::QLocalMediaPlaylistProvider(QObject *parent)
+ :QMediaPlaylistProvider(*new QLocalMediaPlaylistProviderPrivate, parent)
+{
+}
+
+QLocalMediaPlaylistProvider::~QLocalMediaPlaylistProvider()
+{
+}
+
+bool QLocalMediaPlaylistProvider::isReadOnly() const
+{
+ return false;
+}
+
+int QLocalMediaPlaylistProvider::mediaCount() const
+{
+ return d_func()->resources.size();
+}
+
+QMediaContent QLocalMediaPlaylistProvider::media(int pos) const
+{
+ return d_func()->resources.value(pos);
+}
+
+bool QLocalMediaPlaylistProvider::addMedia(const QMediaContent &content)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ int pos = d->resources.count();
+
+ emit mediaAboutToBeInserted(pos, pos);
+ d->resources.append(content);
+ emit mediaInserted(pos, pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ if (items.isEmpty())
+ return true;
+
+ int pos = d->resources.count();
+ int end = pos+items.count()-1;
+
+ emit mediaAboutToBeInserted(pos, end);
+ d->resources.append(items);
+ emit mediaInserted(pos, end);
+
+ return true;
+}
+
+
+bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QMediaContent &content)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ emit mediaAboutToBeInserted(pos, pos);
+ d->resources.insert(pos, content);
+ emit mediaInserted(pos,pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QList<QMediaContent> &items)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ if (items.isEmpty())
+ return true;
+
+ const int last = pos+items.count()-1;
+
+ emit mediaAboutToBeInserted(pos, last);
+ for (int i=0; i<items.count(); i++)
+ d->resources.insert(pos+i, items.at(i));
+ emit mediaInserted(pos, last);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::removeMedia(int fromPos, int toPos)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ Q_ASSERT(fromPos >= 0);
+ Q_ASSERT(fromPos <= toPos);
+ Q_ASSERT(toPos < mediaCount());
+
+ emit mediaAboutToBeRemoved(fromPos, toPos);
+ d->resources.erase(d->resources.begin()+fromPos, d->resources.begin()+toPos+1);
+ emit mediaRemoved(fromPos, toPos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::removeMedia(int pos)
+{
+ Q_D(QLocalMediaPlaylistProvider);
+
+ emit mediaAboutToBeRemoved(pos, pos);
+ d->resources.removeAt(pos);
+ emit mediaRemoved(pos, pos);
+
+ return true;
+}
+
+bool QLocalMediaPlaylistProvider::clear()
+{
+ Q_D(QLocalMediaPlaylistProvider);
+ if (!d->resources.isEmpty()) {
+ int lastPos = mediaCount()-1;
+ emit mediaAboutToBeRemoved(0, lastPos);
+ d->resources.clear();
+ emit mediaRemoved(0, lastPos);
+ }
+
+ return true;
+}
+
+void QLocalMediaPlaylistProvider::shuffle()
+{
+ Q_D(QLocalMediaPlaylistProvider);
+ if (!d->resources.isEmpty()) {
+ QList<QMediaContent> resources;
+
+ while (!d->resources.isEmpty()) {
+ resources.append(d->resources.takeAt(qrand() % d->resources.size()));
+ }
+
+ d->resources = resources;
+ emit mediaChanged(0, mediaCount()-1);
+ }
+
+}
+
+#include "moc_qlocalmediaplaylistprovider.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qlocalmediaplaylistprovider.h b/src/multimedia/qlocalmediaplaylistprovider.h
new file mode 100644
index 000000000..e712a3f73
--- /dev/null
+++ b/src/multimedia/qlocalmediaplaylistprovider.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALMEDIAPAYLISTPROVIDER_H
+#define QLOCALMEDIAPAYLISTPROVIDER_H
+
+#include "qmediaplaylistprovider.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QLocalMediaPlaylistProviderPrivate;
+class Q_MULTIMEDIA_EXPORT QLocalMediaPlaylistProvider : public QMediaPlaylistProvider
+{
+ Q_OBJECT
+public:
+ QLocalMediaPlaylistProvider(QObject *parent=0);
+ virtual ~QLocalMediaPlaylistProvider();
+
+ virtual int mediaCount() const;
+ virtual QMediaContent media(int pos) const;
+
+ virtual bool isReadOnly() const;
+
+ virtual bool addMedia(const QMediaContent &content);
+ virtual bool addMedia(const QList<QMediaContent> &items);
+ virtual bool insertMedia(int pos, const QMediaContent &content);
+ virtual bool insertMedia(int pos, const QList<QMediaContent> &items);
+ virtual bool removeMedia(int pos);
+ virtual bool removeMedia(int start, int end);
+ virtual bool clear();
+
+public Q_SLOTS:
+ virtual void shuffle();
+
+private:
+ Q_DECLARE_PRIVATE(QLocalMediaPlaylistProvider)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QLOCALMEDIAPAYLISTSOURCE_H
diff --git a/src/multimedia/qmediabackgroundplaybackcontrol.cpp b/src/multimedia/qmediabackgroundplaybackcontrol.cpp
new file mode 100644
index 000000000..d7cbd380a
--- /dev/null
+++ b/src/multimedia/qmediabackgroundplaybackcontrol.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediabackgroundplaybackcontrol.h"
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMediaBackgroundPlaybackControl
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 5.0
+
+
+ \brief The QMediaBackgroundPlaybackControl class provides access to the background playback
+ related control of a QMediaService.
+
+ If a QMediaService can play media in background, it should implement QMediaBackgroundPlaybackControl.
+ This control provides a means to set the \l {setContextId()}{contextId} for application,
+ \l {acquire()}{acquire the resource for playback} and \l {release()} {release the playback resource}.
+
+ The interface name of QMediaBackgroundPlaybackControl is \c com.nokia.Qt.QMediaBackgroundPlaybackControl/1.0 as
+ defined in QMediaBackgroundPlaybackControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaBackgroundPlaybackControl_iid
+
+ \c com.nokia.Qt.QMediaBackgroundPlaybackControl/1.0
+
+ Defines the interface name of the QMediaBackgroundPlaybackControl class.
+
+ \relates QMediaBackgroundPlaybackControl
+*/
+
+/*!
+ Destroys a media background playback control.
+*/
+QMediaBackgroundPlaybackControl::~QMediaBackgroundPlaybackControl()
+{
+}
+
+/*!
+ Constructs a new media background playback control with the given \a parent.
+*/
+QMediaBackgroundPlaybackControl::QMediaBackgroundPlaybackControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ \fn QMediaBackgroundPlaybackControl::setContextId(const QString& contextId)
+
+ Sets the contextId for the application, the last contextId will be released if previously set.
+ \l {acquire()}{acquire method} will be automatically invoked after setting a new contextId.
+
+ contextId is an unique string set by the application and is used by the background daemon to
+ distinguish and manage different context for different application.
+
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaBackgroundPlaybackControl::acquire()
+
+ Try to acquire the playback resource for current application
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaBackgroundPlaybackControl::release()
+
+ Give up the playback resource if current applicaiton holds it.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaBackgroundPlaybackControl::isAcquired()
+ \brief indicate whether the background playback resource is granted or not
+
+ It may take sometime for the backend to actually update this value before the first use.
+
+ By default this property is false
+
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaBackgroundPlaybackControl::acquired()
+
+ Signals that the playback resource is acquired
+
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaBackgroundPlaybackControl::lost()
+
+ Signals that the playback resource is lost
+
+ \since 1.0
+*/
+
+#include "moc_qmediabackgroundplaybackcontrol.cpp"
+QT_END_NAMESPACE
+
+
diff --git a/src/multimedia/qmediabackgroundplaybackcontrol.h b/src/multimedia/qmediabackgroundplaybackcontrol.h
new file mode 100644
index 000000000..2cf8d1935
--- /dev/null
+++ b/src/multimedia/qmediabackgroundplaybackcontrol.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIABACKGROUNDPLAYBACKCONTROL_H
+#define QMEDIABACKGROUNDPLAYBACKCONTROL_H
+
+#include "qmediacontrol.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaBackgroundPlaybackControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaBackgroundPlaybackControl();
+
+ virtual void setContextId(const QString& contextId) = 0;
+ virtual void acquire() = 0;
+ virtual void release() = 0;
+
+ virtual bool isAcquired() const = 0;
+
+Q_SIGNALS:
+ void acquired();
+ void lost();
+
+protected:
+ QMediaBackgroundPlaybackControl(QObject* parent = 0);
+};
+
+#define QMediaBackgroundPlaybackControl_iid "com.nokia.Qt.QMediaBackgroundPlaybackControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaBackgroundPlaybackControl, QMediaBackgroundPlaybackControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIABACKGROUNDPLAYBACKCONTROL_H
diff --git a/src/multimedia/qmediabindableinterface.cpp b/src/multimedia/qmediabindableinterface.cpp
new file mode 100644
index 000000000..f5be34dac
--- /dev/null
+++ b/src/multimedia/qmediabindableinterface.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmediabindableinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaBindableInterface
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+
+ \brief The QMediaBindableInterface class is the base class for objects extending media objects functionality.
+
+ \sa
+*/
+
+/*!
+ Destroys a media helper object.
+*/
+
+QMediaBindableInterface::~QMediaBindableInterface()
+{
+}
+
+/*!
+ \fn QMediaBindableInterface::mediaObject() const;
+
+ Return the currently attached media object.
+ \since 1.0
+*/
+
+
+/*!
+ \fn QMediaBindableInterface::setMediaObject(QMediaObject *object);
+
+ Attaches to the media \a object.
+ Returns true if attached successfully, otherwise returns false.
+ \since 1.0
+*/
+
+
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediabindableinterface.h b/src/multimedia/qmediabindableinterface.h
new file mode 100644
index 000000000..02b5b1a21
--- /dev/null
+++ b/src/multimedia/qmediabindableinterface.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIABINDABLEINTERFACE_H
+#define QMEDIABINDABLEINTERFACE_H
+
+#include <qmediaobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaObject;
+
+class Q_MULTIMEDIA_EXPORT QMediaBindableInterface
+{
+public:
+ virtual ~QMediaBindableInterface();
+
+ virtual QMediaObject *mediaObject() const = 0;
+
+protected:
+ friend class QMediaObject;
+ virtual bool setMediaObject(QMediaObject *object) = 0;
+};
+
+#define QMediaBindableInterface_iid \
+ "com.nokia.Qt.QMediaBindableInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaBindableInterface, QMediaBindableInterface_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIABINDABLEINTERFACE_H
diff --git a/src/multimedia/qmediacontainercontrol.cpp b/src/multimedia/qmediacontainercontrol.cpp
new file mode 100644
index 000000000..5a4e618f2
--- /dev/null
+++ b/src/multimedia/qmediacontainercontrol.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmediacontainercontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaContainerControl
+
+ \brief The QMediaContainerControl class provides access to the output container format of a QMediaService
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ If a QMediaService supports writing encoded data it will implement
+ QMediaContainerControl. This control provides information about the output
+ containers supported by a media service and allows one to be selected as
+ the current output containers.
+
+ The functionality provided by this control is exposed to application code
+ through the QMediaRecorder class.
+
+ The interface name of QMediaContainerControl is \c com.nokia.Qt.QMediaContainerControl/1.0 as
+ defined in QMediaContainerControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaRecorder
+*/
+
+/*!
+ \macro QMediaContainerControl_iid
+
+ \c com.nokia.Qt.QMediaContainerControl/1.0
+
+ Defines the interface name of the QMediaContainerControl class.
+
+ \relates QMediaContainerControl
+*/
+
+/*!
+ Constructs a new media container control with the given \a parent.
+*/
+QMediaContainerControl::QMediaContainerControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a media container control.
+*/
+QMediaContainerControl::~QMediaContainerControl()
+{
+}
+
+
+/*!
+ \fn QMediaContainerControl::supportedContainers() const
+
+ Returns a list of MIME types of supported container formats.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaContainerControl::containerMimeType() const
+
+ Returns the MIME type of the selected container format.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaContainerControl::setContainerMimeType(const QString &mimeType)
+
+ Sets the current container format to the format identified by the given \a mimeType.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaContainerControl::containerDescription(const QString &mimeType) const
+
+ Returns a description of the container format identified by the given \a mimeType.
+ \since 1.0
+*/
+
+#include "moc_qmediacontainercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediacontainercontrol.h b/src/multimedia/qmediacontainercontrol.h
new file mode 100644
index 000000000..af48605d0
--- /dev/null
+++ b/src/multimedia/qmediacontainercontrol.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIACONTAINERCONTROL_H
+#define QMEDIACONTAINERCONTROL_H
+
+#include "qmediacontrol.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaContainerControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaContainerControl();
+
+ virtual QStringList supportedContainers() const = 0;
+ virtual QString containerMimeType() const = 0;
+ virtual void setContainerMimeType(const QString &formatMimeType) = 0;
+
+ virtual QString containerDescription(const QString &formatMimeType) const = 0;
+
+protected:
+ QMediaContainerControl(QObject *parent = 0);
+};
+
+#define QMediaContainerControl_iid "com.nokia.Qt.QMediaContainerControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaContainerControl, QMediaContainerControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIACONTAINERCONTROL_H
diff --git a/src/multimedia/qmediacontent.cpp b/src/multimedia/qmediacontent.cpp
new file mode 100644
index 000000000..8cd97bbe0
--- /dev/null
+++ b/src/multimedia/qmediacontent.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+#include "qmediacontent.h"
+
+QT_BEGIN_NAMESPACE
+
+
+class QMediaContentPrivate : public QSharedData
+{
+public:
+ QMediaContentPrivate() {}
+ QMediaContentPrivate(const QMediaResourceList &r):
+ resources(r) {}
+
+ QMediaContentPrivate(const QMediaContentPrivate &other):
+ QSharedData(other),
+ resources(other.resources)
+ {}
+
+ bool operator ==(const QMediaContentPrivate &other) const
+ {
+ return resources == other.resources;
+ }
+
+ QMediaResourceList resources;
+private:
+ QMediaContentPrivate& operator=(const QMediaContentPrivate &other);
+};
+
+
+/*!
+ \class QMediaContent
+
+ \brief The QMediaContent class provides access to the resources relating to a media content.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ QMediaContent is used within the multimedia framework as the logical handle
+ to media content. A QMediaContent object is composed of one or more
+ \l {QMediaResource}s where each resource provides the URL and format
+ information of a different encoding of the content.
+
+ A non-null QMediaContent will always have a primary or canonical reference to
+ the content available through the canonicalUrl() or canonicalResource()
+ methods, any additional resources are optional.
+*/
+
+
+/*!
+ Constructs a null QMediaContent.
+*/
+
+QMediaContent::QMediaContent()
+{
+}
+
+/*!
+ Constructs a media content with \a url providing a reference to the content.
+ \since 1.0
+*/
+
+QMediaContent::QMediaContent(const QUrl &url):
+ d(new QMediaContentPrivate)
+{
+ d->resources << QMediaResource(url);
+}
+
+/*!
+ Constructs a media content with \a request providing a reference to the content.
+
+ This constructor can be used to reference media content via network protocols such as HTTP.
+ This may include additional information required to obtain the resource, such as Cookies or HTTP headers.
+ \since 1.0
+*/
+
+QMediaContent::QMediaContent(const QNetworkRequest &request):
+ d(new QMediaContentPrivate)
+{
+ d->resources << QMediaResource(request);
+}
+
+/*!
+ Constructs a media content with \a resource providing a reference to the content.
+ \since 1.0
+*/
+
+QMediaContent::QMediaContent(const QMediaResource &resource):
+ d(new QMediaContentPrivate)
+{
+ d->resources << resource;
+}
+
+/*!
+ Constructs a media content with \a resources providing a reference to the content.
+ \since 1.0
+*/
+
+QMediaContent::QMediaContent(const QMediaResourceList &resources):
+ d(new QMediaContentPrivate(resources))
+{
+}
+
+/*!
+ Constructs a copy of the media content \a other.
+ \since 1.0
+*/
+
+QMediaContent::QMediaContent(const QMediaContent &other):
+ d(other.d)
+{
+}
+
+/*!
+ Destroys the media content object.
+*/
+
+QMediaContent::~QMediaContent()
+{
+}
+
+/*!
+ Assigns the value of \a other to this media content.
+ \since 1.0
+*/
+
+QMediaContent& QMediaContent::operator=(const QMediaContent &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns true if \a other is equivalent to this media content; false otherwise.
+ \since 1.0
+*/
+
+bool QMediaContent::operator==(const QMediaContent &other) const
+{
+ return (d.constData() == 0 && other.d.constData() == 0) ||
+ (d.constData() != 0 && other.d.constData() != 0 &&
+ *d.constData() == *other.d.constData());
+}
+
+/*!
+ Returns true if \a other is not equivalent to this media content; false otherwise.
+ \since 1.0
+*/
+
+bool QMediaContent::operator!=(const QMediaContent &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Returns true if this media content is null (uninitialized); false otherwise.
+ \since 1.0
+*/
+
+bool QMediaContent::isNull() const
+{
+ return d.constData() == 0;
+}
+
+/*!
+ Returns a QUrl that represents that canonical resource for this media content.
+ \since 1.0
+*/
+
+QUrl QMediaContent::canonicalUrl() const
+{
+ return canonicalResource().url();
+}
+
+/*!
+ Returns a QNetworkRequest that represents that canonical resource for this media content.
+ \since 1.0
+*/
+
+QNetworkRequest QMediaContent::canonicalRequest() const
+{
+ return canonicalResource().request();
+}
+
+/*!
+ Returns a QMediaResource that represents that canonical resource for this media content.
+ \since 1.0
+*/
+
+QMediaResource QMediaContent::canonicalResource() const
+{
+ return d.constData() != 0
+ ? d->resources.value(0)
+ : QMediaResource();
+}
+
+/*!
+ Returns a list of alternative resources for this media content. The first item in this list
+ is always the canonical resource.
+ \since 1.0
+*/
+
+QMediaResourceList QMediaContent::resources() const
+{
+ return d.constData() != 0
+ ? d->resources
+ : QMediaResourceList();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediacontent.h b/src/multimedia/qmediacontent.h
new file mode 100644
index 000000000..cfd109d84
--- /dev/null
+++ b/src/multimedia/qmediacontent.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIACONTENT_H
+#define QMEDIACONTENT_H
+
+#include <QtCore/qmetatype.h>
+#include <QtCore/qshareddata.h>
+
+#include "qmediaresource.h"
+
+#include <qtmultimediadefs.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaContentPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaContent
+{
+public:
+ QMediaContent();
+ QMediaContent(const QUrl &contentUrl);
+ QMediaContent(const QNetworkRequest &contentRequest);
+ QMediaContent(const QMediaResource &contentResource);
+ QMediaContent(const QMediaResourceList &resources);
+ QMediaContent(const QMediaContent &other);
+ ~QMediaContent();
+
+ QMediaContent& operator=(const QMediaContent &other);
+
+ bool operator==(const QMediaContent &other) const;
+ bool operator!=(const QMediaContent &other) const;
+
+ bool isNull() const;
+
+ QUrl canonicalUrl() const;
+ QNetworkRequest canonicalRequest() const;
+ QMediaResource canonicalResource() const;
+
+ QMediaResourceList resources() const;
+
+private:
+ QSharedDataPointer<QMediaContentPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaContent)
+
+QT_END_HEADER
+
+#endif // QMEDIACONTENT_H
diff --git a/src/multimedia/qmediacontrol.cpp b/src/multimedia/qmediacontrol.cpp
new file mode 100644
index 000000000..0cde2cddd
--- /dev/null
+++ b/src/multimedia/qmediacontrol.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+
+#include "qmediacontrol.h"
+#include "qmediacontrol_p.h"
+
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMediaControl class provides a base interface for media service controls.
+
+ Media controls provide an interface to individual features provided by a
+ media service. Most services implement a principal control which exposes
+ the core functionality of the service and a number of optional controls which
+ expose any additional functionality.
+
+ A pointer to a control implemented by a media service can be obtained using
+ the \l {QMediaService::requestControl()} member of QMediaService. If the
+ service doesn't implement a control it will instead return a null pointer.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Request control
+
+ Alternatively if the IId of the control has been declared using
+ Q_MEDIA_DECLARE_CONTROL the template version of
+ QMediaService::requestControl() can be used to request the service without
+ explicitly passing the IId or using qobject_cast().
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Request control templated
+
+ Most application code will not interface directly with a media service's
+ controls, instead the QMediaObject which owns the service acts as an
+ intermediary between one or more controls and the application.
+
+ \sa QMediaService, QMediaObject
+*/
+
+/*!
+ \macro Q_MEDIA_DECLARE_CONTROL(Class, IId)
+ \relates QMediaControl
+
+ The Q_MEDIA_DECLARE_CONTROL macro declares an \a IId for a \a Class that
+ inherits from QMediaControl.
+
+ Declaring an IId for a QMediaControl allows an instance of that control to
+ be requested from QMediaService::requestControl() without explicitly
+ passing the IId.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Request control templated
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ Destroys a media control.
+*/
+
+QMediaControl::~QMediaControl()
+{
+ delete d_ptr;
+}
+
+/*!
+ Constructs a media control with the given \a parent.
+ \since 1.0
+*/
+
+QMediaControl::QMediaControl(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaControlPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+
+QMediaControl::QMediaControl(QMediaControlPrivate &dd, QObject *parent)
+ : QObject(parent)
+ , d_ptr(&dd)
+
+{
+ d_ptr->q_ptr = this;
+}
+
+#include "moc_qmediacontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediacontrol.h b/src/multimedia/qmediacontrol.h
new file mode 100644
index 000000000..3d27026c5
--- /dev/null
+++ b/src/multimedia/qmediacontrol.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIACONTROL_H
+#define QABSTRACTMEDIACONTROL_H
+
+#include <qtmultimediadefs.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaControlPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ ~QMediaControl();
+
+protected:
+ QMediaControl(QObject *parent = 0);
+ QMediaControl(QMediaControlPrivate &dd, QObject *parent = 0);
+
+ QMediaControlPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaControl)
+};
+
+template <typename T> const char *qmediacontrol_iid() { return 0; }
+
+#define Q_MEDIA_DECLARE_CONTROL(Class, IId) \
+ template <> inline const char *qmediacontrol_iid<Class *>() { return IId; }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QABSTRACTMEDIACONTROL_H
diff --git a/src/multimedia/qmediacontrol_p.h b/src/multimedia/qmediacontrol_p.h
new file mode 100644
index 000000000..05693a028
--- /dev/null
+++ b/src/multimedia/qmediacontrol_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIACONTROL_P_H
+#define QABSTRACTMEDIACONTROL_P_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.
+//
+
+#include <qtmultimediadefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaControl;
+
+class QMediaControlPrivate
+{
+public:
+ virtual ~QMediaControlPrivate() {}
+
+ QMediaControl *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmediaencodersettings.cpp b/src/multimedia/qmediaencodersettings.cpp
new file mode 100644
index 000000000..5f85eec37
--- /dev/null
+++ b/src/multimedia/qmediaencodersettings.cpp
@@ -0,0 +1,822 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaencodersettings.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAudioEncoderSettingsPrivate : public QSharedData
+{
+public:
+ QAudioEncoderSettingsPrivate() :
+ isNull(true),
+ encodingMode(QtMultimedia::ConstantQualityEncoding),
+ bitrate(-1),
+ sampleRate(-1),
+ channels(-1),
+ quality(QtMultimedia::NormalQuality)
+ {
+ }
+
+ QAudioEncoderSettingsPrivate(const QAudioEncoderSettingsPrivate &other):
+ QSharedData(other),
+ isNull(other.isNull),
+ encodingMode(other.encodingMode),
+ codec(other.codec),
+ bitrate(other.bitrate),
+ sampleRate(other.sampleRate),
+ channels(other.channels),
+ quality(other.quality)
+ {
+ }
+
+ bool isNull;
+ QtMultimedia::EncodingMode encodingMode;
+ QString codec;
+ int bitrate;
+ int sampleRate;
+ int channels;
+ QtMultimedia::EncodingQuality quality;
+
+private:
+ QAudioEncoderSettingsPrivate& operator=(const QAudioEncoderSettingsPrivate &other);
+};
+
+/*!
+ \class QAudioEncoderSettings
+
+ \brief The QAudioEncoderSettings class provides a set of audio encoder settings.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ A audio encoder settings object is used to specify the audio encoder
+ settings used by QMediaRecorder. Audio encoder settings are selected by
+ constructing a QAudioEncoderSettings object, setting the desired properties
+ and then passing it to a QMediaRecorder instance using the
+ QMediaRecorder::setEncodingSettings() function.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Audio encoder settings
+
+ \sa QMediaRecorder, QAudioEncoderControl
+*/
+
+/*!
+ Construct a null audio encoder settings object.
+*/
+QAudioEncoderSettings::QAudioEncoderSettings()
+ :d(new QAudioEncoderSettingsPrivate)
+{
+}
+
+/*!
+ Constructs a copy of the audio encoder settings object \a other.
+ \since 1.0
+*/
+
+QAudioEncoderSettings::QAudioEncoderSettings(const QAudioEncoderSettings& other)
+ :d(other.d)
+{
+}
+
+/*!
+ Destroys an audio encoder settings object.
+*/
+
+QAudioEncoderSettings::~QAudioEncoderSettings()
+{
+}
+
+/*!
+ Assigns the value of \a other to an audio encoder settings object.
+ \since 1.0
+*/
+
+QAudioEncoderSettings& QAudioEncoderSettings::operator=(const QAudioEncoderSettings &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Determines if \a other is of equal value to an audio encoder settings
+ object.
+
+ Returns true if the settings objects are of equal value, and false if they
+ are not of equal value.
+ \since 1.0
+*/
+
+bool QAudioEncoderSettings::operator==(const QAudioEncoderSettings &other) const
+{
+ return (d == other.d) ||
+ (d->isNull == other.d->isNull &&
+ d->encodingMode == other.d->encodingMode &&
+ d->bitrate == other.d->bitrate &&
+ d->sampleRate == other.d->sampleRate &&
+ d->channels == other.d->channels &&
+ d->quality == other.d->quality &&
+ d->codec == other.d->codec);
+}
+
+/*!
+ Determines if \a other is of equal value to an audio encoder settings
+ object.
+
+ Returns true if the settings objects are not of equal value, and true if
+ they are of equal value.
+ \since 1.0
+*/
+
+bool QAudioEncoderSettings::operator!=(const QAudioEncoderSettings &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Identifies if an audio settings object is initialized.
+
+ Returns true if the settings object is null, and false if it is not.
+ \since 1.0
+*/
+
+bool QAudioEncoderSettings::isNull() const
+{
+ return d->isNull;
+}
+
+/*!
+ Returns the audio encoding mode.
+
+ \since 1.0
+ \sa QtMultimedia::EncodingMode
+*/
+QtMultimedia::EncodingMode QAudioEncoderSettings::encodingMode() const
+{
+ return d->encodingMode;
+}
+
+/*!
+ Sets the audio encoding \a mode setting.
+
+ If QtMultimedia::ConstantQualityEncoding is set, the quality
+ encoding parameter is used and bit rate is ignored,
+ otherwise the bitrate is used.
+
+ The audio codec, channels count and sample rate settings are used in all
+ the encoding modes.
+
+ \since 1.0
+ \sa encodingMode(), QtMultimedia::EncodingMode
+*/
+void QAudioEncoderSettings::setEncodingMode(QtMultimedia::EncodingMode mode)
+{
+ d->encodingMode = mode;
+}
+
+/*!
+ Returns the audio codec.
+ \since 1.0
+*/
+QString QAudioEncoderSettings::codec() const
+{
+ return d->codec;
+}
+
+/*!
+ Sets the audio \a codec.
+ \since 1.0
+*/
+void QAudioEncoderSettings::setCodec(const QString& codec)
+{
+ d->isNull = false;
+ d->codec = codec;
+}
+
+/*!
+ Returns the bit rate of the compressed audio stream in bits per second.
+ \since 1.0
+*/
+int QAudioEncoderSettings::bitRate() const
+{
+ return d->bitrate;
+}
+
+/*!
+ Returns the number of audio channels.
+ \since 1.0
+*/
+int QAudioEncoderSettings::channelCount() const
+{
+ return d->channels;
+}
+
+/*!
+ Sets the number of audio \a channels.
+
+ A value of -1 indicates the encoder should make an optimal choice based on
+ what is available from the audio source and the limitations of the codec.
+ \since 1.0
+*/
+void QAudioEncoderSettings::setChannelCount(int channels)
+{
+ d->isNull = false;
+ d->channels = channels;
+}
+
+/*!
+ Sets the audio bit \a rate in bits per second.
+ \since 1.0
+*/
+void QAudioEncoderSettings::setBitRate(int rate)
+{
+ d->isNull = false;
+ d->bitrate = rate;
+}
+
+/*!
+ Returns the audio sample rate in Hz.
+ \since 1.0
+*/
+int QAudioEncoderSettings::sampleRate() const
+{
+ return d->sampleRate;
+}
+
+/*!
+ Sets the audio sample \a rate in Hz.
+
+ A value of -1 indicates the encoder should make an optimal choice based on what is avaialbe
+ from the audio source and the limitations of the codec.
+ \since 1.0
+ */
+void QAudioEncoderSettings::setSampleRate(int rate)
+{
+ d->isNull = false;
+ d->sampleRate = rate;
+}
+
+/*!
+ Returns the audio encoding quality.
+ \since 1.0
+*/
+
+QtMultimedia::EncodingQuality QAudioEncoderSettings::quality() const
+{
+ return d->quality;
+}
+
+/*!
+ Set the audio encoding \a quality.
+
+ Setting the audio quality parameter allows backend to choose the balanced
+ set of encoding parameters to achieve the desired quality level.
+
+ The \a quality settings parameter is only used in the
+ \l {QtMultimedia::ConstantQualityEncoding}{constant quality} \l{encodingMode()}{encoding mode}.
+ \since 1.0
+*/
+void QAudioEncoderSettings::setQuality(QtMultimedia::EncodingQuality quality)
+{
+ d->isNull = false;
+ d->quality = quality;
+}
+
+class QVideoEncoderSettingsPrivate : public QSharedData
+{
+public:
+ QVideoEncoderSettingsPrivate() :
+ isNull(true),
+ encodingMode(QtMultimedia::ConstantQualityEncoding),
+ bitrate(-1),
+ frameRate(0),
+ quality(QtMultimedia::NormalQuality)
+ {
+ }
+
+ QVideoEncoderSettingsPrivate(const QVideoEncoderSettingsPrivate &other):
+ QSharedData(other),
+ isNull(other.isNull),
+ encodingMode(other.encodingMode),
+ codec(other.codec),
+ bitrate(other.bitrate),
+ resolution(other.resolution),
+ frameRate(other.frameRate),
+ quality(other.quality)
+ {
+ }
+
+ bool isNull;
+ QtMultimedia::EncodingMode encodingMode;
+ QString codec;
+ int bitrate;
+ QSize resolution;
+ qreal frameRate;
+ QtMultimedia::EncodingQuality quality;
+
+private:
+ QVideoEncoderSettingsPrivate& operator=(const QVideoEncoderSettingsPrivate &other);
+};
+
+/*!
+ \class QVideoEncoderSettings
+
+ \brief The QVideoEncoderSettings class provides a set of video encoder settings.
+ \since 1.0
+
+ A video encoder settings object is used to specify the video encoder
+ settings used by QMediaRecorder. Video encoder settings are selected by
+ constructing a QVideoEncoderSettings object, setting the desired properties
+ and then passing it to a QMediaRecorder instance using the
+ QMediaRecorder::setEncodingSettings() function.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Video encoder settings
+
+ \sa QMediaRecorder, QVideoEncoderControl
+*/
+
+/*!
+ Constructs a null video encoder settings object.
+*/
+
+QVideoEncoderSettings::QVideoEncoderSettings()
+ :d(new QVideoEncoderSettingsPrivate)
+{
+}
+
+/*!
+ Constructs a copy of the video encoder settings object \a other.
+ \since 1.0
+*/
+
+QVideoEncoderSettings::QVideoEncoderSettings(const QVideoEncoderSettings& other)
+ :d(other.d)
+{
+}
+
+/*!
+ Destroys a video encoder settings object.
+*/
+
+QVideoEncoderSettings::~QVideoEncoderSettings()
+{
+}
+
+/*!
+ Assigns the value of \a other to a video encoder settings object.
+ \since 1.0
+*/
+QVideoEncoderSettings &QVideoEncoderSettings::operator=(const QVideoEncoderSettings &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Determines if \a other is of equal value to a video encoder settings object.
+
+ Returns true if the settings objects are of equal value, and false if they
+ are not of equal value.
+ \since 1.0
+*/
+bool QVideoEncoderSettings::operator==(const QVideoEncoderSettings &other) const
+{
+ return (d == other.d) ||
+ (d->isNull == other.d->isNull &&
+ d->encodingMode == other.d->encodingMode &&
+ d->bitrate == other.d->bitrate &&
+ d->quality == other.d->quality &&
+ d->codec == other.d->codec &&
+ d->resolution == other.d->resolution &&
+ qFuzzyCompare(d->frameRate, other.d->frameRate));
+}
+
+/*!
+ Determines if \a other is of equal value to a video encoder settings object.
+
+ Returns true if the settings objects are not of equal value, and false if
+ they are of equal value.
+ \since 1.0
+*/
+bool QVideoEncoderSettings::operator!=(const QVideoEncoderSettings &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Identifies if a video encoder settings object is uninitalized.
+
+ Returns true if the settings are null, and false if they are not.
+ \since 1.0
+*/
+bool QVideoEncoderSettings::isNull() const
+{
+ return d->isNull;
+}
+
+/*!
+ Returns the video encoding mode.
+
+ \since 1.0
+ \sa QtMultimedia::EncodingMode
+*/
+QtMultimedia::EncodingMode QVideoEncoderSettings::encodingMode() const
+{
+ return d->encodingMode;
+}
+
+/*!
+ Sets the video encoding \a mode.
+
+ If QtMultimedia::ConstantQualityEncoding is set,
+ the quality encoding parameter is used and bit rate is ignored,
+ otherwise the bitrate is used.
+
+ The rest of encoding settings are respected regardless of encoding mode.
+
+ \since 1.0
+ \sa QtMultimedia::EncodingMode
+*/
+void QVideoEncoderSettings::setEncodingMode(QtMultimedia::EncodingMode mode)
+{
+ d->isNull = false;
+ d->encodingMode = mode;
+}
+
+/*!
+ Returns the video codec.
+ \since 1.0
+*/
+
+QString QVideoEncoderSettings::codec() const
+{
+ return d->codec;
+}
+
+/*!
+ Sets the video \a codec.
+ \since 1.0
+*/
+void QVideoEncoderSettings::setCodec(const QString& codec)
+{
+ d->isNull = false;
+ d->codec = codec;
+}
+
+/*!
+ Returns bit rate of the encoded video stream in bits per second.
+ \since 1.0
+*/
+int QVideoEncoderSettings::bitRate() const
+{
+ return d->bitrate;
+}
+
+/*!
+ Sets the bit rate of the encoded video stream to \a value.
+ \since 1.0
+*/
+
+void QVideoEncoderSettings::setBitRate(int value)
+{
+ d->isNull = false;
+ d->bitrate = value;
+}
+
+/*!
+ Returns the video frame rate.
+ \since 1.0
+*/
+qreal QVideoEncoderSettings::frameRate() const
+{
+ return d->frameRate;
+}
+
+/*!
+ \fn QVideoEncoderSettings::setFrameRate(qreal rate)
+
+ Sets the video frame \a rate.
+
+ A value of 0 indicates the encoder should make an optimal choice based on what is available
+ from the video source and the limitations of the codec.
+ \since 1.0
+*/
+
+void QVideoEncoderSettings::setFrameRate(qreal rate)
+{
+ d->isNull = false;
+ d->frameRate = rate;
+}
+
+/*!
+ Returns the resolution of the encoded video.
+ \since 1.0
+*/
+
+QSize QVideoEncoderSettings::resolution() const
+{
+ return d->resolution;
+}
+
+/*!
+ Sets the \a resolution of the encoded video.
+
+ An empty QSize indicates the encoder should make an optimal choice based on
+ what is available from the video source and the limitations of the codec.
+ \since 1.0
+*/
+
+void QVideoEncoderSettings::setResolution(const QSize &resolution)
+{
+ d->isNull = false;
+ d->resolution = resolution;
+}
+
+/*!
+ Sets the \a width and \a height of the resolution of the encoded video.
+
+ \overload
+ \since 1.0
+*/
+
+void QVideoEncoderSettings::setResolution(int width, int height)
+{
+ d->isNull = false;
+ d->resolution = QSize(width, height);
+}
+
+/*!
+ Returns the video encoding quality.
+ \since 1.0
+*/
+
+QtMultimedia::EncodingQuality QVideoEncoderSettings::quality() const
+{
+ return d->quality;
+}
+
+/*!
+ Sets the video encoding \a quality.
+
+ Setting the video quality parameter allows backend to choose the balanced
+ set of encoding parameters to achieve the desired quality level.
+
+ The \a quality settings parameter is only used in the
+ \l {QtMultimedia::ConstantQualityEncoding}{constant quality} \l{encodingMode()}{encoding mode}.
+ The \a quality settings parameter is only used in the \l
+ {QtMultimedia::ConstantQualityEncoding}{constant quality}
+ \l{encodingMode()}{encoding mode}.
+ \since 1.0
+*/
+
+void QVideoEncoderSettings::setQuality(QtMultimedia::EncodingQuality quality)
+{
+ d->isNull = false;
+ d->quality = quality;
+}
+
+
+
+class QImageEncoderSettingsPrivate : public QSharedData
+{
+public:
+ QImageEncoderSettingsPrivate() :
+ isNull(true),
+ quality(QtMultimedia::NormalQuality)
+ {
+ }
+
+ QImageEncoderSettingsPrivate(const QImageEncoderSettingsPrivate &other):
+ QSharedData(other),
+ isNull(other.isNull),
+ codec(other.codec),
+ resolution(other.resolution),
+ quality(other.quality)
+ {
+ }
+
+ bool isNull;
+ QString codec;
+ QSize resolution;
+ QtMultimedia::EncodingQuality quality;
+
+private:
+ QImageEncoderSettingsPrivate& operator=(const QImageEncoderSettingsPrivate &other);
+};
+
+/*!
+ \class QImageEncoderSettings
+
+
+ \brief The QImageEncoderSettings class provides a set of image encoder
+ settings.
+ \since 1.0
+
+ A image encoder settings object is used to specify the image encoder
+ settings used by QCameraImageCapture. Image encoder settings are selected
+ by constructing a QImageEncoderSettings object, setting the desired
+ properties and then passing it to a QCameraImageCapture instance using the
+ QCameraImageCapture::setImageSettings() function.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Image encoder settings
+
+ \sa QImageEncoderControl
+*/
+
+/*!
+ Constructs a null image encoder settings object.
+*/
+
+QImageEncoderSettings::QImageEncoderSettings()
+ :d(new QImageEncoderSettingsPrivate)
+{
+}
+
+/*!
+ Constructs a copy of the image encoder settings object \a other.
+ \since 1.0
+*/
+
+QImageEncoderSettings::QImageEncoderSettings(const QImageEncoderSettings& other)
+ :d(other.d)
+{
+}
+
+/*!
+ Destroys a image encoder settings object.
+*/
+
+QImageEncoderSettings::~QImageEncoderSettings()
+{
+}
+
+/*!
+ Assigns the value of \a other to a image encoder settings object.
+ \since 1.0
+*/
+QImageEncoderSettings &QImageEncoderSettings::operator=(const QImageEncoderSettings &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Determines if \a other is of equal value to a image encoder settings
+ object.
+
+ Returns true if the settings objects are of equal value, and false if they
+ are not of equal value.
+ \since 1.0
+*/
+bool QImageEncoderSettings::operator==(const QImageEncoderSettings &other) const
+{
+ return (d == other.d) ||
+ (d->isNull == other.d->isNull &&
+ d->quality == other.d->quality &&
+ d->codec == other.d->codec &&
+ d->resolution == other.d->resolution);
+
+}
+
+/*!
+ Determines if \a other is of equal value to a image encoder settings
+ object.
+
+ Returns true if the settings objects are not of equal value, and false if
+ they are of equal value.
+ \since 1.0
+*/
+bool QImageEncoderSettings::operator!=(const QImageEncoderSettings &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Identifies if a image encoder settings object is uninitalized.
+
+ Returns true if the settings are null, and false if they are not.
+ \since 1.0
+*/
+bool QImageEncoderSettings::isNull() const
+{
+ return d->isNull;
+}
+
+/*!
+ Returns the image codec.
+ \since 1.0
+*/
+
+QString QImageEncoderSettings::codec() const
+{
+ return d->codec;
+}
+
+/*!
+ Sets the image \a codec.
+ \since 1.0
+*/
+void QImageEncoderSettings::setCodec(const QString& codec)
+{
+ d->isNull = false;
+ d->codec = codec;
+}
+
+/*!
+ Returns the resolution of the encoded image.
+ \since 1.0
+*/
+
+QSize QImageEncoderSettings::resolution() const
+{
+ return d->resolution;
+}
+
+/*!
+ Sets the \a resolution of the encoded image.
+
+ An empty QSize indicates the encoder should make an optimal choice based on
+ what is available from the image source and the limitations of the codec.
+ \since 1.0
+*/
+
+void QImageEncoderSettings::setResolution(const QSize &resolution)
+{
+ d->isNull = false;
+ d->resolution = resolution;
+}
+
+/*!
+ Sets the \a width and \a height of the resolution of the encoded image.
+
+ \overload
+ \since 1.0
+*/
+
+void QImageEncoderSettings::setResolution(int width, int height)
+{
+ d->isNull = false;
+ d->resolution = QSize(width, height);
+}
+
+/*!
+ Returns the image encoding quality.
+ \since 1.0
+*/
+
+QtMultimedia::EncodingQuality QImageEncoderSettings::quality() const
+{
+ return d->quality;
+}
+
+/*!
+ Sets the image encoding \a quality.
+ \since 1.0
+*/
+
+void QImageEncoderSettings::setQuality(QtMultimedia::EncodingQuality quality)
+{
+ d->isNull = false;
+ d->quality = quality;
+}
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaencodersettings.h b/src/multimedia/qmediaencodersettings.h
new file mode 100644
index 000000000..28bf6d6c8
--- /dev/null
+++ b/src/multimedia/qmediaencodersettings.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAENCODERSETTINGS_H
+#define QMEDIAENCODERSETTINGS_H
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qsize.h>
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class QAudioEncoderSettingsPrivate;
+class Q_MULTIMEDIA_EXPORT QAudioEncoderSettings
+{
+public:
+ QAudioEncoderSettings();
+ QAudioEncoderSettings(const QAudioEncoderSettings& other);
+
+ ~QAudioEncoderSettings();
+
+ QAudioEncoderSettings& operator=(const QAudioEncoderSettings &other);
+ bool operator==(const QAudioEncoderSettings &other) const;
+ bool operator!=(const QAudioEncoderSettings &other) const;
+
+ bool isNull() const;
+
+ QtMultimedia::EncodingMode encodingMode() const;
+ void setEncodingMode(QtMultimedia::EncodingMode);
+
+ QString codec() const;
+ void setCodec(const QString& codec);
+
+ int bitRate() const;
+ void setBitRate(int bitrate);
+
+ int channelCount() const;
+ void setChannelCount(int channels);
+
+ int sampleRate() const;
+ void setSampleRate(int rate);
+
+ QtMultimedia::EncodingQuality quality() const;
+ void setQuality(QtMultimedia::EncodingQuality quality);
+
+private:
+ QSharedDataPointer<QAudioEncoderSettingsPrivate> d;
+};
+
+class QVideoEncoderSettingsPrivate;
+class Q_MULTIMEDIA_EXPORT QVideoEncoderSettings
+{
+public:
+ QVideoEncoderSettings();
+ QVideoEncoderSettings(const QVideoEncoderSettings& other);
+
+ ~QVideoEncoderSettings();
+
+ QVideoEncoderSettings& operator=(const QVideoEncoderSettings &other);
+ bool operator==(const QVideoEncoderSettings &other) const;
+ bool operator!=(const QVideoEncoderSettings &other) const;
+
+ bool isNull() const;
+
+ QtMultimedia::EncodingMode encodingMode() const;
+ void setEncodingMode(QtMultimedia::EncodingMode);
+
+ QString codec() const;
+ void setCodec(const QString &);
+
+ QSize resolution() const;
+ void setResolution(const QSize &);
+ void setResolution(int width, int height);
+
+ qreal frameRate() const;
+ void setFrameRate(qreal rate);
+
+ int bitRate() const;
+ void setBitRate(int bitrate);
+
+ QtMultimedia::EncodingQuality quality() const;
+ void setQuality(QtMultimedia::EncodingQuality quality);
+
+private:
+ QSharedDataPointer<QVideoEncoderSettingsPrivate> d;
+};
+
+class QImageEncoderSettingsPrivate;
+class Q_MULTIMEDIA_EXPORT QImageEncoderSettings
+{
+public:
+ QImageEncoderSettings();
+ QImageEncoderSettings(const QImageEncoderSettings& other);
+
+ ~QImageEncoderSettings();
+
+ QImageEncoderSettings& operator=(const QImageEncoderSettings &other);
+ bool operator==(const QImageEncoderSettings &other) const;
+ bool operator!=(const QImageEncoderSettings &other) const;
+
+ bool isNull() const;
+
+ QString codec() const;
+ void setCodec(const QString &);
+
+ QSize resolution() const;
+ void setResolution(const QSize &);
+ void setResolution(int width, int height);
+
+ QtMultimedia::EncodingQuality quality() const;
+ void setQuality(QtMultimedia::EncodingQuality quality);
+
+private:
+ QSharedDataPointer<QImageEncoderSettingsPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmediaenumdebug.h b/src/multimedia/qmediaenumdebug.h
new file mode 100644
index 000000000..3fa7ee820
--- /dev/null
+++ b/src/multimedia/qmediaenumdebug.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAENUMDEBUG_H
+#define QMEDIAENUMDEBUG_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.
+
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_HEADER
+
+#ifndef QT_NO_DEBUG_STREAM
+
+#define Q_MEDIA_ENUM_DEBUG(Class,Enum) \
+inline QDebug operator<<(QDebug dbg, Class::Enum value) \
+{ \
+ int index = Class::staticMetaObject.indexOfEnumerator(#Enum); \
+ dbg.nospace() << #Class << "::" << Class::staticMetaObject.enumerator(index).valueToKey(value); \
+ return dbg.space(); \
+}
+
+#else
+
+#define Q_MEDIA_ENUM_DEBUG(Class,Enum)
+
+#endif //QT_NO_DEBUG_STREAM
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/multimedia/qmediaimageviewer.cpp b/src/multimedia/qmediaimageviewer.cpp
new file mode 100644
index 000000000..01265dc2f
--- /dev/null
+++ b/src/multimedia/qmediaimageviewer.cpp
@@ -0,0 +1,604 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaimageviewer.h"
+
+#include "qmediaobject_p.h"
+#include "qmediaimageviewerservice_p.h"
+
+#include <qmediaplaylist.h>
+#include <qmediaplaylistsourcecontrol.h>
+#include <qmediacontent.h>
+#include <qmediaresource.h>
+#include <qvideosurfaceoutput_p.h>
+
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qtextstream.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaImageViewerPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaImageViewer)
+public:
+ QMediaImageViewerPrivate():
+ viewerControl(0), playlist(0),
+ state(QMediaImageViewer::StoppedState), timeout(3000), pauseTime(0)
+ {
+ }
+
+ void _q_mediaStatusChanged(QMediaImageViewer::MediaStatus status);
+ void _q_playlistMediaChanged(const QMediaContent &content);
+ void _q_playlistDestroyed();
+
+ QMediaImageViewerControl *viewerControl;
+ QMediaPlaylist *playlist;
+ QPointer<QObject> videoOutput;
+ QVideoSurfaceOutput surfaceOutput;
+ QMediaImageViewer::State state;
+ int timeout;
+ int pauseTime;
+ QTime time;
+ QBasicTimer timer;
+ QMediaContent media;
+};
+
+void QMediaImageViewerPrivate::_q_mediaStatusChanged(QMediaImageViewer::MediaStatus status)
+{
+ switch (status) {
+ case QMediaImageViewer::NoMedia:
+ case QMediaImageViewer::LoadingMedia:
+ emit q_func()->mediaStatusChanged(status);
+ break;
+ case QMediaImageViewer::LoadedMedia:
+ if (state == QMediaImageViewer::PlayingState) {
+ time.start();
+ timer.start(qMax(0, timeout), q_func());
+ q_func()->addPropertyWatch("elapsedTime");
+ }
+ emit q_func()->mediaStatusChanged(status);
+ emit q_func()->elapsedTimeChanged(0);
+ break;
+ case QMediaImageViewer::InvalidMedia:
+ emit q_func()->mediaStatusChanged(status);
+
+ if (state == QMediaImageViewer::PlayingState) {
+ playlist->next();
+ if (playlist->currentIndex() < 0)
+ emit q_func()->stateChanged(state = QMediaImageViewer::StoppedState);
+ }
+ break;
+ }
+}
+
+void QMediaImageViewerPrivate::_q_playlistMediaChanged(const QMediaContent &content)
+{
+ media = content;
+ pauseTime = 0;
+
+ viewerControl->showMedia(media);
+
+ emit q_func()->mediaChanged(media);
+}
+
+void QMediaImageViewerPrivate::_q_playlistDestroyed()
+{
+ playlist = 0;
+ timer.stop();
+
+ if (state != QMediaImageViewer::StoppedState)
+ emit q_func()->stateChanged(state = QMediaImageViewer::StoppedState);
+
+ q_func()->setMedia(QMediaContent());
+}
+
+/*!
+ \class QMediaImageViewer
+ \brief The QMediaImageViewer class provides a means of viewing image media.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+
+ QMediaImageViewer is used together with a media display object such as
+ QVideoWidget to present an image. A display object is attached to the
+ image viewer by means of the bind function.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Binding
+
+ QMediaImageViewer can be paired with a QMediaPlaylist to create a slide
+ show of images. Constructing a QMediaPlaylist with a pointer to an
+ instance of QMediaImageViewer will attach it to the image viewer;
+ changing the playlist's selection will then change the media displayed
+ by the image viewer. With a playlist attached QMediaImageViewer's
+ play(), pause(), and stop() slots can be control the progression of the
+ playlist. The \l timeout property determines how long an image is
+ displayed for before progressing to the next in the playlist, and the
+ \l elapsedTime property holds how the duration the current image has
+ been displayed for.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Playlist
+*/
+
+/*!
+ \enum QMediaImageViewer::State
+
+ Enumerates the possible control states an image viewer may be in. The
+ control state of an image viewer determines whether the image viewer is
+ automatically progressing through images in an attached playlist.
+
+ \value StoppedState The image viewer is stopped, and will not automatically move to the next
+ image. The \l elapsedTime is fixed at 0.
+ \value PlayingState The slide show is playing, and will move to the next image when the
+ \l elapsedTime reaches the \l timeout. The \l elapsedTime is being incremented.
+ \value PausedState The image viewer is paused, and will not automatically move the to next
+ image. The \l elapsedTime is fixed at the time the image viewer was paused.
+*/
+
+/*!
+ \enum QMediaImageViewer::MediaStatus
+
+ Enumerates the status of an image viewer's current media.
+
+ \value NoMedia There is no current media.
+ \value LoadingMedia The image viewer is loading the current media.
+ \value LoadedMedia The image viewer has loaded the current media.
+ \value InvalidMedia The current media cannot be loaded.
+*/
+
+/*!
+ Constructs a new image viewer with the given \a parent.
+*/
+QMediaImageViewer::QMediaImageViewer(QObject *parent)
+ : QMediaObject(*new QMediaImageViewerPrivate, parent, new QMediaImageViewerService)
+{
+ Q_D(QMediaImageViewer);
+
+ d->viewerControl = qobject_cast<QMediaImageViewerControl*>(
+ d->service->requestControl(QMediaImageViewerControl_iid));
+
+ connect(d->viewerControl, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
+ this, SLOT(_q_mediaStatusChanged(QMediaImageViewer::MediaStatus)));
+}
+
+/*!
+ Destroys an image viewer.
+*/
+QMediaImageViewer::~QMediaImageViewer()
+{
+ Q_D(QMediaImageViewer);
+
+ delete d->service;
+}
+
+/*!
+ \property QMediaImageViewer::state
+ \brief the playlist control state of a slide show.
+ \since 1.0
+*/
+
+QMediaImageViewer::State QMediaImageViewer::state() const
+{
+ return d_func()->state;
+}
+
+/*!
+ \fn QMediaImageViewer::stateChanged(QMediaImageViewer::State state)
+
+ Signals that the playlist control \a state of an image viewer has changed.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaImageViewer::mediaStatus
+ \brief the status of the current media.
+ \since 1.0
+*/
+
+QMediaImageViewer::MediaStatus QMediaImageViewer::mediaStatus() const
+{
+ return d_func()->viewerControl->mediaStatus();
+}
+
+/*!
+ \fn QMediaImageViewer::mediaStatusChanged(QMediaImageViewer::MediaStatus status)
+
+ Signals the the \a status of the current media has changed.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaImageViewer::media
+ \brief the media an image viewer is presenting.
+ \since 1.0
+*/
+
+QMediaContent QMediaImageViewer::media() const
+{
+ Q_D(const QMediaImageViewer);
+
+ return d->media;
+}
+
+void QMediaImageViewer::setMedia(const QMediaContent &media)
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->playlist && d->playlist->currentMedia() != media) {
+ disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_playlistMediaChanged(QMediaContent)));
+ disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ d->playlist = 0;
+ }
+
+ d->media = media;
+
+ if (d->timer.isActive()) {
+ d->pauseTime = 0;
+ d->timer.stop();
+ removePropertyWatch("elapsedTime");
+ emit elapsedTimeChanged(0);
+ }
+
+ if (d->state != QMediaImageViewer::StoppedState)
+ emit stateChanged(d->state = QMediaImageViewer::StoppedState);
+
+ d->viewerControl->showMedia(d->media);
+
+ emit mediaChanged(d->media);
+}
+
+/*!
+ Use \a playlist as the source of images to be displayed in the viewer.
+ \since 1.0
+*/
+void QMediaImageViewer::setPlaylist(QMediaPlaylist *playlist)
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->playlist) {
+ disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_playlistMediaChanged(QMediaContent)));
+ disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ QMediaObject::unbind(d->playlist);
+ }
+
+ d->playlist = playlist;
+
+ if (d->playlist) {
+ connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_playlistMediaChanged(QMediaContent)));
+ connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ QMediaObject::bind(d->playlist);
+
+ setMedia(d->playlist->currentMedia());
+ } else {
+ setMedia(QMediaContent());
+ }
+}
+
+/*!
+ Returns the current playlist, or 0 if none.
+ \since 1.0
+*/
+QMediaPlaylist *QMediaImageViewer::playlist() const
+{
+ return d_func()->playlist;
+}
+
+/*!
+ \fn QMediaImageViewer::mediaChanged(const QMediaContent &media)
+
+ Signals that the \a media an image viewer is presenting has changed.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaImageViewer::timeout
+ \brief the amount of time in milliseconds an image is displayed for before moving to the next
+ image.
+
+ The timeout only applies if the image viewer has a playlist attached and is in the PlayingState.
+ \since 1.0
+*/
+
+int QMediaImageViewer::timeout() const
+{
+ return d_func()->timeout;
+}
+
+void QMediaImageViewer::setTimeout(int timeout)
+{
+ Q_D(QMediaImageViewer);
+
+ d->timeout = qMax(0, timeout);
+
+ if (d->timer.isActive())
+ d->timer.start(qMax(0, d->timeout - d->pauseTime - d->time.elapsed()), this);
+}
+
+/*!
+ \property QMediaImageViewer::elapsedTime
+ \brief the amount of time in milliseconds that has elapsed since the current image was loaded.
+
+ The elapsed time only increases while the image viewer is in the PlayingState. If stopped the
+ elapsed time will be reset to 0.
+ \since 1.0
+*/
+
+int QMediaImageViewer::elapsedTime() const
+{
+ Q_D(const QMediaImageViewer);
+
+ int elapsedTime = d->pauseTime;
+
+ if (d->timer.isActive())
+ elapsedTime += d->time.elapsed();
+
+ return elapsedTime;
+}
+
+/*!
+ \fn QMediaImageViewer::elapsedTimeChanged(int time)
+
+ Signals that the amount of \a time in milliseconds since the current
+ image was loaded has changed.
+
+ This signal is emitted at a regular interval when the image viewer is
+ in the PlayingState and an image is loaded. The notification interval
+ is controlled by the QMediaObject::notifyInterval property.
+
+ \since 1.0
+ \sa timeout, QMediaObject::notifyInterval
+*/
+
+/*!
+ Sets a video \a widget as the current video output.
+
+ This will unbind any previous video output bound with setVideoOutput().
+ \since 1.1
+*/
+
+void QMediaImageViewer::setVideoOutput(QVideoWidget *widget)
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ // We don't know (in this library) that QVideoWidget inherits QObject
+ QObject *widgetObject = reinterpret_cast<QObject*>(widget);
+
+ d->videoOutput = widgetObject && bind(widgetObject) ? widgetObject : 0;
+}
+
+/*!
+ Sets a video \a item as the current video output.
+
+ This will unbind any previous video output bound with setVideoOutput().
+ \since 1.1
+*/
+
+void QMediaImageViewer::setVideoOutput(QGraphicsVideoItem *item)
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
+ // but QObject inheritance depends on QObject coming first, so try this out.
+ QObject *itemObject = reinterpret_cast<QObject*>(item);
+
+ d->videoOutput = itemObject && bind(itemObject) ? itemObject : 0;
+}
+
+/*!
+ Sets a video \a surface as the video output of a image viewer.
+
+ If a video output has already been set on the image viewer the new surface
+ will replace it.
+ \since 1.2
+*/
+
+void QMediaImageViewer::setVideoOutput(QAbstractVideoSurface *surface)
+{
+ Q_D(QMediaImageViewer);
+
+ d->surfaceOutput.setVideoSurface(surface);
+
+ if (d->videoOutput != &d->surfaceOutput) {
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ d->videoOutput = bind(&d->surfaceOutput) ? &d->surfaceOutput : 0;
+ }
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+bool QMediaImageViewer::bind(QObject *object)
+{
+ if (QMediaPlaylist *playlist = qobject_cast<QMediaPlaylist *>(object)) {
+ setPlaylist(playlist);
+
+ return true;
+ } else {
+ return QMediaObject::bind(object);
+ }
+}
+
+/*!
+ \internal
+ \since 1.0
+ */
+void QMediaImageViewer::unbind(QObject *object)
+{
+ if (object == d_func()->playlist)
+ setPlaylist(0);
+ else
+ QMediaObject::unbind(object);
+}
+
+/*!
+ Starts a slide show.
+
+ If the playlist has no current media this will start at the beginning of the playlist, otherwise
+ it will resume from the current media.
+
+ If no playlist is attached to an image viewer this will do nothing.
+ \since 1.0
+*/
+void QMediaImageViewer::play()
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->playlist && d->playlist->mediaCount() > 0 && d->state != PlayingState) {
+ d->state = PlayingState;
+
+ switch (d->viewerControl->mediaStatus()) {
+ case NoMedia:
+ case InvalidMedia:
+ d->playlist->next();
+ if (d->playlist->currentIndex() < 0)
+ d->state = StoppedState;
+ break;
+ case LoadingMedia:
+ break;
+ case LoadedMedia:
+ d->time.start();
+ d->timer.start(qMax(0, d->timeout - d->pauseTime), this);
+ break;
+ }
+
+ if (d->state == PlayingState)
+ emit stateChanged(d->state);
+ }
+}
+
+/*!
+ Pauses a slide show.
+
+ The current media and elapsed time are retained. If resumed, the current image will be
+ displayed for the remainder of the time out period before the next image is loaded.
+ \since 1.0
+*/
+void QMediaImageViewer::pause()
+{
+ Q_D(QMediaImageViewer);
+
+ if (d->state == PlayingState) {
+ if (d->viewerControl->mediaStatus() == LoadedMedia) {
+ d->pauseTime += d->timeout - d->time.elapsed();
+ d->timer.stop();
+ removePropertyWatch("elapsedTime");
+ }
+
+ emit stateChanged(d->state = PausedState);
+ emit elapsedTimeChanged(d->pauseTime);
+ }
+}
+
+/*!
+ Stops a slide show.
+
+ The current media is retained, but the elapsed time is discarded. If resumed, the current
+ image will be displayed for the full time out period before the next image is loaded.
+ \since 1.0
+*/
+void QMediaImageViewer::stop()
+{
+ Q_D(QMediaImageViewer);
+
+ switch (d->state) {
+ case PlayingState:
+ d->timer.stop();
+ removePropertyWatch("elapsedTime");
+ // fall through.
+ case PausedState:
+ d->pauseTime = 0;
+ d->state = QMediaImageViewer::StoppedState;
+
+ emit stateChanged(d->state);
+ emit elapsedTimeChanged(0);
+ break;
+ case StoppedState:
+ break;
+ }
+}
+
+/*!
+ \reimp
+
+ \internal
+ \since 1.0
+*/
+void QMediaImageViewer::timerEvent(QTimerEvent *event)
+{
+ Q_D(QMediaImageViewer);
+
+ if (event->timerId() == d->timer.timerId()) {
+ d->timer.stop();
+ removePropertyWatch("elapsedTime");
+ emit elapsedTimeChanged(d->pauseTime = d->timeout);
+
+ d->playlist->next();
+
+ if (d->playlist->currentIndex() < 0) {
+ d->pauseTime = 0;
+ emit stateChanged(d->state = StoppedState);
+ emit elapsedTimeChanged(0);
+ }
+ } else {
+ QMediaObject::timerEvent(event);
+ }
+}
+
+#include "moc_qmediaimageviewer.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaimageviewer.h b/src/multimedia/qmediaimageviewer.h
new file mode 100644
index 000000000..7010fad3f
--- /dev/null
+++ b/src/multimedia/qmediaimageviewer.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAIMAGEVIEWER_H
+#define QMEDIAIMAGEVIEWER_H
+
+#include "qmediaobject.h"
+#include "qmediacontent.h"
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoSurface;
+class QGraphicsVideoItem;
+class QMediaPlaylist;
+class QVideoWidget;
+
+class QMediaImageViewerPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaImageViewer : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged)
+ Q_PROPERTY(QMediaContent media READ media WRITE setMedia NOTIFY mediaChanged)
+ Q_PROPERTY(int timeout READ timeout WRITE setTimeout)
+ Q_PROPERTY(int elapsedTime READ elapsedTime NOTIFY elapsedTimeChanged)
+ Q_ENUMS(State MediaStatus)
+
+public:
+ enum State
+ {
+ StoppedState,
+ PlayingState,
+ PausedState
+ };
+
+ enum MediaStatus
+ {
+ NoMedia,
+ LoadingMedia,
+ LoadedMedia,
+ InvalidMedia
+ };
+
+ explicit QMediaImageViewer(QObject *parent = 0);
+ ~QMediaImageViewer();
+
+ State state() const;
+ MediaStatus mediaStatus() const;
+
+ QMediaContent media() const;
+ QMediaPlaylist *playlist() const;
+
+ int timeout() const;
+ int elapsedTime() const;
+
+ void setVideoOutput(QVideoWidget *widget);
+ void setVideoOutput(QGraphicsVideoItem *item);
+ void setVideoOutput(QAbstractVideoSurface *surface);
+
+ bool bind(QObject *);
+ void unbind(QObject *);
+
+public Q_SLOTS:
+ void setMedia(const QMediaContent &media);
+ void setPlaylist(QMediaPlaylist *playlist);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setTimeout(int timeout);
+
+Q_SIGNALS:
+ void stateChanged(QMediaImageViewer::State state);
+ void mediaStatusChanged(QMediaImageViewer::MediaStatus status);
+ void mediaChanged(const QMediaContent &media);
+ void elapsedTimeChanged(int time);
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ Q_DECLARE_PRIVATE(QMediaImageViewer)
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaStatusChanged(QMediaImageViewer::MediaStatus))
+ Q_PRIVATE_SLOT(d_func(), void _q_playlistMediaChanged(const QMediaContent &))
+ Q_PRIVATE_SLOT(d_func(), void _q_playlistDestroyed())
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaImageViewer::State)
+Q_DECLARE_METATYPE(QMediaImageViewer::MediaStatus)
+
+Q_MEDIA_ENUM_DEBUG(QMediaImageViewer, State)
+Q_MEDIA_ENUM_DEBUG(QMediaImageViewer, MediaStatus)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qmediaimageviewerservice.cpp b/src/multimedia/qmediaimageviewerservice.cpp
new file mode 100644
index 000000000..65de7a81b
--- /dev/null
+++ b/src/multimedia/qmediaimageviewerservice.cpp
@@ -0,0 +1,463 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaimageviewerservice_p.h"
+
+#include "qmediacontrol_p.h"
+#include "qmediaservice_p.h"
+
+#include <qmediacontent.h>
+#include <qmediaresource.h>
+#include <qmediaobject_p.h>
+#include <qvideorenderercontrol.h>
+
+#include <QtCore/qdebug.h>
+
+#include <QtCore/qurl.h>
+#include <QtGui/qimagereader.h>
+
+#include <QtNetwork/qnetworkaccessmanager.h>
+#include <QtNetwork/qnetworkreply.h>
+#include <QtNetwork/qnetworkrequest.h>
+
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaImageViewerServicePrivate : public QMediaServicePrivate
+{
+public:
+ QMediaImageViewerServicePrivate()
+ : viewerControl(0)
+ , rendererControl(0)
+ , network(0)
+ , internalNetwork(0)
+ {
+ }
+
+ bool load(QIODevice *device);
+ void clear();
+
+ QMediaImageViewerControl *viewerControl;
+ QMediaImageViewerRenderer *rendererControl;
+ QNetworkAccessManager *network;
+ QNetworkAccessManager *internalNetwork;
+ QImage m_image;
+};
+
+
+QMediaImageViewerRenderer::QMediaImageViewerRenderer(QObject *parent)
+ : QVideoRendererControl(parent)
+ , m_surface(0)
+{
+}
+
+QMediaImageViewerRenderer::~QMediaImageViewerRenderer()
+{
+ if (m_surface)
+ m_surface->stop();
+}
+
+QAbstractVideoSurface *QMediaImageViewerRenderer::surface() const
+{
+ return m_surface;
+}
+
+void QMediaImageViewerRenderer::setSurface(QAbstractVideoSurface *surface)
+{
+ if (m_surface)
+ m_surface->stop();
+
+ m_surface = surface;
+
+ if (m_surface && !m_image.isNull())
+ showImage(m_image);
+}
+
+void QMediaImageViewerRenderer::showImage(const QImage &image)
+{
+ m_image = image;
+
+ if (m_surface) {
+ if (m_image.isNull()) {
+ m_surface->stop();
+ } else {
+ QVideoSurfaceFormat format(
+ image.size(), QVideoFrame::pixelFormatFromImageFormat(image.format()));
+
+ if (!m_surface->isFormatSupported(format)) {
+ foreach (QVideoFrame::PixelFormat pixelFormat, m_surface->supportedPixelFormats()) {
+ const QImage::Format imageFormat
+ = QVideoFrame::imageFormatFromPixelFormat(pixelFormat);
+
+ if (imageFormat != QImage::Format_Invalid) {
+ format = QVideoSurfaceFormat(image.size(), pixelFormat);
+
+ if (m_surface->isFormatSupported(format) && m_surface->start(format)) {
+ m_image = image.convertToFormat(imageFormat);
+
+ m_surface->present(QVideoFrame(m_image));
+
+ return;
+ }
+ }
+ }
+ } else if (m_surface->start(format)) {
+ m_surface->present(QVideoFrame(image));
+ }
+ }
+ }
+}
+
+bool QMediaImageViewerServicePrivate::load(QIODevice *device)
+{
+ QImageReader reader(device);
+
+ if (!reader.canRead()) {
+ m_image = QImage();
+ } else {
+ m_image = reader.read();
+ }
+
+ if (rendererControl)
+ rendererControl->showImage(m_image);
+
+ return !m_image.isNull();
+}
+
+void QMediaImageViewerServicePrivate::clear()
+{
+ m_image = QImage();
+
+ if (rendererControl)
+ rendererControl->showImage(m_image);
+}
+
+/*!
+ \class QMediaImageViewerService
+ \since 1.0
+ \internal
+*/
+
+/*!
+*/
+QMediaImageViewerService::QMediaImageViewerService(QObject *parent)
+ : QMediaService(*new QMediaImageViewerServicePrivate, parent)
+{
+ Q_D(QMediaImageViewerService);
+
+ d->viewerControl = new QMediaImageViewerControl(this);
+}
+
+/*!
+*/
+QMediaImageViewerService::~QMediaImageViewerService()
+{
+ Q_D(QMediaImageViewerService);
+
+ delete d->rendererControl;
+ delete d->viewerControl;
+}
+
+/*!
+*/
+QMediaControl *QMediaImageViewerService::requestControl(const char *name)
+{
+ Q_D(QMediaImageViewerService);
+
+ if (qstrcmp(name, QMediaImageViewerControl_iid) == 0) {
+ return d->viewerControl;
+ } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ if (!d->rendererControl) {
+ d->rendererControl = new QMediaImageViewerRenderer;
+ d->rendererControl->showImage(d->m_image);
+
+ return d->rendererControl;
+ }
+ }
+ return 0;
+}
+
+void QMediaImageViewerService::releaseControl(QMediaControl *control)
+{
+ Q_D(QMediaImageViewerService);
+
+ if (!control) {
+ qWarning("QMediaService::releaseControl():"
+ " Attempted release of null control");
+ } else if (control == d->rendererControl) {
+ delete d->rendererControl;
+
+ d->rendererControl = 0;
+ }
+}
+
+/*!
+*/
+QNetworkAccessManager *QMediaImageViewerService::networkManager() const
+{
+ Q_D(const QMediaImageViewerService);
+
+ if (!d->network) {
+ QMediaImageViewerServicePrivate *_d = const_cast<QMediaImageViewerServicePrivate *>(d);
+
+ if (!_d->internalNetwork)
+ _d->internalNetwork = new QNetworkAccessManager(
+ const_cast<QMediaImageViewerService *>(this));
+
+ _d->network = d->internalNetwork;
+ }
+
+ return d->network;
+}
+
+
+void QMediaImageViewerService::setNetworkManager(QNetworkAccessManager *manager)
+{
+ d_func()->network = manager;
+}
+
+class QMediaImageViewerControlPrivate : public QMediaControlPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaImageViewerControl)
+public:
+ QMediaImageViewerControlPrivate()
+ : service(0)
+ , getReply(0)
+ , headReply(0)
+ , status(QMediaImageViewer::NoMedia)
+ {
+ foreach (const QByteArray &format, QImageReader::supportedImageFormats()) {
+ supportedExtensions.append(
+ QLatin1Char('.') + QString::fromLatin1(format.data(), format.size()));
+ }
+ }
+
+ bool isImageType(const QUrl &url, const QString &mimeType) const;
+
+ void loadImage();
+ void cancelRequests();
+
+ void _q_getFinished();
+ void _q_headFinished();
+
+ QMediaImageViewerService *service;
+ QNetworkReply *getReply;
+ QNetworkReply *headReply;
+ QMediaImageViewer::MediaStatus status;
+ QMediaContent media;
+ QMediaResource currentMedia;
+ QList<QMediaResource> possibleResources;
+ QStringList supportedExtensions;
+};
+
+bool QMediaImageViewerControlPrivate::isImageType(const QUrl &url, const QString &mimeType) const
+{
+ if (!mimeType.isEmpty()) {
+ return mimeType.startsWith(QLatin1String("image/"))
+ || mimeType == QLatin1String("application/xml+svg");
+ } else if (url.scheme() == QLatin1String("file")) {
+ QString path = url.path();
+
+ foreach (const QString &extension, supportedExtensions) {
+ if (path.endsWith(extension, Qt::CaseInsensitive))
+ return true;
+ }
+ }
+ return false;
+}
+
+void QMediaImageViewerControlPrivate::loadImage()
+{
+ cancelRequests();
+
+ QMediaImageViewer::MediaStatus currentStatus = status;
+ status = QMediaImageViewer::InvalidMedia;
+
+ QNetworkAccessManager *network = service->networkManager();
+
+ while (!possibleResources.isEmpty() && !headReply && !getReply) {
+ currentMedia = possibleResources.takeFirst();
+
+ QUrl url = currentMedia.url();
+ QString mimeType = currentMedia.mimeType();
+
+ if (isImageType(url, mimeType)) {
+ getReply = network->get(QNetworkRequest(url));
+ QObject::connect(getReply, SIGNAL(finished()), q_func(), SLOT(_q_getFinished()));
+
+ status = QMediaImageViewer::LoadingMedia;
+ } else if (mimeType.isEmpty() && url.scheme() != QLatin1String("file")) {
+ headReply = network->head(QNetworkRequest(currentMedia.url()));
+ QObject::connect(headReply, SIGNAL(finished()), q_func(), SLOT(_q_headFinished()));
+
+ status = QMediaImageViewer::LoadingMedia;
+ }
+ }
+
+ if (status == QMediaImageViewer::InvalidMedia)
+ currentMedia = QMediaResource();
+
+ if (status != currentStatus)
+ emit q_func()->mediaStatusChanged(status);
+}
+
+void QMediaImageViewerControlPrivate::cancelRequests()
+{
+ if (getReply) {
+ getReply->abort();
+ getReply->deleteLater();
+ getReply = 0;
+ }
+
+ if (headReply) {
+ headReply->abort();
+ headReply->deleteLater();
+ headReply = 0;
+ }
+}
+
+void QMediaImageViewerControlPrivate::_q_getFinished()
+{
+ if (getReply != q_func()->sender())
+ return;
+
+ QImage image;
+
+ if (service->d_func()->load(getReply)) {
+ possibleResources.clear();
+
+ status = QMediaImageViewer::LoadedMedia;
+
+ emit q_func()->mediaStatusChanged(status);
+ } else {
+ loadImage();
+ }
+}
+
+void QMediaImageViewerControlPrivate::_q_headFinished()
+{
+ if (headReply != q_func()->sender())
+ return;
+
+ QString mimeType = headReply->header(QNetworkRequest::ContentTypeHeader)
+ .toString().section(QLatin1Char(';'), 0, 0);
+ QUrl url = headReply->url();
+ if (url.isEmpty())
+ url = headReply->request().url();
+
+ headReply->deleteLater();
+ headReply = 0;
+
+ if (isImageType(url, mimeType) || mimeType.isEmpty()) {
+ QNetworkAccessManager *network = service->networkManager();
+
+ getReply = network->get(QNetworkRequest(url));
+
+ QObject::connect(getReply, SIGNAL(finished()), q_func(), SLOT(_q_getFinished()));
+ } else {
+ loadImage();
+ }
+}
+
+/*!
+ \class QMediaImageViewerControl
+ \internal
+ \since 1.1
+*/
+QMediaImageViewerControl::QMediaImageViewerControl(QMediaImageViewerService *parent)
+ : QMediaControl(*new QMediaImageViewerControlPrivate, parent)
+{
+ Q_D(QMediaImageViewerControl);
+
+ d->service = parent;
+}
+
+/*!
+*/
+QMediaImageViewerControl::~QMediaImageViewerControl()
+{
+ Q_D(QMediaImageViewerControl);
+
+ delete d->getReply;
+}
+
+/*!
+ \since 1.1
+*/
+QMediaImageViewer::MediaStatus QMediaImageViewerControl::mediaStatus() const
+{
+ return d_func()->status;
+}
+
+/*!
+ \fn QMediaImageViewerControl::mediaStatusChanged(QMediaImageViewer::MediaStatus status);
+ \since 1.1
+*/
+
+/*!
+ \since 1.1
+*/
+void QMediaImageViewerControl::showMedia(const QMediaContent &media)
+{
+ Q_D(QMediaImageViewerControl);
+
+ d->media = media;
+ d->currentMedia = QMediaResource();
+ d->cancelRequests();
+
+ if (media.isNull()) {
+ d->service->d_func()->clear();
+ if (d->status != QMediaImageViewer::NoMedia) {
+ d->status = QMediaImageViewer::NoMedia;
+ emit mediaStatusChanged(d->status);
+ }
+ } else {
+ d->possibleResources = media.resources();
+ d->loadImage();
+ }
+}
+
+
+#include "moc_qmediaimageviewerservice_p.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaimageviewerservice_p.h b/src/multimedia/qmediaimageviewerservice_p.h
new file mode 100644
index 000000000..d1b6956d9
--- /dev/null
+++ b/src/multimedia/qmediaimageviewerservice_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIASLIDESHOWSERVICE_P_H
+#define QMEDIASLIDESHOWSERVICE_P_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.
+//
+
+#include <qtmultimediadefs.h>
+#include <qmediaservice.h>
+#include <qmediaimageviewer.h>
+#include <qvideorenderercontrol.h>
+
+#include <QtCore/qpointer.h>
+#include <QtGui/qimage.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QAbstractVideoSurface;
+class QNetworkAccessManager;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class QMediaImageViewerServicePrivate;
+
+class Q_AUTOTEST_EXPORT QMediaImageViewerService : public QMediaService
+{
+ Q_OBJECT
+public:
+ explicit QMediaImageViewerService(QObject *parent = 0);
+ ~QMediaImageViewerService();
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *);
+
+ QNetworkAccessManager *networkManager() const;
+ void setNetworkManager(QNetworkAccessManager *manager);
+
+private:
+ Q_DECLARE_PRIVATE(QMediaImageViewerService)
+ friend class QMediaImageViewerControl;
+ friend class QMediaImageViewerControlPrivate;
+};
+
+class QMediaImageViewerControlPrivate;
+
+class QMediaImageViewerControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ explicit QMediaImageViewerControl(QMediaImageViewerService *parent);
+ ~QMediaImageViewerControl();
+
+ QMediaImageViewer::MediaStatus mediaStatus() const;
+
+ void showMedia(const QMediaContent &media);
+
+Q_SIGNALS:
+ void mediaStatusChanged(QMediaImageViewer::MediaStatus status);
+
+private:
+ Q_DECLARE_PRIVATE(QMediaImageViewerControl)
+ Q_PRIVATE_SLOT(d_func(), void _q_headFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_getFinished())
+};
+
+#define QMediaImageViewerControl_iid "com.nokia.Qt.QMediaImageViewerControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaImageViewerControl, QMediaImageViewerControl_iid)
+
+class QMediaImageViewerRenderer : public QVideoRendererControl
+{
+ Q_OBJECT
+public:
+ QMediaImageViewerRenderer(QObject *parent = 0);
+ ~QMediaImageViewerRenderer();
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+ void showImage(const QImage &image);
+
+Q_SIGNALS:
+ void surfaceChanged(QAbstractVideoSurface *surface);
+
+private:
+ QPointer<QAbstractVideoSurface> m_surface;
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmedianetworkaccesscontrol.cpp b/src/multimedia/qmedianetworkaccesscontrol.cpp
new file mode 100644
index 000000000..a976859ed
--- /dev/null
+++ b/src/multimedia/qmedianetworkaccesscontrol.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmedianetworkaccesscontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaNetworkAccessControl
+ \preliminary
+ \brief The QMediaNetworkAccessControl class allows the setting of the Network Access Point for media related activities.
+ \ingroup multimedia-serv
+ \inmodule QtMultimedia
+ \since 1.2
+
+ The functionality provided by this control allows the
+ setting of a Network Access Point.
+
+ This control can be used to set a network access for various
+ network related activities. the exact nature in dependant on the underlying
+ usage by the supported QMediaObject
+*/
+
+QMediaNetworkAccessControl::QMediaNetworkAccessControl(QObject *parent) :
+ QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a network access control.
+*/
+QMediaNetworkAccessControl::~QMediaNetworkAccessControl()
+{
+}
+
+/*!
+ \fn void QMediaNetworkAccessControl::setConfigurations(const QList<QNetworkConfiguration> &configurations);
+
+ \a configurations contains a list of network configurations to be used for network access.
+
+ It is assumed the list is given in highest to lowest preference order.
+ By calling this function all previous configurations will be invalidated
+ and replaced with the new list.
+ \since 1.2
+*/
+
+/*
+ \fn QNetworkConfiguration QMediaNetworkAccessControl::currentConfiguration() const
+
+ Returns the current active configuration in use.
+ A default constructed QNetworkConfigration is returned if no user supplied configuration are in use.
+*/
+
+
+/*!
+ \fn QMediaNetworkAccessControl::configurationChanged(const QNetworkConfiguration &configuration)
+ This signal is emitted when the current active network configuration changes
+ to \a configuration.
+ \since 1.2
+*/
+
+
+
+#include "moc_qmedianetworkaccesscontrol.cpp"
+QT_END_NAMESPACE
diff --git a/src/multimedia/qmedianetworkaccesscontrol.h b/src/multimedia/qmedianetworkaccesscontrol.h
new file mode 100644
index 000000000..22ee95711
--- /dev/null
+++ b/src/multimedia/qmedianetworkaccesscontrol.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIANETWORKACCESSCONTROL_H
+#define QMEDIANETWORKACCESSCONTROL_H
+
+#include "qmediacontrol.h"
+
+#include <QtCore/qlist.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaNetworkAccessControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+
+ virtual ~QMediaNetworkAccessControl();
+
+ virtual void setConfigurations(const QList<QNetworkConfiguration> &configuration) = 0;
+ virtual QNetworkConfiguration currentConfiguration() const = 0;
+
+Q_SIGNALS:
+ void configurationChanged(const QNetworkConfiguration& configuration);
+
+protected:
+ QMediaNetworkAccessControl(QObject *parent = 0);
+};
+
+#define QMediaNetworkAccessControl_iid "com.nokia.Qt.QMediaNetworkAccessControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaNetworkAccessControl, QMediaNetworkAccessControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmediaobject.cpp b/src/multimedia/qmediaobject.cpp
new file mode 100644
index 000000000..7eb1a2dfa
--- /dev/null
+++ b/src/multimedia/qmediaobject.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qdebug.h>
+
+#include "qmediaobject_p.h"
+
+#include <qmediaservice.h>
+#include <qmetadatareadercontrol.h>
+#include <qmediabindableinterface.h>
+
+
+QT_BEGIN_NAMESPACE
+
+void QMediaObjectPrivate::_q_notify()
+{
+ Q_Q(QMediaObject);
+
+ const QMetaObject* m = q->metaObject();
+
+ foreach (int pi, notifyProperties) {
+ QMetaProperty p = m->property(pi);
+ p.notifySignal().invoke(
+ q, QGenericArgument(QMetaType::typeName(p.userType()), p.read(q).data()));
+ }
+}
+
+
+/*!
+ \class QMediaObject
+
+ \brief The QMediaObject class provides a common base for multimedia objects.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ QMediaObject derived classes provide access to the functionality of a
+ QMediaService. Each media object hosts a QMediaService and uses the
+ QMediaControl interfaces implemented by the service to implement its
+ API. Most media objects when constructed will request a new
+ QMediaService instance from a QMediaServiceProvider, but some like
+ QMediaRecorder will share a service with another object.
+
+ QMediaObject itself provides an API for accessing a media
+ service's \l {metaData()}{meta-data} and a means of connecting other media objects,
+ and peripheral classes like QVideoWidget and QMediaPlaylist.
+
+ \sa QMediaService, QMediaControl
+*/
+
+/*!
+ Destroys this media object.
+*/
+
+QMediaObject::~QMediaObject()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns the service availability error state.
+ \since 1.0
+*/
+
+QtMultimedia::AvailabilityError QMediaObject::availabilityError() const
+{
+ return d_func()->service == 0 ? QtMultimedia::ServiceMissingError : QtMultimedia::NoError;
+}
+
+/*!
+ Returns true if the service is available for use.
+ \since 1.0
+*/
+
+bool QMediaObject::isAvailable() const
+{
+ return d_func()->service != 0;
+}
+
+/*!
+ Returns the media service that provides the functionality of this multimedia object.
+ \since 1.0
+*/
+
+QMediaService* QMediaObject::service() const
+{
+ return d_func()->service;
+}
+
+int QMediaObject::notifyInterval() const
+{
+ return d_func()->notifyTimer->interval();
+}
+
+void QMediaObject::setNotifyInterval(int milliSeconds)
+{
+ Q_D(QMediaObject);
+
+ if (d->notifyTimer->interval() != milliSeconds) {
+ d->notifyTimer->setInterval(milliSeconds);
+
+ emit notifyIntervalChanged(milliSeconds);
+ }
+}
+
+/*!
+ Bind \a object to this QMediaObject instance.
+
+ This method establishes a relationship between this media object and a
+ helper object. The nature of the relationship depends on both parties. This
+ methods returns true if the helper was successfully bound, false otherwise.
+
+ Most subclasses of QMediaObject provide more convenient functions
+ that wrap this functionality, so this function rarely needs to be
+ called directly.
+
+ The object passed must implement the QMediaBindableInterface interface.
+
+ \since 1.0
+ \sa QMediaBindableInterface
+*/
+bool QMediaObject::bind(QObject *object)
+{
+ QMediaBindableInterface *helper = qobject_cast<QMediaBindableInterface*>(object);
+ if (!helper)
+ return false;
+
+ QMediaObject *currentObject = helper->mediaObject();
+
+ if (currentObject == this)
+ return true;
+
+ if (currentObject)
+ currentObject->unbind(object);
+
+ return helper->setMediaObject(this);
+}
+
+/*!
+ Detach \a object from the QMediaObject instance.
+
+ Unbind the helper object from this media object. A warning
+ will be generated if the object was not previously bound to this
+ object.
+
+ \since 1.0
+ \sa QMediaBindableInterface
+*/
+void QMediaObject::unbind(QObject *object)
+{
+ QMediaBindableInterface *helper = qobject_cast<QMediaBindableInterface*>(object);
+
+ if (helper && helper->mediaObject() == this)
+ helper->setMediaObject(0);
+ else
+ qWarning() << "QMediaObject: Trying to unbind not connected helper object";
+}
+
+/*!
+ Constructs a media object which uses the functionality provided by a media \a service.
+
+ The \a parent is passed to QObject.
+
+ This class is meant as a base class for multimedia objects so this
+ constructor is protected.
+ \since 1.0
+*/
+
+QMediaObject::QMediaObject(QObject *parent, QMediaService *service):
+ QObject(parent),
+ d_ptr(new QMediaObjectPrivate)
+
+{
+ Q_D(QMediaObject);
+
+ d->q_ptr = this;
+
+ d->notifyTimer = new QTimer(this);
+ d->notifyTimer->setInterval(1000);
+ connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+
+ d->service = service;
+
+ setupMetaData();
+}
+
+/*!
+ \internal
+*/
+
+QMediaObject::QMediaObject(QMediaObjectPrivate &dd, QObject *parent,
+ QMediaService *service):
+ QObject(parent),
+ d_ptr(&dd)
+{
+ Q_D(QMediaObject);
+ d->q_ptr = this;
+
+ d->notifyTimer = new QTimer(this);
+ d->notifyTimer->setInterval(1000);
+ connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+
+ d->service = service;
+
+ setupMetaData();
+}
+
+/*!
+ Watch the property \a name. The property's notify signal will be emitted
+ once every \code notifyInterval milliseconds.
+
+ \since 1.0
+ \sa notifyInterval
+*/
+
+void QMediaObject::addPropertyWatch(QByteArray const &name)
+{
+ Q_D(QMediaObject);
+
+ const QMetaObject* m = metaObject();
+
+ int index = m->indexOfProperty(name.constData());
+
+ if (index != -1 && m->property(index).hasNotifySignal()) {
+ d->notifyProperties.insert(index);
+
+ if (!d->notifyTimer->isActive())
+ d->notifyTimer->start();
+ }
+}
+
+/*!
+ Remove property \a name from the list of properties whose changes are
+ regularly signaled.
+
+ \since 1.0
+ \sa notifyInterval
+*/
+
+void QMediaObject::removePropertyWatch(QByteArray const &name)
+{
+ Q_D(QMediaObject);
+
+ int index = metaObject()->indexOfProperty(name.constData());
+
+ if (index != -1) {
+ d->notifyProperties.remove(index);
+
+ if (d->notifyProperties.isEmpty())
+ d->notifyTimer->stop();
+ }
+}
+
+/*!
+ \property QMediaObject::notifyInterval
+
+ The interval at which notifiable properties will update.
+
+ The interval is expressed in milliseconds, the default value is 1000.
+
+ \since 1.0
+ \sa addPropertyWatch(), removePropertyWatch()
+*/
+
+/*!
+ \fn void QMediaObject::notifyIntervalChanged(int milliseconds)
+
+ Signal a change in the notify interval period to \a milliseconds.
+ \since 1.0
+*/
+
+/*!
+ Returns true if there is meta-data associated with this media object, else false.
+ \since 1.0
+*/
+
+bool QMediaObject::isMetaDataAvailable() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->isMetaDataAvailable()
+ : false;
+}
+
+/*!
+ \fn QMediaObject::metaDataAvailableChanged(bool available)
+
+ Signals that the \a available state of a media object's meta-data has changed.
+ \since 1.0
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+ \since 1.0
+*/
+QVariant QMediaObject::metaData(QtMultimedia::MetaData key) const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->metaData(key)
+ : QVariant();
+}
+
+/*!
+ Returns a list of keys there is meta-data available for.
+ \since 1.0
+*/
+QList<QtMultimedia::MetaData> QMediaObject::availableMetaData() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableMetaData()
+ : QList<QtMultimedia::MetaData>();
+}
+
+/*!
+ \fn QMediaObject::metaDataChanged()
+
+ Signals that this media object's meta-data has changed.
+ \since 1.0
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+
+ The naming and type of extended meta-data is not standardized, so the values and meaning
+ of keys may vary between backends.
+ \since 1.0
+*/
+QVariant QMediaObject::extendedMetaData(const QString &key) const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->extendedMetaData(key)
+ : QVariant();
+}
+
+/*!
+ Returns a list of keys there is extended meta-data available for.
+ \since 1.0
+*/
+QStringList QMediaObject::availableExtendedMetaData() const
+{
+ Q_D(const QMediaObject);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableExtendedMetaData()
+ : QStringList();
+}
+
+
+void QMediaObject::setupMetaData()
+{
+ Q_D(QMediaObject);
+
+ if (d->service != 0) {
+ d->metaDataControl = qobject_cast<QMetaDataReaderControl*>(
+ d->service->requestControl(QMetaDataReaderControl_iid));
+
+ if (d->metaDataControl) {
+ connect(d->metaDataControl, SIGNAL(metaDataChanged()), SIGNAL(metaDataChanged()));
+ connect(d->metaDataControl,
+ SIGNAL(metaDataAvailableChanged(bool)),
+ SIGNAL(metaDataAvailableChanged(bool)));
+ }
+ }
+}
+
+/*!
+ \fn QMediaObject::availabilityChanged(bool available)
+
+ Signal emitted when the availability state has changed to \a available
+ \since 1.0
+*/
+
+
+#include "moc_qmediaobject.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaobject.h b/src/multimedia/qmediaobject.h
new file mode 100644
index 000000000..aba8f7021
--- /dev/null
+++ b/src/multimedia/qmediaobject.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIAOBJECT_H
+#define QABSTRACTMEDIAOBJECT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaService;
+class QMediaBindableInterface;
+
+class QMediaObjectPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged)
+public:
+ ~QMediaObject();
+
+ virtual bool isAvailable() const;
+ virtual QtMultimedia::AvailabilityError availabilityError() const;
+
+ virtual QMediaService* service() const;
+
+ int notifyInterval() const;
+ void setNotifyInterval(int milliSeconds);
+
+ virtual bool bind(QObject *);
+ virtual void unbind(QObject *);
+
+ bool isMetaDataAvailable() const;
+
+ QVariant metaData(QtMultimedia::MetaData key) const;
+ QList<QtMultimedia::MetaData> availableMetaData() const;
+
+ QVariant extendedMetaData(const QString &key) const;
+ QStringList availableExtendedMetaData() const;
+
+Q_SIGNALS:
+ void notifyIntervalChanged(int milliSeconds);
+
+ void metaDataAvailableChanged(bool available);
+ void metaDataChanged();
+
+ void availabilityChanged(bool available);
+
+protected:
+ QMediaObject(QObject *parent, QMediaService *service);
+ QMediaObject(QMediaObjectPrivate &dd, QObject *parent, QMediaService *service);
+
+ void addPropertyWatch(QByteArray const &name);
+ void removePropertyWatch(QByteArray const &name);
+
+ QMediaObjectPrivate *d_ptr;
+
+private:
+ void setupMetaData();
+
+ Q_DECLARE_PRIVATE(QMediaObject)
+ Q_PRIVATE_SLOT(d_func(), void _q_notify())
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QABSTRACTMEDIAOBJECT_H
diff --git a/src/multimedia/qmediaobject_p.h b/src/multimedia/qmediaobject_p.h
new file mode 100644
index 000000000..f27420cf0
--- /dev/null
+++ b/src/multimedia/qmediaobject_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIAOBJECT_P_H
+#define QABSTRACTMEDIAOBJECT_P_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.
+//
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qset.h>
+#include <QtCore/qtimer.h>
+
+#include "qmediaobject.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMetaDataReaderControl;
+
+#define Q_DECLARE_NON_CONST_PUBLIC(Class) \
+ inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
+ friend class Class;
+
+
+class QMediaObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaObject)
+
+public:
+ QMediaObjectPrivate():metaDataControl(0), notifyTimer(0) {}
+ virtual ~QMediaObjectPrivate() {}
+
+ void _q_notify();
+
+ QMediaService *service;
+ QMetaDataReaderControl *metaDataControl;
+ QTimer* notifyTimer;
+ QSet<int> notifyProperties;
+
+ QMediaObject *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmediaplayer.cpp b/src/multimedia/qmediaplayer.cpp
new file mode 100644
index 000000000..5d5a7a7a3
--- /dev/null
+++ b/src/multimedia/qmediaplayer.cpp
@@ -0,0 +1,1139 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qpointer.h>
+
+
+#include "qmediaplayer.h"
+
+#include <qmediaobject_p.h>
+#include <qmediaservice.h>
+#include <qmediaplayercontrol.h>
+#include <qmediaserviceprovider.h>
+#include <qmediaplaylist.h>
+#include <qmediaplaylistcontrol.h>
+#include <qmediaplaylistsourcecontrol.h>
+#include <qvideosurfaceoutput_p.h>
+#include <qmedianetworkaccesscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlayer
+ \brief The QMediaPlayer class allows the playing of a media source.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+
+
+ The QMediaPlayer class is a high level media playback class. It can be used
+ to playback such content as songs, movies and internet radio. The content
+ to playback is specified as a QMediaContent, which can be thought of as a
+ main or canonical URL with addition information attached. When provided
+ with a QMediaContent playback may be able to commence.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Player
+
+ QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist
+ for accessing playlist functionality.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Movie playlist
+
+ \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist
+*/
+
+namespace
+{
+class MediaPlayerRegisterMetaTypes
+{
+public:
+ MediaPlayerRegisterMetaTypes()
+ {
+ qRegisterMetaType<QMediaPlayer::State>("QMediaPlayer::State");
+ qRegisterMetaType<QMediaPlayer::MediaStatus>("QMediaPlayer::MediaStatus");
+ qRegisterMetaType<QMediaPlayer::Error>("QMediaPlayer::Error");
+ }
+} _registerPlayerMetaTypes;
+}
+
+class QMediaPlayerPrivate : public QMediaObjectPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaPlayer)
+
+public:
+ QMediaPlayerPrivate()
+ : provider(0)
+ , control(0)
+ , playlistSourceControl(0)
+ , state(QMediaPlayer::StoppedState)
+ , error(QMediaPlayer::NoError)
+ , filterStates(false)
+ , playlist(0)
+ {}
+
+ QMediaServiceProvider *provider;
+ QMediaPlayerControl* control;
+ QMediaPlaylistSourceControl* playlistSourceControl;
+ QMediaPlayer::State state;
+ QMediaPlayer::Error error;
+ QString errorString;
+ bool filterStates;
+
+ QPointer<QObject> videoOutput;
+ QMediaPlaylist *playlist;
+ QMediaNetworkAccessControl *networkAccessControl;
+ QVideoSurfaceOutput surfaceOutput;
+
+ void _q_stateChanged(QMediaPlayer::State state);
+ void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void _q_error(int error, const QString &errorString);
+ void _q_updateMedia(const QMediaContent&);
+ void _q_playlistDestroyed();
+};
+
+void QMediaPlayerPrivate::_q_stateChanged(QMediaPlayer::State ps)
+{
+ Q_Q(QMediaPlayer);
+
+ if (filterStates)
+ return;
+
+ if (playlist
+ && ps != state && ps == QMediaPlayer::StoppedState
+ && (control->mediaStatus() == QMediaPlayer::EndOfMedia ||
+ control->mediaStatus() == QMediaPlayer::InvalidMedia)) {
+ playlist->next();
+ ps = control->state();
+ }
+
+ if (ps != state) {
+ state = ps;
+
+ if (ps == QMediaPlayer::PlayingState)
+ q->addPropertyWatch("position");
+ else
+ q->removePropertyWatch("position");
+
+ emit q->stateChanged(ps);
+ }
+}
+
+void QMediaPlayerPrivate::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status)
+{
+ Q_Q(QMediaPlayer);
+
+ switch (status) {
+ case QMediaPlayer::StalledMedia:
+ case QMediaPlayer::BufferingMedia:
+ q->addPropertyWatch("bufferStatus");
+ emit q->mediaStatusChanged(status);
+ break;
+ default:
+ q->removePropertyWatch("bufferStatus");
+ emit q->mediaStatusChanged(status);
+ break;
+ }
+
+}
+
+void QMediaPlayerPrivate::_q_error(int error, const QString &errorString)
+{
+ Q_Q(QMediaPlayer);
+
+ this->error = QMediaPlayer::Error(error);
+ this->errorString = errorString;
+
+ emit q->error(this->error);
+}
+
+void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media)
+{
+ Q_Q(QMediaPlayer);
+
+ if (!control)
+ return;
+
+ const QMediaPlayer::State currentState = state;
+
+ filterStates = true;
+ control->setMedia(media, 0);
+
+ if (!media.isNull()) {
+ switch (currentState) {
+ case QMediaPlayer::PlayingState:
+ control->play();
+ break;
+ case QMediaPlayer::PausedState:
+ control->pause();
+ break;
+ default:
+ break;
+ }
+ }
+ filterStates = false;
+
+ state = control->state();
+
+ if (state != currentState) {
+ if (state == QMediaPlayer::PlayingState)
+ q->addPropertyWatch("position");
+ else
+ q->removePropertyWatch("position");
+
+ emit q->stateChanged(state);
+ }
+}
+
+void QMediaPlayerPrivate::_q_playlistDestroyed()
+{
+ playlist = 0;
+
+ if (!control)
+ return;
+
+ if (playlistSourceControl)
+ playlistSourceControl->setPlaylist(0);
+
+ control->setMedia(QMediaContent(), 0);
+}
+
+static QMediaService *playerService(QMediaPlayer::Flags flags, QMediaServiceProvider *provider)
+{
+ if (flags) {
+ QMediaServiceProviderHint::Features features = 0;
+ if (flags & QMediaPlayer::LowLatency)
+ features |= QMediaServiceProviderHint::LowLatencyPlayback;
+
+ if (flags & QMediaPlayer::StreamPlayback)
+ features |= QMediaServiceProviderHint::StreamPlayback;
+
+ if (flags & QMediaPlayer::VideoSurface)
+ features |= QMediaServiceProviderHint::VideoSurface;
+
+ return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER,
+ QMediaServiceProviderHint(features));
+ } else
+ return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER);
+}
+
+
+/*!
+ Construct a QMediaPlayer that uses the playback service from \a provider,
+ parented to \a parent and with \a flags.
+
+ If a playback service is not specified the system default will be used.
+ \since 1.0
+*/
+
+QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags, QMediaServiceProvider *provider):
+ QMediaObject(*new QMediaPlayerPrivate,
+ parent,
+ playerService(flags,provider))
+{
+ Q_D(QMediaPlayer);
+
+ d->provider = provider;
+
+ if (d->service == 0) {
+ d->error = ServiceMissingError;
+ } else {
+ d->control = qobject_cast<QMediaPlayerControl*>(d->service->requestControl(QMediaPlayerControl_iid));
+ d->playlistSourceControl = qobject_cast<QMediaPlaylistSourceControl*>(d->service->requestControl(QMediaPlaylistSourceControl_iid));
+ d->networkAccessControl = qobject_cast<QMediaNetworkAccessControl*>(d->service->requestControl(QMediaNetworkAccessControl_iid));
+ if (d->control != 0) {
+ connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SIGNAL(mediaChanged(QMediaContent)));
+ connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State)));
+ connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(d->control, SIGNAL(error(int,QString)), SLOT(_q_error(int,QString)));
+
+ connect(d->control, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
+ connect(d->control, SIGNAL(positionChanged(qint64)), SIGNAL(positionChanged(qint64)));
+ connect(d->control, SIGNAL(audioAvailableChanged(bool)), SIGNAL(audioAvailableChanged(bool)));
+ connect(d->control, SIGNAL(videoAvailableChanged(bool)), SIGNAL(videoAvailableChanged(bool)));
+ connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
+ connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
+ connect(d->control, SIGNAL(seekableChanged(bool)), SIGNAL(seekableChanged(bool)));
+ connect(d->control, SIGNAL(playbackRateChanged(qreal)), SIGNAL(playbackRateChanged(qreal)));
+ connect(d->control, SIGNAL(bufferStatusChanged(int)), SIGNAL(bufferStatusChanged(int)));
+
+ if (d->control->state() == PlayingState)
+ addPropertyWatch("position");
+
+ if (d->control->mediaStatus() == StalledMedia || d->control->mediaStatus() == BufferingMedia)
+ addPropertyWatch("bufferStatus");
+ }
+ if (d->networkAccessControl != 0) {
+ connect(d->networkAccessControl, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SIGNAL(networkConfigurationChanged(QNetworkConfiguration)));
+ }
+ }
+}
+
+
+/*!
+ Destroys the player object.
+*/
+
+QMediaPlayer::~QMediaPlayer()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->service) {
+ if (d->control)
+ d->service->releaseControl(d->control);
+ }
+
+ d->provider->releaseService(d->service);
+}
+
+QMediaContent QMediaPlayer::media() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->media();
+
+ return QMediaContent();
+}
+
+/*!
+ Returns the stream source of media data.
+
+ This is only valid if a stream was passed to setMedia().
+
+ \since 1.0
+ \sa setMedia()
+*/
+
+const QIODevice *QMediaPlayer::mediaStream() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->mediaStream();
+
+ return 0;
+}
+
+QMediaPlaylist *QMediaPlayer::playlist() const
+{
+ return d_func()->playlistSourceControl ?
+ d_func()->playlistSourceControl->playlist() :
+ d_func()->playlist;
+}
+
+void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->playlistSourceControl) {
+ if (d->playlistSourceControl->playlist())
+ disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ d->playlistSourceControl->setPlaylist(playlist);
+
+ if (playlist)
+ connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+ } else {
+ if (d->playlist) {
+ disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_updateMedia(QMediaContent)));
+ disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+ }
+
+ d->playlist = playlist;
+
+ if (d->playlist) {
+ connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SLOT(_q_updateMedia(QMediaContent)));
+ connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
+
+ if (d->control != 0)
+ d->control->setMedia(playlist->currentMedia(), 0);
+ } else {
+ setMedia(QMediaContent(), 0);
+ }
+
+ }
+}
+
+/*!
+ Sets the network access points for remote media playback.
+ \a configurations contains, in ascending preferential order, a list of
+ configuration that can be used for network access.
+
+ This will invalidate the choice of previous configurations.
+ \since 1.2
+*/
+void QMediaPlayer::setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->networkAccessControl)
+ d->networkAccessControl->setConfigurations(configurations);
+}
+
+QMediaPlayer::State QMediaPlayer::state() const
+{
+ return d_func()->state;
+}
+
+QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->mediaStatus();
+
+ return QMediaPlayer::UnknownMediaStatus;
+}
+
+qint64 QMediaPlayer::duration() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->duration();
+
+ return -1;
+}
+
+qint64 QMediaPlayer::position() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->position();
+
+ return 0;
+}
+
+int QMediaPlayer::volume() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->volume();
+
+ return 0;
+}
+
+bool QMediaPlayer::isMuted() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isMuted();
+
+ return false;
+}
+
+int QMediaPlayer::bufferStatus() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->bufferStatus();
+
+ return 0;
+}
+
+bool QMediaPlayer::isAudioAvailable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isAudioAvailable();
+
+ return false;
+}
+
+bool QMediaPlayer::isVideoAvailable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isVideoAvailable();
+
+ return false;
+}
+
+bool QMediaPlayer::isSeekable() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->isSeekable();
+
+ return false;
+}
+
+qreal QMediaPlayer::playbackRate() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->control != 0)
+ return d->control->playbackRate();
+
+ return 0.0;
+}
+
+/*!
+ Returns the current error state.
+ \since 1.0
+*/
+
+QMediaPlayer::Error QMediaPlayer::error() const
+{
+ return d_func()->error;
+}
+
+QString QMediaPlayer::errorString() const
+{
+ return d_func()->errorString;
+}
+
+/*!
+ Returns the current network access point in use.
+ If a default contructed QNetworkConfiguration is returned
+ this feature is not available or that none of the
+ current supplied configurations are in use.
+ \since 1.2
+*/
+QNetworkConfiguration QMediaPlayer::currentNetworkConfiguration() const
+{
+ Q_D(const QMediaPlayer);
+
+ if (d->networkAccessControl)
+ return d_func()->networkAccessControl->currentConfiguration();
+
+ return QNetworkConfiguration();
+}
+
+//public Q_SLOTS:
+/*!
+ Start or resume playing the current source.
+ \since 1.0
+*/
+
+void QMediaPlayer::play()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0) {
+ QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection,
+ Q_ARG(int, QMediaPlayer::ServiceMissingError),
+ Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")));
+ return;
+ }
+
+ //if playlist control is available, the service should advance itself
+ if (d->playlist && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty())
+ d->playlist->setCurrentIndex(0);
+
+ // Reset error conditions
+ d->error = NoError;
+ d->errorString = QString();
+
+ d->control->play();
+}
+
+/*!
+ Pause playing the current source.
+ \since 1.0
+*/
+
+void QMediaPlayer::pause()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->pause();
+}
+
+/*!
+ Stop playing, and reset the play position to the beginning.
+ \since 1.0
+*/
+
+void QMediaPlayer::stop()
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->stop();
+}
+
+void QMediaPlayer::setPosition(qint64 position)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0 || !isSeekable())
+ return;
+
+ d->control->setPosition(qBound(qint64(0), position, duration()));
+}
+
+void QMediaPlayer::setVolume(int v)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0)
+ return;
+
+ int clamped = qBound(0, v, 100);
+ if (clamped == volume())
+ return;
+
+ d->control->setVolume(clamped);
+}
+
+void QMediaPlayer::setMuted(bool muted)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control == 0 || muted == isMuted())
+ return;
+
+ d->control->setMuted(muted);
+}
+
+void QMediaPlayer::setPlaybackRate(qreal rate)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->control != 0)
+ d->control->setPlaybackRate(rate);
+}
+
+/*!
+ Sets the current \a media source.
+
+ If a \a stream is supplied; media data will be read from it instead of resolving the media
+ source. In this case the media source may still be used to resolve additional information
+ about the media such as mime type.
+
+ Setting the media to a null QMediaContent will cause the player to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+ \since 1.0
+*/
+
+void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream)
+{
+ Q_D(QMediaPlayer);
+
+ if (playlist() && playlist()->currentMedia() != media)
+ setPlaylist(0);
+
+ if (d->control != 0)
+ d_func()->control->setMedia(media, stream);
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+
+bool QMediaPlayer::bind(QObject *obj)
+{
+ return QMediaObject::bind(obj);
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+
+void QMediaPlayer::unbind(QObject *obj)
+{
+ QMediaObject::unbind(obj);
+}
+
+/*!
+ Returns the level of support a media player has for a \a mimeType and a set of \a codecs.
+
+ The \a flags argument allows additional requirements such as performance indicators to be
+ specified.
+ \since 1.0
+*/
+QtMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType,
+ const QStringList& codecs,
+ Flags flags)
+{
+ return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
+ mimeType,
+ codecs,
+ flags);
+}
+
+/*!
+ \deprecated
+ Returns a list of MIME types supported by the media player.
+
+ The \a flags argument causes the resultant list to be restricted to MIME types which can be supported
+ given additional requirements, such as performance indicators.
+
+ This function may not return useful results on some platforms, and support for a specific file of a
+ given mime type is not guaranteed even if the mime type is in general supported. In addition, in some
+ cases this function will need to load all available media plugins and query them for their support, which
+ may take some time.
+ \since 1.0
+*/
+QStringList QMediaPlayer::supportedMimeTypes(Flags flags)
+{
+ return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER),
+ flags);
+}
+
+/*!
+ \fn void QMediaPlayer::setVideoOutput(QVideoWidget* output)
+
+ Attach a QVideoWidget video \a output to the media player.
+
+ If the media player has already video output attached,
+ it will be replaced with a new one.
+ \since 1.0
+*/
+void QMediaPlayer::setVideoOutput(QVideoWidget *output)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ // We don't know (in this library) that QVideoWidget inherits QObject
+ QObject *outputObject = reinterpret_cast<QObject*>(output);
+
+ d->videoOutput = outputObject && bind(outputObject) ? outputObject : 0;
+}
+
+/*!
+ \fn void QMediaPlayer::setVideoOutput(QGraphicsVideoItem* output)
+
+ Attach a QGraphicsVideoItem video \a output to the media player.
+
+ If the media player has already video output attached,
+ it will be replaced with a new one.
+ \since 1.0
+*/
+void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)
+{
+ Q_D(QMediaPlayer);
+
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
+ // but QObject inheritance depends on QObject coming first, so try this out.
+ QObject *outputObject = reinterpret_cast<QObject*>(output);
+
+ d->videoOutput = outputObject && bind(outputObject) ? outputObject : 0;
+}
+
+/*!
+ Sets a video \a surface as the video output of a media player.
+
+ If a video output has already been set on the media player the new surface
+ will replace it.
+ \since 1.2
+*/
+
+void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface)
+{
+ Q_D(QMediaPlayer);
+
+ d->surfaceOutput.setVideoSurface(surface);
+
+ if (d->videoOutput != &d->surfaceOutput) {
+ if (d->videoOutput)
+ unbind(d->videoOutput);
+
+ d->videoOutput = bind(&d->surfaceOutput) ? &d->surfaceOutput : 0;
+ }
+}
+
+// Enums
+/*!
+ \enum QMediaPlayer::State
+
+ Defines the current state of a media player.
+
+ \value PlayingState The media player is currently playing content.
+ \value PausedState The media player has paused playback, playback of the current track will
+ resume from the position the player was paused at.
+ \value StoppedState The media player is not playing content, playback will begin from the start
+ of the current track.
+*/
+
+/*!
+ \enum QMediaPlayer::MediaStatus
+
+ Defines the status of a media player's current media.
+
+ \value UnknownMediaStatus The status of the media cannot be determined.
+ \value NoMedia The is no current media. The player is in the StoppedState.
+ \value LoadingMedia The current media is being loaded. The player may be in any state.
+ \value LoadedMedia The current media has been loaded. The player is in the StoppedState.
+ \value StalledMedia Playback of the current media has stalled due to insufficient buffering or
+ some other temporary interruption. The player is in the PlayingState or PausedState.
+ \value BufferingMedia The player is buffering data but has enough data buffered for playback to
+ continue for the immediate future. The player is in the PlayingState or PausedState.
+ \value BufferedMedia The player has fully buffered the current media. The player is in the
+ PlayingState or PausedState.
+ \value EndOfMedia Playback has reached the end of the current media. The player is in the
+ StoppedState.
+ \value InvalidMedia The current media cannot be played. The player is in the StoppedState.
+*/
+
+/*!
+ \enum QMediaPlayer::Error
+
+ Defines a media player error condition.
+
+ \value NoError No error has occurred.
+ \value ResourceError A media resource couldn't be resolved.
+ \value FormatError The format of a media resource isn't (fully) supported. Playback may still
+ be possible, but without an audio or video component.
+ \value NetworkError A network error occurred.
+ \value AccessDeniedError There are not the appropriate permissions to play a media resource.
+ \value ServiceMissingError A valid playback service was not found, playback cannot proceed.
+*/
+
+// Signals
+/*!
+ \fn QMediaPlayer::error(QMediaPlayer::Error error)
+
+ Signals that an \a error condition has occurred.
+
+ \since 1.0
+ \sa errorString()
+*/
+
+/*!
+ \fn void QMediaPlayer::stateChanged(State state)
+
+ \since 1.0
+ Signal the \a state of the Player object has changed.
+*/
+
+/*!
+ \fn QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+
+ Signals that the \a status of the current media has changed.
+
+ \since 1.0
+ \sa mediaStatus()
+*/
+
+/*!
+ \fn void QMediaPlayer::mediaChanged(const QMediaContent &media);
+
+ Signals that the current playing content will be obtained from \a media.
+
+ \since 1.0
+ \sa media()
+*/
+
+/*!
+ \fn void QMediaPlayer::playbackRateChanged(qreal rate);
+
+ Signals the playbackRate has changed to \a rate.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::seekableChanged(bool seekable);
+
+ Signals the \a seekable status of the player object has changed.
+ \since 1.0
+*/
+
+// Properties
+/*!
+ \property QMediaPlayer::state
+ \brief the media player's playback state.
+
+ By default this property is QMediaPlayer::Stopped
+
+ \since 1.0
+ \sa mediaStatus(), play(), pause(), stop()
+*/
+
+/*!
+ \property QMediaPlayer::error
+ \brief a string describing the last error condition.
+
+ \since 1.0
+ \sa error()
+*/
+
+/*!
+ \property QMediaPlayer::media
+ \brief the active media source being used by the player object.
+
+ The player object will use the QMediaContent for selection of the content to
+ be played.
+
+ By default this property has a null QMediaContent.
+
+ Setting this property to a null QMediaContent will cause the player to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+
+ \since 1.0
+ \sa QMediaContent
+*/
+
+/*!
+ \property QMediaPlayer::playlist
+ \brief the media playlist being used by the player object.
+
+ The player object will use the current playlist item for selection of the content to
+ be played.
+
+ By default this property is set to null.
+
+ If the media playlist is used as a source, QMediaPlayer::media is updated with
+ a current playlist item. The current source should be selected with
+ QMediaPlaylist::setCurrentIndex(int) instead of QMediaPlayer::setMedia(),
+ otherwise the current playlist will be discarded.
+
+ \since 1.0
+ \sa QMediaContent
+*/
+
+
+/*!
+ \property QMediaPlayer::mediaStatus
+ \brief the status of the current media stream.
+
+ The stream status describes how the playback of the current stream is
+ progressing.
+
+ By default this property is QMediaPlayer::NoMedia
+
+ \since 1.0
+ \sa state
+*/
+
+/*!
+ \property QMediaPlayer::duration
+ \brief the duration of the current media.
+
+ The value is the total playback time in milliseconds of the current media.
+ The value may change across the life time of the QMediaPlayer object and
+ may not be available when initial playback begins, connect to the
+ durationChanged() signal to receive status notifications.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::position
+ \brief the playback position of the current media.
+
+ The value is the current playback position, expressed in milliseconds since
+ the beginning of the media. Periodically changes in the position will be
+ indicated with the signal positionChanged(), the interval between updates
+ can be set with QMediaObject's method setNotifyInterval().
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::volume
+ \brief the current playback volume.
+
+ The playback volume is a linear in effect and the value can range from 0 -
+ 100, values outside this range will be clamped.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::muted
+ \brief the muted state of the current media.
+
+ The value will be true if the playback volume is muted; otherwise false.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::bufferStatus
+ \brief the percentage of the temporary buffer filled before playback begins.
+
+ When the player object is buffering; this property holds the percentage of
+ the temporary buffer that is filled. The buffer will need to reach 100%
+ filled before playback can resume, at which time the MediaStatus will be
+ BufferedMedia.
+
+ \since 1.0
+ \sa mediaStatus()
+*/
+
+/*!
+ \property QMediaPlayer::audioAvailable
+ \brief the audio availabilty status for the current media.
+
+ As the life time of QMediaPlayer can be longer than the playback of one
+ QMediaContent, this property may change over time, the
+ audioAvailableChanged signal can be used to monitor it's status.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::videoAvailable
+ \brief the video availability status for the current media.
+
+ If available, the QVideoWidget class can be used to view the video. As the
+ life time of QMediaPlayer can be longer than the playback of one
+ QMediaContent, this property may change over time, the
+ videoAvailableChanged signal can be used to monitor it's status.
+
+ \since 1.0
+ \sa QVideoWidget, QMediaContent
+*/
+
+/*!
+ \property QMediaPlayer::seekable
+ \brief the seek-able status of the current media
+
+ If seeking is supported this property will be true; false otherwise. The
+ status of this property may change across the life time of the QMediaPlayer
+ object, use the seekableChanged signal to monitor changes.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlayer::playbackRate
+ \brief the playback rate of the current media.
+
+ This value is a multiplier applied to the media's standard play rate. By
+ default this value is 1.0, indicating that the media is playing at the
+ standard pace. Values higher than 1.0 will increase the rate of play.
+ Values less than zero can be set and indicate the media will rewind at the
+ multiplier of the standard pace.
+
+ Not all playback services support change of the playback rate. It is
+ framework defined as to the status and quality of audio and video
+ while fast forwarding or rewinding.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::durationChanged(qint64 duration)
+
+ Signal the duration of the content has changed to \a duration, expressed in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::positionChanged(qint64 position)
+
+ Signal the position of the content has changed to \a position, expressed in
+ milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::volumeChanged(int volume)
+
+ Signal the playback volume has changed to \a volume.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::mutedChanged(bool muted)
+
+ Signal the mute state has changed to \a muted.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::videoAvailableChanged(bool videoAvailable)
+
+ Signal the availability of visual content has changed to \a videoAvailable.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::audioAvailableChanged(bool available)
+
+ Signals the availability of audio content has changed to \a available.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)
+
+ Signal the amount of the local buffer filled as a percentage by \a percentFilled.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlayer::networkConfigurationChanged(const QNetworkConfiguration &configuration)
+
+ Signal that the active in use network access point has been changed to \a configuration and all subsequent network access will use this \a configuration.
+ \since 1.2
+*/
+
+/*!
+ \enum QMediaPlayer::Flag
+
+ \value LowLatency The player is expected to be used with simple audio formats,
+ but playback should start without significant delay.
+ Such playback service can be used for beeps, ringtones, etc.
+
+ \value StreamPlayback The player is expected to play QIODevice based streams.
+ If passed to QMediaPlayer constructor, the service supporting
+ streams playback will be chosen.
+
+ \value VideoSurface The player is expected to be able to render to a
+ QAbstractVideoSurface \l {setVideoOutput()}{output}.
+*/
+
+#include "moc_qmediaplayer.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplayer.h b/src/multimedia/qmediaplayer.h
new file mode 100644
index 000000000..f53b50ceb
--- /dev/null
+++ b/src/multimedia/qmediaplayer.h
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYER_H
+#define QMEDIAPLAYER_H
+
+
+#include "qmediaserviceprovider.h"
+#include "qmediaobject.h"
+#include "qmediacontent.h"
+#include "qmediaenumdebug.h"
+
+#include <QtNetwork/qnetworkconfiguration.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoSurface;
+class QMediaPlaylist;
+class QVideoWidget;
+class QGraphicsVideoItem;
+
+class QMediaPlayerPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaPlayer : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaContent media READ media WRITE setMedia NOTIFY mediaChanged)
+ Q_PROPERTY(QMediaPlaylist * playlist READ playlist WRITE setPlaylist)
+ Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(int bufferStatus READ bufferStatus NOTIFY bufferStatusChanged)
+ Q_PROPERTY(bool audioAvailable READ isAudioAvailable NOTIFY audioAvailableChanged)
+ Q_PROPERTY(bool videoAvailable READ isVideoAvailable NOTIFY videoAvailableChanged)
+ Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged)
+ Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged)
+ Q_PROPERTY(QString error READ errorString)
+ Q_ENUMS(State)
+ Q_ENUMS(MediaStatus)
+ Q_ENUMS(Error)
+
+public:
+ enum State
+ {
+ StoppedState,
+ PlayingState,
+ PausedState
+ };
+
+ enum MediaStatus
+ {
+ UnknownMediaStatus,
+ NoMedia,
+ LoadingMedia,
+ LoadedMedia,
+ StalledMedia,
+ BufferingMedia,
+ BufferedMedia,
+ EndOfMedia,
+ InvalidMedia
+ };
+
+ enum Flag
+ {
+ LowLatency = 0x01,
+ StreamPlayback = 0x02,
+ VideoSurface = 0x04
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ enum Error
+ {
+ NoError,
+ ResourceError,
+ FormatError,
+ NetworkError,
+ AccessDeniedError,
+ ServiceMissingError
+ };
+
+ QMediaPlayer(QObject *parent = 0, Flags flags = 0, QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider());
+ ~QMediaPlayer();
+
+ static QtMultimedia::SupportEstimate hasSupport(const QString &mimeType,
+ const QStringList& codecs = QStringList(),
+ Flags flags = 0);
+ static QStringList supportedMimeTypes(Flags flags = 0);
+
+ void setVideoOutput(QVideoWidget *);
+ void setVideoOutput(QGraphicsVideoItem *);
+ void setVideoOutput(QAbstractVideoSurface *surface);
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ QMediaPlaylist *playlist() const;
+
+ State state() const;
+ MediaStatus mediaStatus() const;
+
+ qint64 duration() const;
+ qint64 position() const;
+
+ int volume() const;
+ bool isMuted() const;
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ int bufferStatus() const;
+
+ bool isSeekable() const;
+ qreal playbackRate() const;
+
+ Error error() const;
+ QString errorString() const;
+
+ QNetworkConfiguration currentNetworkConfiguration() const;
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+ void setPosition(qint64 position);
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void setPlaybackRate(qreal rate);
+
+ void setMedia(const QMediaContent &media, QIODevice *stream = 0);
+ void setPlaylist(QMediaPlaylist *playlist);
+
+ void setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent &media);
+
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool available);
+ void videoAvailableChanged(bool videoAvailable);
+
+ void bufferStatusChanged(int percentFilled);
+
+ void seekableChanged(bool seekable);
+ void playbackRateChanged(qreal rate);
+
+ void error(QMediaPlayer::Error error);
+
+ void networkConfigurationChanged(const QNetworkConfiguration &configuration);
+public:
+ virtual bool bind(QObject *);
+ virtual void unbind(QObject *);
+
+private:
+ Q_DISABLE_COPY(QMediaPlayer)
+ Q_DECLARE_PRIVATE(QMediaPlayer)
+ Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaPlayer::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus))
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateMedia(const QMediaContent&))
+ Q_PRIVATE_SLOT(d_func(), void _q_playlistDestroyed())
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaPlayer::State)
+Q_DECLARE_METATYPE(QMediaPlayer::MediaStatus)
+Q_DECLARE_METATYPE(QMediaPlayer::Error)
+
+Q_MEDIA_ENUM_DEBUG(QMediaPlayer, State)
+Q_MEDIA_ENUM_DEBUG(QMediaPlayer, MediaStatus)
+Q_MEDIA_ENUM_DEBUG(QMediaPlayer, Error)
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYER_H
diff --git a/src/multimedia/qmediaplayercontrol.cpp b/src/multimedia/qmediaplayercontrol.cpp
new file mode 100644
index 000000000..2585b044c
--- /dev/null
+++ b/src/multimedia/qmediaplayercontrol.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaplayercontrol.h"
+#include "qmediacontrol_p.h"
+#include "qmediaplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMediaPlayerControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMediaPlayerControl class provides access to the media playing
+ functionality of a QMediaService.
+
+ If a QMediaService can play media is will implement QMediaPlayerControl.
+ This control provides a means to set the \l {setMedia()}{media} to play,
+ \l {play()}{start}, \l {pause()} {pause} and \l {stop()}{stop} playback,
+ \l {setPosition()}{seek}, and control the \l {setVolume()}{volume}.
+ It also provides feedback on the \l {duration()}{duration} of the media,
+ the current \l {position()}{position}, and \l {bufferStatus()}{buffering}
+ progress.
+
+ The functionality provided by this control is exposed to application
+ code through the QMediaPlayer class.
+
+ The interface name of QMediaPlayerControl is \c com.nokia.Qt.QMediaPlayerControl/1.0 as
+ defined in QMediaPlayerControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaPlayerControl_iid
+
+ \c com.nokia.Qt.QMediaPlayerControl/1.0
+
+ Defines the interface name of the QMediaPlayerControl class.
+
+ \relates QMediaPlayerControl
+*/
+
+/*!
+ Destroys a media player control.
+*/
+QMediaPlayerControl::~QMediaPlayerControl()
+{
+}
+
+/*!
+ Constructs a new media player control with the given \a parent.
+*/
+QMediaPlayerControl::QMediaPlayerControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ \fn QMediaPlayerControl::state() const
+
+ Returns the state of a player control.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::stateChanged(QMediaPlayer::State state)
+
+ Signals that the \a state of a player control has changed.
+
+ \since 1.0
+ \sa state()
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStatus() const
+
+ Returns the status of the current media.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+
+ Signals that the \a status of the current media has changed.
+
+ \since 1.0
+ \sa mediaStatus()
+*/
+
+
+/*!
+ \fn QMediaPlayerControl::duration() const
+
+ Returns the duration of the current media in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::durationChanged(qint64 duration)
+
+ Signals that the \a duration of the current media has changed.
+
+ \since 1.0
+ \sa duration()
+*/
+
+/*!
+ \fn QMediaPlayerControl::position() const
+
+ Returns the current playback position in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::setPosition(qint64 position)
+
+ Sets the playback \a position of the current media. This will initiate a seek and it may take
+ some time for playback to reach the position set.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::positionChanged(qint64 position)
+
+ Signals the playback \a position has changed.
+
+ This is only emitted in when there has been a discontinous change in the playback postion, such
+ as a seek or the position being reset.
+
+ \since 1.0
+ \sa position()
+*/
+
+/*!
+ \fn QMediaPlayerControl::volume() const
+
+ Returns the audio volume of a player control.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::setVolume(int volume)
+
+ Sets the audio \a volume of a player control.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::volumeChanged(int volume)
+
+ Signals the audio \a volume of a player control has changed.
+
+ \since 1.0
+ \sa volume()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isMuted() const
+
+ Returns the mute state of a player control.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::setMuted(bool mute)
+
+ Sets the \a mute state of a player control.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::mutedChanged(bool mute)
+
+ Signals a change in the \a mute status of a player control.
+
+ \since 1.0
+ \sa isMuted()
+*/
+
+/*!
+ \fn QMediaPlayerControl::bufferStatus() const
+
+ Returns the buffering progress of the current media. Progress is measured in the percentage
+ of the buffer filled.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::bufferStatusChanged(int progress)
+
+ Signals that buffering \a progress has changed.
+
+ \since 1.0
+ \sa bufferStatus()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isAudioAvailable() const
+
+ Identifies if there is audio output available for the current media.
+
+ Returns true if audio output is available and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::audioAvailableChanged(bool audio)
+
+ Signals that there has been a change in the availability of \a audio output.
+
+ \since 1.0
+ \sa isAudioAvailable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isVideoAvailable() const
+
+ Identifies if there is video output available for the current media.
+
+ Returns true if video output is available and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::videoAvailableChanged(bool video)
+
+ Signals that there has been a change in the availability of \a video output.
+
+ \since 1.0
+ \sa isVideoAvailable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::isSeekable() const
+
+ Identifies if the current media is seekable.
+
+ Returns true if it possible to seek within the current media, and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::seekableChanged(bool seekable)
+
+ Signals that the \a seekable state of a player control has changed.
+
+ \since 1.0
+ \sa isSeekable()
+*/
+
+/*!
+ \fn QMediaPlayerControl::availablePlaybackRanges() const
+
+ Returns a range of times in milliseconds that can be played back.
+
+ Usually for local files this is a continuous interval equal to [0..duration()]
+ or an empty time range if seeking is not supported, but for network sources
+ it refers to the buffered parts of the media.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::availablePlaybackRangesChanged(const QMediaTimeRange &ranges)
+
+ Signals that the available media playback \a ranges have changed.
+
+ \since 1.0
+ \sa QMediaPlayerControl::availablePlaybackRanges()
+*/
+
+/*!
+ \fn qreal QMediaPlayerControl::playbackRate() const
+
+ Returns the rate of playback.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::setPlaybackRate(qreal rate)
+
+ Sets the \a rate of playback.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::media() const
+
+ Returns the current media source.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaStream() const
+
+ Returns the current media stream. This is only a valid if a stream was passed to setMedia().
+
+ \since 1.0
+ \sa setMedia()
+*/
+
+/*!
+ \fn QMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
+
+ Sets the current \a media source. If a \a stream is supplied; data will be read from that
+ instead of attempting to resolve the media source. The media source may still be used to
+ supply media information such as mime type.
+
+ Setting the media to a null QMediaContent will cause the control to discard all
+ information relating to the current media source and to cease all I/O operations related
+ to that media.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::mediaChanged(const QMediaContent& content)
+
+ Signals that the current media \a content has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::play()
+
+ Starts playback of the current media.
+
+ If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState}
+ {playing} state.
+
+ \since 1.0
+ \sa state()
+*/
+
+/*!
+ \fn QMediaPlayerControl::pause()
+
+ Pauses playback of the current media.
+
+ If sucessful the player control will immediately enter the \l {QMediaPlayer::PausedState}
+ {paused} state.
+
+ \since 1.0
+ \sa state(), play(), stop()
+*/
+
+/*!
+ \fn QMediaPlayerControl::stop()
+
+ Stops playback of the current media.
+
+ If successful the player control will immediately enter the \l {QMediaPlayer::StoppedState}
+ {stopped} state.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::error(int error, const QString &errorString)
+
+ Signals that an \a error has occurred. The \a errorString provides a more detailed explanation.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlayerControl::playbackRateChanged(qreal rate)
+
+ Signal emitted when playback rate changes to \a rate.
+ \since 1.0
+*/
+
+#include "moc_qmediaplayercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplayercontrol.h b/src/multimedia/qmediaplayercontrol.h
new file mode 100644
index 000000000..a6e02ee9a
--- /dev/null
+++ b/src/multimedia/qmediaplayercontrol.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYERCONTROL_H
+#define QMEDIAPLAYERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediaplayer.h"
+#include "qmediatimerange.h"
+
+#include <QtCore/qpair.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylist;
+
+class Q_MULTIMEDIA_EXPORT QMediaPlayerControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QMediaPlayerControl();
+
+ virtual QMediaPlayer::State state() const = 0;
+
+ virtual QMediaPlayer::MediaStatus mediaStatus() const = 0;
+
+ virtual qint64 duration() const = 0;
+
+ virtual qint64 position() const = 0;
+ virtual void setPosition(qint64 position) = 0;
+
+ virtual int volume() const = 0;
+ virtual void setVolume(int volume) = 0;
+
+ virtual bool isMuted() const = 0;
+ virtual void setMuted(bool muted) = 0;
+
+ virtual int bufferStatus() const = 0;
+
+ virtual bool isAudioAvailable() const = 0;
+ virtual bool isVideoAvailable() const = 0;
+
+ virtual bool isSeekable() const = 0;
+
+ virtual QMediaTimeRange availablePlaybackRanges() const = 0;
+
+ virtual qreal playbackRate() const = 0;
+ virtual void setPlaybackRate(qreal rate) = 0;
+
+ virtual QMediaContent media() const = 0;
+ virtual const QIODevice *mediaStream() const = 0;
+ virtual void setMedia(const QMediaContent &media, QIODevice *stream) = 0;
+
+ virtual void play() = 0;
+ virtual void pause() = 0;
+ virtual void stop() = 0;
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent& content);
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+ 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 bufferStatusChanged(int percentFilled);
+ void seekableChanged(bool);
+ void availablePlaybackRangesChanged(const QMediaTimeRange&);
+ void playbackRateChanged(qreal rate);
+ void error(int error, const QString &errorString);
+
+protected:
+ QMediaPlayerControl(QObject* parent = 0);
+};
+
+#define QMediaPlayerControl_iid "com.nokia.Qt.QMediaPlayerControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaPlayerControl, QMediaPlayerControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYERCONTROL_H
+
diff --git a/src/multimedia/qmediaplaylist.cpp b/src/multimedia/qmediaplaylist.cpp
new file mode 100644
index 000000000..a5618ad5c
--- /dev/null
+++ b/src/multimedia/qmediaplaylist.cpp
@@ -0,0 +1,756 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaplaylist.h"
+#include "qmediaplaylist_p.h"
+#include "qmediaplaylistprovider.h"
+#include "qlocalmediaplaylistprovider.h"
+#include "qmediaplaylistioplugin.h"
+#include "qmediaservice.h"
+#include "qmediaplaylistcontrol.h"
+#include "qmediaplayercontrol.h"
+
+#include <QtCore/qlist.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qcoreapplication.h>
+
+#include "qmediapluginloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, playlistIOLoader,
+ (QMediaPlaylistIOInterface_iid, QLatin1String("playlistformats"), Qt::CaseInsensitive))
+
+
+/*!
+ \class QMediaPlaylist
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+
+ \brief The QMediaPlaylist class provides a list of media content to play.
+
+ QMediaPlaylist is intended to be used with other media objects,
+ like QMediaPlayer or QMediaImageViewer.
+
+ QMediaPlaylist allows to access the service intrinsic playlist functionality
+ if available, otherwise it provides the the local memory playlist implementation.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Movie playlist
+
+ Depending on playlist source implementation, most of the playlist mutating
+ operations can be asynchronous.
+
+ \sa QMediaContent
+*/
+
+
+/*!
+ \enum QMediaPlaylist::PlaybackMode
+
+ The QMediaPlaylist::PlaybackMode describes the order items in playlist are played.
+
+ \value CurrentItemOnce The current item is played only once.
+
+ \value CurrentItemInLoop The current item is played repeatedly in a loop.
+
+ \value Sequential Playback starts from the current and moves through each successive item until the last is reached and then stops.
+ The next item is a null item when the last one is currently playing.
+
+ \value Loop Playback restarts at the first item after the last has finished playing.
+
+ \value Random Play items in random order.
+*/
+
+
+
+/*!
+ Create a new playlist object for with the given \a parent.
+*/
+
+QMediaPlaylist::QMediaPlaylist(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaPlaylistPrivate)
+{
+ Q_D(QMediaPlaylist);
+
+ d->q_ptr = this;
+ d->localPlaylistControl = new QLocalMediaPlaylistControl(this);
+
+ setMediaObject(0);
+}
+
+/*!
+ Destroys the playlist.
+ */
+
+QMediaPlaylist::~QMediaPlaylist()
+{
+ Q_D(QMediaPlaylist);
+
+ if (d->mediaObject)
+ d->mediaObject->unbind(this);
+
+ delete d_ptr;
+}
+
+/*!
+ Returns the QMediaObject instance that this QMediaPlaylist is bound too,
+ or 0 otherwise.
+ \since 1.0
+*/
+QMediaObject *QMediaPlaylist::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+/*!
+ \internal
+ If \a mediaObject is null or doesn't have an intrinsic playlist,
+ internal local memory playlist source will be created.
+ \since 1.0
+*/
+bool QMediaPlaylist::setMediaObject(QMediaObject *mediaObject)
+{
+ Q_D(QMediaPlaylist);
+
+ if (mediaObject && mediaObject == d->mediaObject)
+ return true;
+
+ QMediaService *service = mediaObject
+ ? mediaObject->service() : 0;
+
+ QMediaPlaylistControl *newControl = 0;
+
+ if (service)
+ newControl = qobject_cast<QMediaPlaylistControl*>(service->requestControl(QMediaPlaylistControl_iid));
+
+ if (!newControl)
+ newControl = d->localPlaylistControl;
+
+ if (d->control != newControl) {
+ int oldSize = 0;
+ if (d->control) {
+ QMediaPlaylistProvider *playlist = d->control->playlistProvider();
+ oldSize = playlist->mediaCount();
+ disconnect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)),
+ this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString)));
+
+ disconnect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int)));
+ disconnect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int)));
+ disconnect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int)));
+ disconnect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int)));
+ disconnect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int)));
+
+ disconnect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded()));
+
+ disconnect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)),
+ this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
+ disconnect(d->control, SIGNAL(currentIndexChanged(int)),
+ this, SIGNAL(currentIndexChanged(int)));
+ disconnect(d->control, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SIGNAL(currentMediaChanged(QMediaContent)));
+
+ if (d->mediaObject)
+ d->mediaObject->service()->releaseControl(d->control);
+ }
+
+ d->control = newControl;
+ QMediaPlaylistProvider *playlist = d->control->playlistProvider();
+ connect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)),
+ this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString)));
+
+ connect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int)));
+ connect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int)));
+ connect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int)));
+ connect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int)));
+ connect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int)));
+
+ connect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded()));
+
+ connect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)),
+ this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
+ connect(d->control, SIGNAL(currentIndexChanged(int)),
+ this, SIGNAL(currentIndexChanged(int)));
+ connect(d->control, SIGNAL(currentMediaChanged(QMediaContent)),
+ this, SIGNAL(currentMediaChanged(QMediaContent)));
+
+ if (oldSize)
+ emit mediaRemoved(0, oldSize-1);
+
+ if (playlist->mediaCount()) {
+ emit mediaAboutToBeInserted(0,playlist->mediaCount()-1);
+ emit mediaInserted(0,playlist->mediaCount()-1);
+ }
+ }
+
+ d->mediaObject = mediaObject;
+
+ return true;
+}
+
+/*!
+ \property QMediaPlaylist::playbackMode
+
+ This property defines the order, items in playlist are played.
+
+ \since 1.0
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+QMediaPlaylist::PlaybackMode QMediaPlaylist::playbackMode() const
+{
+ return d_func()->control->playbackMode();
+}
+
+void QMediaPlaylist::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+{
+ Q_D(QMediaPlaylist);
+ d->control->setPlaybackMode(mode);
+}
+
+/*!
+ Returns position of the current media content in the playlist.
+ \since 1.0
+*/
+int QMediaPlaylist::currentIndex() const
+{
+ return d_func()->control->currentIndex();
+}
+
+/*!
+ Returns the current media content.
+ \since 1.0
+*/
+
+QMediaContent QMediaPlaylist::currentMedia() const
+{
+ return d_func()->playlist()->media(currentIndex());
+}
+
+/*!
+ Returns the index of the item, which would be current after calling next()
+ \a steps times.
+
+ Returned value depends on the size of playlist, current position
+ and playback mode.
+
+ \since 1.0
+ \sa QMediaPlaylist::playbackMode
+*/
+int QMediaPlaylist::nextIndex(int steps) const
+{
+ return d_func()->control->nextIndex(steps);
+}
+
+/*!
+ Returns the index of the item, which would be current after calling previous()
+ \a steps times.
+
+ \since 1.0
+ \sa QMediaPlaylist::playbackMode
+*/
+
+int QMediaPlaylist::previousIndex(int steps) const
+{
+ return d_func()->control->previousIndex(steps);
+}
+
+
+/*!
+ Returns the number of items in the playlist.
+
+ \since 1.0
+ \sa isEmpty()
+ */
+int QMediaPlaylist::mediaCount() const
+{
+ return d_func()->playlist()->mediaCount();
+}
+
+/*!
+ Returns true if the playlist contains no items; otherwise returns false.
+
+ \since 1.0
+ \sa mediaCount()
+ */
+bool QMediaPlaylist::isEmpty() const
+{
+ return mediaCount() == 0;
+}
+
+/*!
+ Returns true if the playlist can be modified; otherwise returns false.
+
+ \since 1.0
+ \sa mediaCount()
+ */
+bool QMediaPlaylist::isReadOnly() const
+{
+ return d_func()->playlist()->isReadOnly();
+}
+
+/*!
+ Returns the media content at \a index in the playlist.
+ \since 1.0
+*/
+
+QMediaContent QMediaPlaylist::media(int index) const
+{
+ return d_func()->playlist()->media(index);
+}
+
+/*!
+ Append the media \a content to the playlist.
+
+ Returns true if the operation is successful, otherwise return false.
+ \since 1.0
+ */
+bool QMediaPlaylist::addMedia(const QMediaContent &content)
+{
+ return d_func()->control->playlistProvider()->addMedia(content);
+}
+
+/*!
+ Append multiple media content \a items to the playlist.
+
+ Returns true if the operation is successful, otherwise return false.
+ \since 1.0
+ */
+bool QMediaPlaylist::addMedia(const QList<QMediaContent> &items)
+{
+ return d_func()->control->playlistProvider()->addMedia(items);
+}
+
+/*!
+ Insert the media \a content to the playlist at position \a pos.
+
+ Returns true if the operation is successful, otherwise false.
+ \since 1.0
+*/
+
+bool QMediaPlaylist::insertMedia(int pos, const QMediaContent &content)
+{
+ return d_func()->playlist()->insertMedia(pos, content);
+}
+
+/*!
+ Insert multiple media content \a items to the playlist at position \a pos.
+
+ Returns true if the operation is successful, otherwise false.
+ \since 1.0
+*/
+
+bool QMediaPlaylist::insertMedia(int pos, const QList<QMediaContent> &items)
+{
+ return d_func()->playlist()->insertMedia(pos, items);
+}
+
+/*!
+ Remove the item from the playlist at position \a pos.
+
+ Returns true if the operation is successful, otherwise return false.
+ \since 1.0
+ */
+bool QMediaPlaylist::removeMedia(int pos)
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->removeMedia(pos);
+}
+
+/*!
+ Remove items in the playlist from \a start to \a end inclusive.
+
+ Returns true if the operation is successful, otherwise return false.
+ \since 1.0
+ */
+bool QMediaPlaylist::removeMedia(int start, int end)
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->removeMedia(start, end);
+}
+
+/*!
+ Remove all the items from the playlist.
+
+ Returns true if the operation is successful, otherwise return false.
+ \since 1.0
+ */
+bool QMediaPlaylist::clear()
+{
+ Q_D(QMediaPlaylist);
+ return d->playlist()->clear();
+}
+
+bool QMediaPlaylistPrivate::readItems(QMediaPlaylistReader *reader)
+{
+ while (!reader->atEnd())
+ playlist()->addMedia(reader->readItem());
+
+ return true;
+}
+
+bool QMediaPlaylistPrivate::writeItems(QMediaPlaylistWriter *writer)
+{
+ for (int i=0; i<playlist()->mediaCount(); i++) {
+ if (!writer->writeItem(playlist()->media(i)))
+ return false;
+ }
+ writer->close();
+ return true;
+}
+
+/*!
+ Load playlist from \a location. If \a format is specified, it is used,
+ otherwise format is guessed from location name and data.
+
+ New items are appended to playlist.
+
+ QMediaPlaylist::loaded() signal is emitted if playlist was loaded successfully,
+ otherwise the playlist emits loadFailed().
+ \since 1.0
+*/
+void QMediaPlaylist::load(const QUrl &location, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->load(location,format))
+ return;
+
+ if (isReadOnly()) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("Could not add items to read only playlist.");
+ emit loadFailed();
+ return;
+ }
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canRead(location,format)) {
+ QMediaPlaylistReader *reader = plugin->createReader(location,QByteArray(format));
+ if (reader && d->readItems(reader)) {
+ delete reader;
+ emit loaded();
+ return;
+ }
+ delete reader;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported");
+ emit loadFailed();
+
+ return;
+}
+
+/*!
+ Load playlist from QIODevice \a device. If \a format is specified, it is used,
+ otherwise format is guessed from device data.
+
+ New items are appended to playlist.
+
+ QMediaPlaylist::loaded() signal is emitted if playlist was loaded successfully,
+ otherwise the playlist emits loadFailed().
+ \since 1.0
+*/
+void QMediaPlaylist::load(QIODevice * device, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->load(device,format))
+ return;
+
+ if (isReadOnly()) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("Could not add items to read only playlist.");
+ emit loadFailed();
+ return;
+ }
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canRead(device,format)) {
+ QMediaPlaylistReader *reader = plugin->createReader(device,QByteArray(format));
+ if (reader && d->readItems(reader)) {
+ delete reader;
+ emit loaded();
+ return;
+ }
+ delete reader;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported");
+ emit loadFailed();
+
+ return;
+}
+
+/*!
+ Save playlist to \a location. If \a format is specified, it is used,
+ otherwise format is guessed from location name.
+
+ Returns true if playlist was saved successfully, otherwise returns false.
+ \since 1.0
+ */
+bool QMediaPlaylist::save(const QUrl &location, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->save(location,format))
+ return true;
+
+ QFile file(location.toLocalFile());
+
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ d->error = AccessDeniedError;
+ d->errorString = tr("The file could not be accessed.");
+ return false;
+ }
+
+ return save(&file, format);
+}
+
+/*!
+ Save playlist to QIODevice \a device using format \a format.
+
+ Returns true if playlist was saved successfully, otherwise returns false.
+ \since 1.0
+*/
+bool QMediaPlaylist::save(QIODevice * device, const char *format)
+{
+ Q_D(QMediaPlaylist);
+
+ d->error = NoError;
+ d->errorString.clear();
+
+ if (d->playlist()->save(device,format))
+ return true;
+
+ foreach (QString const& key, playlistIOLoader()->keys()) {
+ QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key));
+ if (plugin && plugin->canWrite(device,format)) {
+ QMediaPlaylistWriter *writer = plugin->createWriter(device,QByteArray(format));
+ if (writer && d->writeItems(writer)) {
+ delete writer;
+ return true;
+ }
+ delete writer;
+ }
+ }
+
+ d->error = FormatNotSupportedError;
+ d->errorString = tr("Playlist format is not supported.");
+
+ return false;
+}
+
+/*!
+ Returns the last error condition.
+ \since 1.0
+*/
+QMediaPlaylist::Error QMediaPlaylist::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns the string describing the last error condition.
+ \since 1.0
+*/
+QString QMediaPlaylist::errorString() const
+{
+ return d_func()->errorString;
+}
+
+/*!
+ Shuffle items in the playlist.
+ \since 1.0
+*/
+void QMediaPlaylist::shuffle()
+{
+ d_func()->playlist()->shuffle();
+}
+
+
+/*!
+ Advance to the next media content in playlist.
+ \since 1.0
+*/
+void QMediaPlaylist::next()
+{
+ d_func()->control->next();
+}
+
+/*!
+ Return to the previous media content in playlist.
+ \since 1.0
+*/
+void QMediaPlaylist::previous()
+{
+ d_func()->control->previous();
+}
+
+/*!
+ Activate media content from playlist at position \a playlistPosition.
+ \since 1.0
+*/
+
+void QMediaPlaylist::setCurrentIndex(int playlistPosition)
+{
+ d_func()->control->setCurrentIndex(playlistPosition);
+}
+
+/*!
+ \fn void QMediaPlaylist::mediaInserted(int start, int end)
+
+ This signal is emitted after media has been inserted into the playlist.
+ The new items are those between \a start and \a end inclusive.
+ \since 1.0
+ */
+
+/*!
+ \fn void QMediaPlaylist::mediaRemoved(int start, int end)
+
+ This signal is emitted after media has been removed from the playlist.
+ The removed items are those between \a start and \a end inclusive.
+ \since 1.0
+ */
+
+/*!
+ \fn void QMediaPlaylist::mediaChanged(int start, int end)
+
+ This signal is emitted after media has been changed in the playlist
+ between \a start and \a end positions inclusive.
+ \since 1.0
+ */
+
+/*!
+ \fn void QMediaPlaylist::currentIndexChanged(int position)
+
+ Signal emitted when playlist position changed to \a position.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylist::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signal emitted when playback mode changed to \a mode.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylist::mediaAboutToBeInserted(int start, int end)
+
+ Signal emitted when items are to be inserted at \a start and ending at \a end.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylist::mediaAboutToBeRemoved(int start, int end)
+
+ Signal emitted when item are to be deleted at \a start and ending at \a end.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylist::currentMediaChanged(const QMediaContent &content)
+
+ Signal emitted when current media changes to \a content.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlaylist::currentIndex
+ \brief Current position.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaPlaylist::currentMedia
+ \brief Current media content.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylist::loaded()
+
+ Signal emitted when playlist finished loading.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylist::loadFailed()
+
+ Signal emitted if failed to load playlist.
+ \since 1.0
+*/
+
+/*!
+ \enum QMediaPlaylist::Error
+
+ This enum describes the QMediaPlaylist error codes.
+
+ \value NoError No errors.
+ \value FormatError Format error.
+ \value FormatNotSupportedError Format not supported.
+ \value NetworkError Network error.
+ \value AccessDeniedError Access denied error.
+*/
+
+#include "moc_qmediaplaylist.cpp"
+#include "moc_qmediaplaylist_p.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylist.h b/src/multimedia/qmediaplaylist.h
new file mode 100644
index 000000000..7b4b62260
--- /dev/null
+++ b/src/multimedia/qmediaplaylist.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLIST_H
+#define QMEDIAPLAYLIST_H
+
+#include <QtCore/qobject.h>
+
+#include <qmediacontent.h>
+#include <qmediaobject.h>
+#include <qmediabindableinterface.h>
+#include <qmediaenumdebug.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistProvider;
+
+class QMediaPlaylistPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaPlaylist : public QObject, public QMediaBindableInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaBindableInterface)
+ Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged)
+ Q_PROPERTY(QMediaContent currentMedia READ currentMedia NOTIFY currentMediaChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_ENUMS(PlaybackMode Error)
+
+public:
+ enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Sequential, Loop, Random };
+ enum Error { NoError, FormatError, FormatNotSupportedError, NetworkError, AccessDeniedError };
+
+ QMediaPlaylist(QObject *parent = 0);
+ virtual ~QMediaPlaylist();
+
+ QMediaObject *mediaObject() const;
+
+ PlaybackMode playbackMode() const;
+ void setPlaybackMode(PlaybackMode mode);
+
+ int currentIndex() const;
+ QMediaContent currentMedia() const;
+
+ int nextIndex(int steps = 1) const;
+ int previousIndex(int steps = 1) const;
+
+ QMediaContent media(int index) const;
+
+ int mediaCount() const;
+ bool isEmpty() const;
+ bool isReadOnly() const;
+
+ bool addMedia(const QMediaContent &content);
+ bool addMedia(const QList<QMediaContent> &items);
+ bool insertMedia(int index, const QMediaContent &content);
+ bool insertMedia(int index, const QList<QMediaContent> &items);
+ bool removeMedia(int pos);
+ bool removeMedia(int start, int end);
+ bool clear();
+
+ void load(const QUrl &location, const char *format = 0);
+ void load(QIODevice * device, const char *format = 0);
+
+ bool save(const QUrl &location, const char *format = 0);
+ bool save(QIODevice * device, const char *format);
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void shuffle();
+
+ void next();
+ void previous();
+
+ void setCurrentIndex(int index);
+
+Q_SIGNALS:
+ void currentIndexChanged(int index);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+ void currentMediaChanged(const QMediaContent&);
+
+ void mediaAboutToBeInserted(int start, int end);
+ void mediaInserted(int start, int end);
+ void mediaAboutToBeRemoved(int start, int end);
+ void mediaRemoved(int start, int end);
+ void mediaChanged(int start, int end);
+
+ void loaded();
+ void loadFailed();
+
+protected:
+ bool setMediaObject(QMediaObject *object);
+ QMediaPlaylistPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaPlaylist)
+ Q_PRIVATE_SLOT(d_func(), void _q_loadFailed(QMediaPlaylist::Error, const QString &))
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaPlaylist::PlaybackMode)
+Q_DECLARE_METATYPE(QMediaPlaylist::Error)
+
+Q_MEDIA_ENUM_DEBUG(QMediaPlaylist, PlaybackMode)
+Q_MEDIA_ENUM_DEBUG(QMediaPlaylist, Error)
+
+QT_END_HEADER
+
+#endif // QMEDIAPLAYLIST_H
diff --git a/src/multimedia/qmediaplaylist_p.h b/src/multimedia/qmediaplaylist_p.h
new file mode 100644
index 000000000..c04483c02
--- /dev/null
+++ b/src/multimedia/qmediaplaylist_p.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLIST_P_H
+#define QMEDIAPLAYLIST_P_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.
+//
+
+#include "qmediaplaylist.h"
+#include "qmediaplaylistcontrol.h"
+#include "qmediaplayer.h"
+#include "qmediaplayercontrol.h"
+#include "qlocalmediaplaylistprovider.h"
+#include "qmediaobject_p.h"
+
+#include <QtCore/qdebug.h>
+
+#ifdef Q_MOC_RUN
+# pragma Q_MOC_EXPAND_MACROS
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistControl;
+class QMediaPlaylistProvider;
+class QMediaPlaylistReader;
+class QMediaPlaylistWriter;
+class QMediaPlayerControl;
+
+class QMediaPlaylistPrivate
+{
+ Q_DECLARE_PUBLIC(QMediaPlaylist)
+public:
+ QMediaPlaylistPrivate()
+ :mediaObject(0),
+ control(0),
+ localPlaylistControl(0),
+ error(QMediaPlaylist::NoError)
+ {
+ }
+
+ virtual ~QMediaPlaylistPrivate() {}
+
+ void _q_loadFailed(QMediaPlaylist::Error error, const QString &errorString)
+ {
+ this->error = error;
+ this->errorString = errorString;
+
+ emit q_ptr->loadFailed();
+ }
+
+ void _q_mediaObjectDeleted()
+ {
+ Q_Q(QMediaPlaylist);
+ mediaObject = 0;
+ if (control != localPlaylistControl)
+ control = 0;
+ q->setMediaObject(0);
+ }
+
+ QMediaObject *mediaObject;
+
+ QMediaPlaylistControl *control;
+ QMediaPlaylistProvider *playlist() const { return control->playlistProvider(); }
+
+ QMediaPlaylistControl *localPlaylistControl;
+
+ bool readItems(QMediaPlaylistReader *reader);
+ bool writeItems(QMediaPlaylistWriter *writer);
+
+ QMediaPlaylist::Error error;
+ QString errorString;
+
+ QMediaPlaylist *q_ptr;
+};
+
+
+class QLocalMediaPlaylistControl : public QMediaPlaylistControl
+{
+ Q_OBJECT
+public:
+ QLocalMediaPlaylistControl(QObject *parent)
+ :QMediaPlaylistControl(parent)
+ {
+ QMediaPlaylistProvider *playlist = new QLocalMediaPlaylistProvider(this);
+ m_navigator = new QMediaPlaylistNavigator(playlist,this);
+ m_navigator->setPlaybackMode(QMediaPlaylist::Sequential);
+
+ connect(m_navigator, SIGNAL(currentIndexChanged(int)), SIGNAL(currentIndexChanged(int)));
+ connect(m_navigator, SIGNAL(activated(QMediaContent)), SIGNAL(currentMediaChanged(QMediaContent)));
+ connect(m_navigator, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)), SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)));
+ }
+
+ virtual ~QLocalMediaPlaylistControl() {};
+
+ QMediaPlaylistProvider* playlistProvider() const { return m_navigator->playlist(); }
+ bool setPlaylistProvider(QMediaPlaylistProvider *mediaPlaylist)
+ {
+ m_navigator->setPlaylist(mediaPlaylist);
+ emit playlistProviderChanged();
+ return true;
+ }
+
+ int currentIndex() const { return m_navigator->currentIndex(); }
+ void setCurrentIndex(int position) { m_navigator->jump(position); }
+ int nextIndex(int steps) const { return m_navigator->nextIndex(steps); }
+ int previousIndex(int steps) const { return m_navigator->previousIndex(steps); }
+
+ void next() { m_navigator->next(); }
+ void previous() { m_navigator->previous(); }
+
+ QMediaPlaylist::PlaybackMode playbackMode() const { return m_navigator->playbackMode(); }
+ void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) { m_navigator->setPlaybackMode(mode); }
+
+private:
+ QMediaPlaylistNavigator *m_navigator;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLIST_P_H
diff --git a/src/multimedia/qmediaplaylistcontrol.cpp b/src/multimedia/qmediaplaylistcontrol.cpp
new file mode 100644
index 000000000..dc2348956
--- /dev/null
+++ b/src/multimedia/qmediaplaylistcontrol.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmediaplaylistcontrol.h"
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMediaPlaylistControl class provides access to the playlist
+ functionality of a QMediaService.
+
+ If a QMediaService contains an internal playlist it will implement
+ QMediaPlaylistControl. This control provides access to the contents of the
+ \l {playlistProvider()}{playlist}, as well as the \l
+ {currentIndex()}{position} of the current media, and a means of navigating
+ to the \l {next()}{next} and \l {previous()}{previous} media.
+
+ The functionality provided by the control is exposed to application code
+ through the QMediaPlaylist class.
+
+ The interface name of QMediaPlaylistControl is \c com.nokia.Qt.QMediaPlaylistControl/1.0 as
+ defined in QMediaPlaylistControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaPlaylistControl_iid
+
+ \c com.nokia.Qt.QMediaPlaylistControl/1.0
+
+ Defines the interface name of the QMediaPlaylistControl class.
+
+ \relates QMediaPlaylistControl
+*/
+
+/*!
+ Create a new playlist control object with the given \a parent.
+*/
+QMediaPlaylistControl::QMediaPlaylistControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys the playlist control.
+*/
+QMediaPlaylistControl::~QMediaPlaylistControl()
+{
+}
+
+
+/*!
+ \fn QMediaPlaylistControl::playlistProvider() const
+
+ Returns the playlist used by this media player.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setPlaylistProvider(QMediaPlaylistProvider *playlist)
+
+ Set the playlist of this media player to \a playlist.
+
+ In many cases it is possible just to use the playlist
+ constructed by player, but sometimes replacing the whole
+ playlist allows to avoid copyting of all the items bettween playlists.
+
+ Returns true if player can use this passed playlist; otherwise returns false.
+
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentIndex() const
+
+ Returns position of the current media source in the playlist.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setCurrentIndex(int position)
+
+ Jump to the item at the given \a position.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::nextIndex(int step) const
+
+ Returns the index of item, which were current after calling next()
+ \a step times.
+
+ Returned value depends on the size of playlist, current position
+ and playback mode.
+
+ \since 1.0
+ \sa QMediaPlaylist::playbackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::previousIndex(int step) const
+
+ Returns the index of item, which were current after calling previous()
+ \a step times.
+
+ \since 1.0
+ \sa QMediaPlaylist::playbackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::next()
+
+ Moves to the next item in playlist.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::previous()
+
+ Returns to the previous item in playlist.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playbackMode() const
+
+ Returns the playlist navigation mode.
+
+ \since 1.0
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+
+ Sets the playback \a mode.
+
+ \since 1.0
+ \sa QMediaPlaylist::PlaybackMode
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playlistProviderChanged()
+
+ Signal emitted when the playlist provider has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentIndexChanged(int position)
+
+ Signal emitted when the playlist \a position is changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signal emitted when the playback \a mode is changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistControl::currentMediaChanged(const QMediaContent& content)
+
+ Signal emitted when current media changes to \a content.
+ \since 1.0
+*/
+
+#include "moc_qmediaplaylistcontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylistcontrol.h b/src/multimedia/qmediaplaylistcontrol.h
new file mode 100644
index 000000000..2cce448fa
--- /dev/null
+++ b/src/multimedia/qmediaplaylistcontrol.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIAPLAYLISTCONTROL_H
+#define QMEDIAPLAYLISTCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediaplaylistnavigator.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistProvider;
+
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaPlaylistControl();
+
+ virtual QMediaPlaylistProvider* playlistProvider() const = 0;
+ virtual bool setPlaylistProvider(QMediaPlaylistProvider *playlist) = 0;
+
+ virtual int currentIndex() const = 0;
+ virtual void setCurrentIndex(int position) = 0;
+ virtual int nextIndex(int steps) const = 0;
+ virtual int previousIndex(int steps) const = 0;
+
+ virtual void next() = 0;
+ virtual void previous() = 0;
+
+ virtual QMediaPlaylist::PlaybackMode playbackMode() const = 0;
+ virtual void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) = 0;
+
+Q_SIGNALS:
+ void playlistProviderChanged();
+ void currentIndexChanged(int position);
+ void currentMediaChanged(const QMediaContent&);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+
+protected:
+ QMediaPlaylistControl(QObject* parent = 0);
+};
+
+#define QMediaPlaylistControl_iid "com.nokia.Qt.QMediaPlaylistControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaPlaylistControl, QMediaPlaylistControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLISTCONTROL_H
diff --git a/src/multimedia/qmediaplaylistioplugin.cpp b/src/multimedia/qmediaplaylistioplugin.cpp
new file mode 100644
index 000000000..80fe0ef6b
--- /dev/null
+++ b/src/multimedia/qmediaplaylistioplugin.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaplaylistioplugin.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistReader
+
+ \brief The QMediaPlaylistReader class provides an interface for reading a playlist file.
+ \inmodule QtMultimedia
+ \since 1.0
+
+ \sa QMediaPlaylistIOPlugin
+*/
+
+/*!
+ Destroys a media playlist reader.
+*/
+QMediaPlaylistReader::~QMediaPlaylistReader()
+{
+}
+
+/*!
+ \fn QMediaPlaylistReader::atEnd() const
+
+ Identifies if a playlist reader has reached the end of its input.
+
+ Returns true if the reader has reached the end; and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistReader::readItem()
+
+ Reads an item of media from a playlist file.
+
+ Returns the read media, or a null QMediaContent if no more media is available.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistReader::close()
+
+ Closes a playlist reader's input device.
+ \since 1.0
+*/
+
+/*!
+ \class QMediaPlaylistWriter
+
+ \brief The QMediaPlaylistWriter class provides an interface for writing a playlist file.
+
+ \since 1.0
+ \sa QMediaPlaylistIOPlugin
+*/
+
+/*!
+ Destroys a media playlist writer.
+*/
+QMediaPlaylistWriter::~QMediaPlaylistWriter()
+{
+}
+
+/*!
+ \fn QMediaPlaylistWriter::writeItem(const QMediaContent &media)
+
+ Writes an item of \a media to a playlist file.
+
+ Returns true if the media was written successfully; and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistWriter::close()
+
+ Finalizes the writing of a playlist and closes the output device.
+ \since 1.0
+*/
+
+/*!
+ \class QMediaPlaylistIOPlugin
+ \brief The QMediaPlaylistIOPlugin class provides an interface for media playlist I/O plug-ins.
+ \since 1.0
+*/
+
+/*!
+ Constructs a media playlist I/O plug-in with the given \a parent.
+*/
+QMediaPlaylistIOPlugin::QMediaPlaylistIOPlugin(QObject *parent)
+ :QObject(parent)
+{
+}
+
+/*!
+ Destroys a media playlist I/O plug-in.
+*/
+QMediaPlaylistIOPlugin::~QMediaPlaylistIOPlugin()
+{
+}
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canRead(QIODevice *device, const QByteArray &format) const
+
+ Identifies if plug-in can read \a format data from an I/O \a device.
+
+ Returns true if the data can be read; and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canRead(const QUrl& location, const QByteArray &format) const
+
+ Identifies if a plug-in can read \a format data from a URL \a location.
+
+ Returns true if the data can be read; and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::canWrite(QIODevice *device, const QByteArray &format) const
+
+ Identifies if a plug-in can write \a format data to an I/O \a device.
+
+ Returns true if the data can be written; and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::keys() const
+
+ Returns a list of format keys supported by a plug-in.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createReader(QIODevice *device, const QByteArray &format)
+
+ Returns a new QMediaPlaylistReader which reads \a format data from an I/O \a device.
+
+ If the device is invalid or the format is unsupported this will return a null pointer.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createReader(const QUrl& location, const QByteArray &format)
+
+ Returns a new QMediaPlaylistReader which reads \a format data from a URL \a location.
+
+ If the location or the format is unsupported this will return a null pointer.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistIOPlugin::createWriter(QIODevice *device, const QByteArray &format)
+
+ Returns a new QMediaPlaylistWriter which writes \a format data to an I/O \a device.
+
+ If the device is invalid or the format is unsupported this will return a null pointer.
+ \since 1.0
+*/
+
+#include "moc_qmediaplaylistioplugin.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylistioplugin.h b/src/multimedia/qmediaplaylistioplugin.h
new file mode 100644
index 000000000..97ded8b43
--- /dev/null
+++ b/src/multimedia/qmediaplaylistioplugin.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTIOPLUGIN_H
+#define QMEDIAPLAYLISTIOPLUGIN_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+#include <qtmultimediadefs.h>
+
+#include "qmediacontent.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QString;
+class QUrl;
+class QByteArray;
+class QIODevice;
+class QStringList;
+
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistReader
+{
+public:
+ virtual ~QMediaPlaylistReader();
+
+ virtual bool atEnd() const = 0;
+ virtual QMediaContent readItem() = 0;
+ virtual void close() = 0;
+};
+
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistWriter
+{
+public:
+ virtual ~QMediaPlaylistWriter();
+
+ virtual bool writeItem(const QMediaContent &content) = 0;
+ virtual void close() = 0;
+};
+
+struct Q_MULTIMEDIA_EXPORT QMediaPlaylistIOInterface : public QFactoryInterface
+{
+ virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0;
+ virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0;
+
+ virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0;
+
+ virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0;
+ virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0;
+
+ virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0;
+};
+
+#define QMediaPlaylistIOInterface_iid "com.nokia.Qt.QMediaPlaylistIOInterface"
+Q_DECLARE_INTERFACE(QMediaPlaylistIOInterface, QMediaPlaylistIOInterface_iid);
+
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistIOPlugin : public QObject, public QMediaPlaylistIOInterface
+{
+Q_OBJECT
+Q_INTERFACES(QMediaPlaylistIOInterface:QFactoryInterface)
+public:
+ explicit QMediaPlaylistIOPlugin(QObject *parent = 0);
+ virtual ~QMediaPlaylistIOPlugin();
+
+ virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0;
+ virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0;
+
+ virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0;
+
+ virtual QStringList keys() const = 0;
+
+ virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0;
+ virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0;
+
+ virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLISTIOPLUGIN_H
diff --git a/src/multimedia/qmediaplaylistnavigator.cpp b/src/multimedia/qmediaplaylistnavigator.cpp
new file mode 100644
index 000000000..d78e6ef42
--- /dev/null
+++ b/src/multimedia/qmediaplaylistnavigator.cpp
@@ -0,0 +1,568 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaplaylistnavigator.h"
+#include "qmediaplaylistprovider.h"
+#include "qmediaplaylist.h"
+#include "qmediaobject_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylistNullProvider : public QMediaPlaylistProvider
+{
+public:
+ QMediaPlaylistNullProvider() :QMediaPlaylistProvider() {}
+ virtual ~QMediaPlaylistNullProvider() {}
+ virtual int mediaCount() const {return 0;}
+ virtual QMediaContent media(int) const { return QMediaContent(); }
+};
+
+Q_GLOBAL_STATIC(QMediaPlaylistNullProvider, _q_nullMediaPlaylist)
+
+class QMediaPlaylistNavigatorPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaPlaylistNavigator)
+public:
+ QMediaPlaylistNavigatorPrivate()
+ :playlist(0),
+ currentPos(-1),
+ lastValidPos(-1),
+ playbackMode(QMediaPlaylist::Sequential),
+ randomPositionsOffset(-1)
+ {
+ }
+
+ QMediaPlaylistProvider *playlist;
+ int currentPos;
+ int lastValidPos; //to be used with CurrentItemOnce playback mode
+ QMediaPlaylist::PlaybackMode playbackMode;
+ QMediaContent currentItem;
+
+ mutable QList<int> randomModePositions;
+ mutable int randomPositionsOffset;
+
+ int nextItemPos(int steps = 1) const;
+ int previousItemPos(int steps = 1) const;
+
+ void _q_mediaInserted(int start, int end);
+ void _q_mediaRemoved(int start, int end);
+ void _q_mediaChanged(int start, int end);
+
+ QMediaPlaylistNavigator *q_ptr;
+};
+
+
+int QMediaPlaylistNavigatorPrivate::nextItemPos(int steps) const
+{
+ if (playlist->mediaCount() == 0)
+ return -1;
+
+ if (steps == 0)
+ return currentPos;
+
+ switch (playbackMode) {
+ case QMediaPlaylist::CurrentItemOnce:
+ return /*currentPos == -1 ? lastValidPos :*/ -1;
+ case QMediaPlaylist::CurrentItemInLoop:
+ return currentPos;
+ case QMediaPlaylist::Sequential:
+ {
+ int nextPos = currentPos+steps;
+ return nextPos < playlist->mediaCount() ? nextPos : -1;
+ }
+ case QMediaPlaylist::Loop:
+ return (currentPos+steps) % playlist->mediaCount();
+ case QMediaPlaylist::Random:
+ {
+ //TODO: limit the history size
+
+ if (randomPositionsOffset == -1) {
+ randomModePositions.clear();
+ randomModePositions.append(currentPos);
+ randomPositionsOffset = 0;
+ }
+
+ while (randomModePositions.size() < randomPositionsOffset+steps+1)
+ randomModePositions.append(-1);
+ int res = randomModePositions[randomPositionsOffset+steps];
+ if (res<0 || res >= playlist->mediaCount()) {
+ res = qrand() % playlist->mediaCount();
+ randomModePositions[randomPositionsOffset+steps] = res;
+ }
+
+ return res;
+ }
+ }
+
+ return -1;
+}
+
+int QMediaPlaylistNavigatorPrivate::previousItemPos(int steps) const
+{
+ if (playlist->mediaCount() == 0)
+ return -1;
+
+ if (steps == 0)
+ return currentPos;
+
+ switch (playbackMode) {
+ case QMediaPlaylist::CurrentItemOnce:
+ return /*currentPos == -1 ? lastValidPos :*/ -1;
+ case QMediaPlaylist::CurrentItemInLoop:
+ return currentPos;
+ case QMediaPlaylist::Sequential:
+ {
+ int prevPos = currentPos == -1 ? playlist->mediaCount() - steps : currentPos - steps;
+ return prevPos>=0 ? prevPos : -1;
+ }
+ case QMediaPlaylist::Loop:
+ {
+ int prevPos = currentPos - steps;
+ while (prevPos<0)
+ prevPos += playlist->mediaCount();
+ return prevPos;
+ }
+ case QMediaPlaylist::Random:
+ {
+ //TODO: limit the history size
+
+ if (randomPositionsOffset == -1) {
+ randomModePositions.clear();
+ randomModePositions.append(currentPos);
+ randomPositionsOffset = 0;
+ }
+
+ while (randomPositionsOffset-steps < 0) {
+ randomModePositions.prepend(-1);
+ randomPositionsOffset++;
+ }
+
+ int res = randomModePositions[randomPositionsOffset-steps];
+ if (res<0 || res >= playlist->mediaCount()) {
+ res = qrand() % playlist->mediaCount();
+ randomModePositions[randomPositionsOffset-steps] = res;
+ }
+
+ return res;
+ }
+ }
+
+ return -1;
+}
+
+/*!
+ \class QMediaPlaylistNavigator
+
+ \brief The QMediaPlaylistNavigator class provides navigation for a media playlist.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ \sa QMediaPlaylist, QMediaPlaylistProvider
+*/
+
+
+/*!
+ Constructs a media playlist navigator for a \a playlist.
+
+ The \a parent is passed to QObject.
+ \since 1.0
+ */
+QMediaPlaylistNavigator::QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaPlaylistNavigatorPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ setPlaylist(playlist ? playlist : _q_nullMediaPlaylist());
+}
+
+/*!
+ Destroys a media playlist navigator.
+ */
+
+QMediaPlaylistNavigator::~QMediaPlaylistNavigator()
+{
+ delete d_ptr;
+}
+
+
+/*! \property QMediaPlaylistNavigator::playbackMode
+ Contains the playback mode.
+ \since 1.0
+ */
+QMediaPlaylist::PlaybackMode QMediaPlaylistNavigator::playbackMode() const
+{
+ return d_func()->playbackMode;
+}
+
+/*!
+ Sets the playback \a mode.
+ \since 1.0
+ */
+void QMediaPlaylistNavigator::setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
+{
+ Q_D(QMediaPlaylistNavigator);
+ if (d->playbackMode == mode)
+ return;
+
+ if (mode == QMediaPlaylist::Random) {
+ d->randomPositionsOffset = 0;
+ d->randomModePositions.append(d->currentPos);
+ } else if (d->playbackMode == QMediaPlaylist::Random) {
+ d->randomPositionsOffset = -1;
+ d->randomModePositions.clear();
+ }
+
+ d->playbackMode = mode;
+
+ emit playbackModeChanged(mode);
+ emit surroundingItemsChanged();
+}
+
+/*!
+ Returns the playlist being navigated.
+ \since 1.0
+*/
+
+QMediaPlaylistProvider *QMediaPlaylistNavigator::playlist() const
+{
+ return d_func()->playlist;
+}
+
+/*!
+ Sets the \a playlist to navigate.
+ \since 1.0
+*/
+void QMediaPlaylistNavigator::setPlaylist(QMediaPlaylistProvider *playlist)
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ if (d->playlist == playlist)
+ return;
+
+ if (d->playlist) {
+ d->playlist->disconnect(this);
+ }
+
+ if (playlist) {
+ d->playlist = playlist;
+ } else {
+ //assign to shared readonly null playlist
+ d->playlist = _q_nullMediaPlaylist();
+ }
+
+ connect(d->playlist, SIGNAL(mediaInserted(int,int)), SLOT(_q_mediaInserted(int,int)));
+ connect(d->playlist, SIGNAL(mediaRemoved(int,int)), SLOT(_q_mediaRemoved(int,int)));
+ connect(d->playlist, SIGNAL(mediaChanged(int,int)), SLOT(_q_mediaChanged(int,int)));
+
+ d->randomPositionsOffset = -1;
+ d->randomModePositions.clear();
+
+ if (d->currentPos != -1) {
+ d->currentPos = -1;
+ emit currentIndexChanged(-1);
+ }
+
+ if (!d->currentItem.isNull()) {
+ d->currentItem = QMediaContent();
+ emit activated(d->currentItem); //stop playback
+ }
+}
+
+/*! \property QMediaPlaylistNavigator::currentItem
+
+ Contains the media at the current position in the playlist.
+
+ \since 1.0
+ \sa currentIndex()
+*/
+
+QMediaContent QMediaPlaylistNavigator::currentItem() const
+{
+ return itemAt(d_func()->currentPos);
+}
+
+/*! \fn QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const
+
+ Returns the media that is \a steps positions ahead of the current
+ position in the playlist.
+
+ \since 1.0
+ \sa nextIndex()
+*/
+QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const
+{
+ return itemAt(nextIndex(steps));
+}
+
+/*!
+ Returns the media that is \a steps positions behind the current
+ position in the playlist.
+
+ \since 1.0
+ \sa previousIndex()
+ */
+QMediaContent QMediaPlaylistNavigator::previousItem(int steps) const
+{
+ return itemAt(previousIndex(steps));
+}
+
+/*!
+ Returns the media at a \a position in the playlist.
+ \since 1.0
+ */
+QMediaContent QMediaPlaylistNavigator::itemAt(int position) const
+{
+ return d_func()->playlist->media(position);
+}
+
+/*! \property QMediaPlaylistNavigator::currentIndex
+
+ Contains the position of the current media.
+
+ If no media is current, the property contains -1.
+
+ \since 1.0
+ \sa nextIndex(), previousIndex()
+*/
+
+int QMediaPlaylistNavigator::currentIndex() const
+{
+ return d_func()->currentPos;
+}
+
+/*!
+ Returns a position \a steps ahead of the current position
+ accounting for the playbackMode().
+
+ If the position is beyond the end of the playlist, this value
+ returned is -1.
+
+ \since 1.0
+ \sa currentIndex(), previousIndex(), playbackMode()
+*/
+
+int QMediaPlaylistNavigator::nextIndex(int steps) const
+{
+ return d_func()->nextItemPos(steps);
+}
+
+/*!
+
+ Returns a position \a steps behind the current position accounting
+ for the playbackMode().
+
+ If the position is prior to the beginning of the playlist this will
+ return -1.
+
+ \since 1.0
+ \sa currentIndex(), nextIndex(), playbackMode()
+*/
+int QMediaPlaylistNavigator::previousIndex(int steps) const
+{
+ return d_func()->previousItemPos(steps);
+}
+
+/*!
+ Advances to the next item in the playlist.
+
+ \since 1.0
+ \sa previous(), jump(), playbackMode()
+ */
+void QMediaPlaylistNavigator::next()
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ int nextPos = d->nextItemPos();
+
+ if ( playbackMode() == QMediaPlaylist::Random )
+ d->randomPositionsOffset++;
+
+ jump(nextPos);
+}
+
+/*!
+ Returns to the previous item in the playlist,
+
+ \since 1.0
+ \sa next(), jump(), playbackMode()
+ */
+void QMediaPlaylistNavigator::previous()
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ int prevPos = d->previousItemPos();
+ if ( playbackMode() == QMediaPlaylist::Random )
+ d->randomPositionsOffset--;
+
+ jump(prevPos);
+}
+
+/*!
+ Jumps to a new \a position in the playlist.
+ \since 1.0
+ */
+void QMediaPlaylistNavigator::jump(int position)
+{
+ Q_D(QMediaPlaylistNavigator);
+
+ if (position<-1 || position>=d->playlist->mediaCount()) {
+ qWarning() << "QMediaPlaylistNavigator: Jump outside playlist range";
+ position = -1;
+ }
+
+ if (position != -1)
+ d->lastValidPos = position;
+
+ if (playbackMode() == QMediaPlaylist::Random) {
+ if (d->randomModePositions[d->randomPositionsOffset] != position) {
+ d->randomModePositions.clear();
+ d->randomModePositions.append(position);
+ d->randomPositionsOffset = 0;
+ }
+ }
+
+ if (position != -1)
+ d->currentItem = d->playlist->media(position);
+ else
+ d->currentItem = QMediaContent();
+
+ if (position != d->currentPos) {
+ d->currentPos = position;
+ emit currentIndexChanged(d->currentPos);
+ emit surroundingItemsChanged();
+ }
+
+ emit activated(d->currentItem);
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaInserted(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos >= start) {
+ currentPos = end-start+1;
+ q->jump(currentPos);
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaRemoved(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos > end) {
+ currentPos = currentPos - end-start+1;
+ q->jump(currentPos);
+ } else if (currentPos >= start) {
+ //current item was removed
+ currentPos = qMin(start, playlist->mediaCount()-1);
+ q->jump(currentPos);
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+void QMediaPlaylistNavigatorPrivate::_q_mediaChanged(int start, int end)
+{
+ Q_Q(QMediaPlaylistNavigator);
+
+ if (currentPos >= start && currentPos<=end) {
+ QMediaContent src = playlist->media(currentPos);
+ if (src != currentItem) {
+ currentItem = src;
+ emit q->activated(src);
+ }
+ }
+
+ //TODO: check if they really changed
+ emit q->surroundingItemsChanged();
+}
+
+/*!
+ \fn QMediaPlaylistNavigator::activated(const QMediaContent &media)
+
+ Signals that the current \a media has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::currentIndexChanged(int position)
+
+ Signals the \a position of the current media has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
+
+ Signals that the playback \a mode has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistNavigator::surroundingItemsChanged()
+
+ Signals that media immediately surrounding the current position has changed.
+ \since 1.0
+*/
+
+#include "moc_qmediaplaylistnavigator.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylistnavigator.h b/src/multimedia/qmediaplaylistnavigator.h
new file mode 100644
index 000000000..72e452072
--- /dev/null
+++ b/src/multimedia/qmediaplaylistnavigator.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTNAVIGATOR_H
+#define QMEDIAPLAYLISTNAVIGATOR_H
+
+#include "qmediaplaylistprovider.h"
+#include "qmediaplaylist.h"
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistNavigatorPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistNavigator : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE jump NOTIFY currentIndexChanged)
+ Q_PROPERTY(QMediaContent currentItem READ currentItem)
+
+public:
+ QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent = 0);
+ virtual ~QMediaPlaylistNavigator();
+
+ QMediaPlaylistProvider *playlist() const;
+ void setPlaylist(QMediaPlaylistProvider *playlist);
+
+ QMediaPlaylist::PlaybackMode playbackMode() const;
+
+ QMediaContent currentItem() const;
+ QMediaContent nextItem(int steps = 1) const;
+ QMediaContent previousItem(int steps = 1) const;
+
+ QMediaContent itemAt(int position) const;
+
+ int currentIndex() const;
+ int nextIndex(int steps = 1) const;
+ int previousIndex(int steps = 1) const;
+
+public Q_SLOTS:
+ void next();
+ void previous();
+
+ void jump(int);
+
+ void setPlaybackMode(QMediaPlaylist::PlaybackMode mode);
+
+Q_SIGNALS:
+ void activated(const QMediaContent &content);
+ void currentIndexChanged(int);
+ void playbackModeChanged(QMediaPlaylist::PlaybackMode mode);
+
+ void surroundingItemsChanged();
+
+protected:
+ QMediaPlaylistNavigatorPrivate *d_ptr;
+
+private:
+ Q_DISABLE_COPY(QMediaPlaylistNavigator)
+ Q_DECLARE_PRIVATE(QMediaPlaylistNavigator)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaInserted(int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaRemoved(int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_mediaChanged(int start, int end))
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLISTNAVIGATOR_H
diff --git a/src/multimedia/qmediaplaylistprovider.cpp b/src/multimedia/qmediaplaylistprovider.cpp
new file mode 100644
index 000000000..75e927b39
--- /dev/null
+++ b/src/multimedia/qmediaplaylistprovider.cpp
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaplaylistprovider.h"
+#include "qmediaplaylistprovider_p.h"
+
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistProvider
+
+ \brief The QMediaPlaylistProvider class provides an abstract list of media.
+ \inmodule QtMultimedia
+ \since 1.0
+
+ \sa QMediaPlaylist
+*/
+
+/*!
+ Constructs a playlist provider with the given \a parent.
+*/
+QMediaPlaylistProvider::QMediaPlaylistProvider(QObject *parent)
+ :QObject(parent), d_ptr(new QMediaPlaylistProviderPrivate)
+{
+}
+
+/*!
+ \internal
+*/
+QMediaPlaylistProvider::QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent)
+ :QObject(parent), d_ptr(&dd)
+{
+}
+
+/*!
+ Destroys a playlist provider.
+*/
+QMediaPlaylistProvider::~QMediaPlaylistProvider()
+{
+ delete d_ptr;
+}
+
+/*!
+ \fn QMediaPlaylistProvider::mediaCount() const;
+
+ Returns the size of playlist.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistProvider::media(int index) const;
+
+ Returns the media at \a index in the playlist.
+
+ If the index is invalid this will return a null media content.
+ \since 1.0
+*/
+
+
+/*!
+ Loads a playlist from from a URL \a location. If no playlist \a format is specified the loader
+ will inspect the URL or probe the headers to guess the format.
+
+ New items are appended to playlist.
+
+ Returns true if the provider supports the format and loading from the locations URL protocol,
+ otherwise this will return false.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::load(const QUrl &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Loads a playlist from from an I/O \a device. If no playlist \a format is specified the loader
+ will probe the headers to guess the format.
+
+ New items are appended to playlist.
+
+ Returns true if the provider supports the format and loading from an I/O device, otherwise this
+ will return false.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::load(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Saves the contents of a playlist to a URL \a location. If no playlist \a format is specified
+ the writer will inspect the URL to guess the format.
+
+ Returns true if the playlist was saved successfully; and false otherwise.
+ \since 1.0
+ */
+bool QMediaPlaylistProvider::save(const QUrl &location, const char *format)
+{
+ Q_UNUSED(location);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Saves the contents of a playlist to an I/O \a device in the specified \a format.
+
+ Returns true if the playlist was saved successfully; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::save(QIODevice * device, const char *format)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ Returns true if a playlist is read-only; otherwise returns false.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::isReadOnly() const
+{
+ return true;
+}
+
+/*!
+ Append \a media to a playlist.
+
+ Returns true if the media was appended; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::addMedia(const QMediaContent &media)
+{
+ Q_UNUSED(media);
+ return false;
+}
+
+/*!
+ Append multiple media \a items to a playlist.
+
+ Returns true if the media items were appended; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items)
+{
+ foreach(const QMediaContent &item, items) {
+ if (!addMedia(item))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Inserts \a media into a playlist at \a position.
+
+ Returns true if the media was inserted; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::insertMedia(int position, const QMediaContent &media)
+{
+ Q_UNUSED(position);
+ Q_UNUSED(media);
+ return false;
+}
+
+/*!
+ Inserts multiple media \a items into a playlist at \a position.
+
+ Returns true if the media \a items were inserted; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::insertMedia(int position, const QList<QMediaContent> &items)
+{
+ for (int i=0; i<items.count(); i++) {
+ if (!insertMedia(position+i,items.at(i)))
+ return false;
+ }
+
+ return true;
+}
+
+
+/*!
+ Removes the media at \a position from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::removeMedia(int position)
+{
+ Q_UNUSED(position);
+ return false;
+}
+
+/*!
+ Removes the media between the given \a start and \a end positions from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+ \since 1.0
+ */
+bool QMediaPlaylistProvider::removeMedia(int start, int end)
+{
+ for (int pos=start; pos<=end; pos++) {
+ if (!removeMedia(pos))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Removes all media from a playlist.
+
+ Returns true if the media was removed; and false otherwise.
+ \since 1.0
+*/
+bool QMediaPlaylistProvider::clear()
+{
+ return removeMedia(0, mediaCount()-1);
+}
+
+/*!
+ Shuffles the contents of a playlist.
+ \since 1.0
+*/
+void QMediaPlaylistProvider::shuffle()
+{
+}
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaAboutToBeInserted(int start, int end);
+
+ Signals that new media is about to be inserted into a playlist between the \a start and \a end
+ positions.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaInserted(int start, int end);
+
+ Signals that new media has been inserted into a playlist between the \a start and \a end
+ positions.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaAboutToBeRemoved(int start, int end);
+
+ Signals that media is about to be removed from a playlist between the \a start and \a end
+ positions.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaRemoved(int start, int end);
+
+ Signals that media has been removed from a playlist between the \a start and \a end positions.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::mediaChanged(int start, int end);
+
+ Signals that media in playlist between the \a start and \a end positions inclusive has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::loaded()
+
+ Signals that a load() finished successfully.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaPlaylistProvider::loadFailed(QMediaPlaylist::Error error, const QString& errorMessage)
+
+ Signals that a load failed() due to an \a error. The \a errorMessage provides more information.
+ \since 1.0
+*/
+
+#include "moc_qmediaplaylistprovider.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylistprovider.h b/src/multimedia/qmediaplaylistprovider.h
new file mode 100644
index 000000000..79167e8ba
--- /dev/null
+++ b/src/multimedia/qmediaplaylistprovider.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTPROVIDER_H
+#define QMEDIAPLAYLISTPROVIDER_H
+
+#include <QObject>
+
+#include "qmediacontent.h"
+#include "qmediaplaylist.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QString;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylistProviderPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistProvider : public QObject
+{
+Q_OBJECT
+public:
+ QMediaPlaylistProvider(QObject *parent=0);
+ virtual ~QMediaPlaylistProvider();
+
+ virtual bool load(const QUrl &location, const char *format = 0);
+ virtual bool load(QIODevice * device, const char *format = 0);
+ virtual bool save(const QUrl &location, const char *format = 0);
+ virtual bool save(QIODevice * device, const char *format);
+
+ virtual int mediaCount() const = 0;
+ virtual QMediaContent media(int index) const = 0;
+
+ virtual bool isReadOnly() const;
+
+ virtual bool addMedia(const QMediaContent &content);
+ virtual bool addMedia(const QList<QMediaContent> &contentList);
+ virtual bool insertMedia(int index, const QMediaContent &content);
+ virtual bool insertMedia(int index, const QList<QMediaContent> &content);
+ virtual bool removeMedia(int pos);
+ virtual bool removeMedia(int start, int end);
+ virtual bool clear();
+
+public Q_SLOTS:
+ virtual void shuffle();
+
+Q_SIGNALS:
+ void mediaAboutToBeInserted(int start, int end);
+ void mediaInserted(int start, int end);
+
+ void mediaAboutToBeRemoved(int start, int end);
+ void mediaRemoved(int start, int end);
+
+ void mediaChanged(int start, int end);
+
+ void loaded();
+ void loadFailed(QMediaPlaylist::Error, const QString& errorMessage);
+
+protected:
+ QMediaPlaylistProviderPrivate *d_ptr;
+ QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent);
+
+private:
+ Q_DECLARE_PRIVATE(QMediaPlaylistProvider)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLISTPROVIDER_H
diff --git a/src/multimedia/qmediaplaylistprovider_p.h b/src/multimedia/qmediaplaylistprovider_p.h
new file mode 100644
index 000000000..71fb86f20
--- /dev/null
+++ b/src/multimedia/qmediaplaylistprovider_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLAYLISTPROVIDER_P_H
+#define QMEDIAPLAYLISTPROVIDER_P_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.
+//
+
+#include "qmediaplaylist.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylistProviderPrivate
+{
+public:
+ QMediaPlaylistProviderPrivate()
+ {}
+ virtual ~QMediaPlaylistProviderPrivate()
+ {}
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+
+#endif // QMEDIAPLAYLISTSOURCE_P_H
diff --git a/src/multimedia/qmediaplaylistsourcecontrol.cpp b/src/multimedia/qmediaplaylistsourcecontrol.cpp
new file mode 100644
index 000000000..ca90feda2
--- /dev/null
+++ b/src/multimedia/qmediaplaylistsourcecontrol.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qmediaplaylistsourcecontrol.h>
+#include <qmediacontrol_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaPlaylistSourceControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMediaPlaylistSourceControl class provides access to the playlist playback
+ functionality of a QMediaService.
+
+ This control allows QMediaPlaylist to be passed directly to the service
+ instead of playing media sources one by one. This control should be
+ implemented if backend benefits from knowing the next media source to be
+ played, for example for preloading, cross fading or gap-less playback.
+
+ If QMediaPlaylistSourceControl is provided, the backend must listen for
+ current playlist item changes to load corresponding media source and
+ advance the playlist with QMediaPlaylist::next() when playback of the
+ current media is finished.
+
+ The interface name of QMediaPlaylistSourceControl is \c com.nokia.Qt.QMediaPlaylistSourceControl/1.0 as
+ defined in QMediaPlaylistSourceControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaPlayer
+*/
+
+/*!
+ \macro QMediaPlaylistSourceControl_iid
+
+ \c com.nokia.Qt.QMediaPlaylistSourceControl/1.0
+
+ Defines the interface name of the QMediaPlaylistSourceControl class.
+
+ \relates QMediaPlaylistSourceControl
+*/
+
+/*!
+ Create a new playlist source control object with the given \a parent.
+*/
+QMediaPlaylistSourceControl::QMediaPlaylistSourceControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys the playlist control.
+*/
+QMediaPlaylistSourceControl::~QMediaPlaylistSourceControl()
+{
+}
+
+
+/*!
+ \fn QMediaPlaylistSourceControl::playlist() const
+
+ Returns the current playlist.
+ Should return a null pointer if no playlist is assigned.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaPlaylistSourceControl::setPlaylist(QMediaPlaylist *playlist)
+
+ Set the playlist of this media player to \a playlist.
+ If a null pointer is passed, the playlist source should be disabled.
+
+ The current media should be replaced with the current item of the media playlist.
+ \since 1.0
+*/
+
+
+/*!
+ \fn QMediaPlaylistSourceControl::playlistChanged(QMediaPlaylist* playlist)
+
+ Signal emitted when the playlist has changed to \a playlist.
+ \since 1.0
+*/
+
+#include "moc_qmediaplaylistsourcecontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaplaylistsourcecontrol.h b/src/multimedia/qmediaplaylistsourcecontrol.h
new file mode 100644
index 000000000..040bb6431
--- /dev/null
+++ b/src/multimedia/qmediaplaylistsourcecontrol.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIAPLAYLISTSOURCECONTROL_H
+#define QMEDIAPLAYLISTSOURCECONTROL_H
+
+#include <qmediacontrol.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaPlaylist;
+
+class Q_MULTIMEDIA_EXPORT QMediaPlaylistSourceControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaPlaylistSourceControl();
+
+ virtual QMediaPlaylist *playlist() const = 0;
+ virtual void setPlaylist(QMediaPlaylist *) = 0;
+
+Q_SIGNALS:
+ void playlistChanged(QMediaPlaylist* playlist);
+
+protected:
+ QMediaPlaylistSourceControl(QObject* parent = 0);
+};
+
+#define QMediaPlaylistSourceControl_iid "com.nokia.Qt.QMediaPlaylistSourceControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaPlaylistSourceControl, QMediaPlaylistSourceControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLAYLISTCONTROL_H
diff --git a/src/multimedia/qmediapluginloader.cpp b/src/multimedia/qmediapluginloader.cpp
new file mode 100644
index 000000000..32f336959
--- /dev/null
+++ b/src/multimedia/qmediapluginloader.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediapluginloader_p.h"
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qpluginloader.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+
+#include "qmediaserviceproviderplugin.h"
+
+#if defined(Q_OS_MAC)
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+typedef QMap<QString,QObjectList> ObjectListMap;
+Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
+
+
+QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
+ m_iid(iid)
+{
+ m_location = QString::fromLatin1("/%1").arg(location);
+ load();
+}
+
+QStringList QMediaPluginLoader::keys() const
+{
+ return m_instances.keys();
+}
+
+QObject* QMediaPluginLoader::instance(QString const &key)
+{
+ return m_instances.value(key).value(0);
+}
+
+QList<QObject*> QMediaPluginLoader::instances(QString const &key)
+{
+ return m_instances.value(key);
+}
+
+//to be used for testing purposes only
+void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
+{
+ staticMediaPlugins()->insert(QString::fromLatin1("/%1").arg(location), objects);
+}
+
+QStringList QMediaPluginLoader::availablePlugins() const
+{
+ QStringList paths;
+ QStringList plugins;
+
+#if defined(Q_OS_MAC)
+ QString imageSuffix(qgetenv("DYLD_IMAGE_SUFFIX"));
+
+ // Bundle plugin directory
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ if (mainBundle != 0) {
+ CFURLRef baseUrl = CFBundleCopyBundleURL(mainBundle);
+ CFURLRef pluginUrlPart = CFBundleCopyBuiltInPlugInsURL(mainBundle);
+ CFStringRef pluginPathPart = CFURLCopyFileSystemPath(pluginUrlPart, kCFURLPOSIXPathStyle);
+ CFURLRef pluginUrl = CFURLCreateCopyAppendingPathComponent(0, baseUrl, pluginPathPart, true);
+ CFStringRef pluginPath = CFURLCopyFileSystemPath(pluginUrl, kCFURLPOSIXPathStyle);
+
+ CFIndex length = CFStringGetLength(pluginPath);
+ UniChar buffer[length];
+ CFStringGetCharacters(pluginPath, CFRangeMake(0, length), buffer);
+
+ paths << QString(reinterpret_cast<const QChar *>(buffer), length);
+
+ CFRelease(pluginPath);
+ CFRelease(pluginUrl);
+ CFRelease(pluginPathPart);
+ CFRelease(pluginUrlPart);
+ CFRelease(baseUrl);
+ }
+#endif
+
+ // Qt paths
+ paths << QCoreApplication::libraryPaths();
+
+ foreach (const QString &path, paths) {
+ QDir typeDir(path + m_location);
+ foreach (const QString &file, typeDir.entryList(QDir::Files)) {
+#if defined(Q_OS_MAC)
+ if (!imageSuffix.isEmpty()) { // Only add appropriate images
+ if (file.lastIndexOf(imageSuffix, -6) == -1)
+ continue;
+ } else { // Ignore any images with common suffixes
+ if (file.endsWith(QLatin1String("_debug.dylib")) ||
+ file.endsWith(QLatin1String("_profile.dylib")))
+ continue;
+ }
+#elif defined(Q_OS_UNIX)
+ // Ignore separate debug files
+ if (file.endsWith(QLatin1String(".debug")))
+ continue;
+#elif defined(Q_OS_WIN)
+ // Ignore non-dlls
+ if (!file.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive))
+ continue;
+#endif
+ plugins << typeDir.absoluteFilePath(file);
+ }
+ }
+
+ return plugins;
+}
+
+void QMediaPluginLoader::load()
+{
+ if (!m_instances.isEmpty())
+ return;
+
+#if !defined QT_NO_DEBUG
+ const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
+#endif
+
+ if (staticMediaPlugins() && staticMediaPlugins()->contains(m_location)) {
+ foreach(QObject *o, staticMediaPlugins()->value(m_location)) {
+ if (o != 0 && o->qt_metacast(m_iid) != 0) {
+ QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
+ if (p != 0) {
+ foreach (QString const &key, p->keys())
+ m_instances[key].append(o);
+ }
+ }
+ }
+ } else {
+ QSet<QString> loadedPlugins;
+
+ foreach (const QString &plugin, availablePlugins()) {
+ QString fileName = QFileInfo(plugin).fileName();
+ //don't try to load plugin with the same name if it's already loaded
+ if (loadedPlugins.contains(fileName)) {
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qDebug() << "Skip loading plugin" << plugin;
+#endif
+ continue;
+ }
+
+ QPluginLoader loader(plugin);
+
+ QObject *o = loader.instance();
+ if (o != 0 && o->qt_metacast(m_iid) != 0) {
+ QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
+ if (p != 0) {
+ foreach (const QString &key, p->keys())
+ m_instances[key].append(o);
+
+ loadedPlugins.insert(fileName);
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qDebug() << "Loaded plugin" << plugin << "services:" << p->keys();
+#endif
+ }
+
+ continue;
+ } else {
+#if !defined QT_NO_DEBUG
+ if (showDebug)
+ qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugin << loader.errorString();
+#endif
+ }
+
+ delete o;
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediapluginloader_p.h b/src/multimedia/qmediapluginloader_p.h
new file mode 100644
index 000000000..1800a41e7
--- /dev/null
+++ b/src/multimedia/qmediapluginloader_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIAPLUGINLOADER_H
+#define QMEDIAPLUGINLOADER_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.
+//
+
+#include <qtmultimediadefs.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmap.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaServiceProviderPlugin;
+
+class Q_AUTOTEST_EXPORT QMediaPluginLoader
+{
+public:
+ QMediaPluginLoader(const char *iid,
+ const QString &suffix = QString(),
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+
+ QStringList keys() const;
+ QObject* instance(QString const &key);
+ QList<QObject*> instances(QString const &key);
+
+ static void setStaticPlugins(const QString &location, const QObjectList& objects);
+
+private:
+ void load();
+ QStringList availablePlugins() const;
+
+ QByteArray m_iid;
+ QString m_location;
+ QMap<QString, QList<QObject *> > m_instances;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIAPLUGINLOADER_H
diff --git a/src/multimedia/qmediarecorder.cpp b/src/multimedia/qmediarecorder.cpp
new file mode 100644
index 000000000..bcbae5708
--- /dev/null
+++ b/src/multimedia/qmediarecorder.cpp
@@ -0,0 +1,904 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediarecorder.h"
+
+#include <qmediarecordercontrol.h>
+#include <qmediaobject_p.h>
+#include <qmediaservice.h>
+#include <qmediaserviceprovider.h>
+#include <qmetadatawritercontrol.h>
+#include <qaudioencodercontrol.h>
+#include <qvideoencodercontrol.h>
+#include <qmediacontainercontrol.h>
+#include <qcamera.h>
+#include <qcameracontrol.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmetaobject.h>
+
+#include <qaudioformat.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaRecorder
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+
+ \brief The QMediaRecorder class is used for the recording of media content.
+
+ The QMediaRecorder class is a high level media recording class. It's not
+ intended to be used alone but for accessing the media recording functions
+ of other media objects, like QRadioTuner, or QAudioCaptureSource.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Media recorder
+
+ \sa QAudioCaptureSource
+*/
+
+namespace
+{
+class MediaRecorderRegisterMetaTypes
+{
+public:
+ MediaRecorderRegisterMetaTypes()
+ {
+ qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::State");
+ qRegisterMetaType<QMediaRecorder::Error>("QMediaRecorder::Error");
+ }
+} _registerRecorderMetaTypes;
+}
+
+
+class QMediaRecorderPrivate
+{
+ Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)
+
+public:
+ QMediaRecorderPrivate();
+
+ QMediaObject *mediaObject;
+
+ QMediaRecorderControl *control;
+ QMediaContainerControl *formatControl;
+ QAudioEncoderControl *audioControl;
+ QVideoEncoderControl *videoControl;
+ QMetaDataWriterControl *metaDataControl;
+
+ QTimer* notifyTimer;
+
+ QMediaRecorder::State state;
+ QMediaRecorder::Error error;
+ QString errorString;
+
+ void _q_stateChanged(QMediaRecorder::State state);
+ void _q_error(int error, const QString &errorString);
+ void _q_serviceDestroyed();
+ void _q_notify();
+ void _q_updateNotifyInterval(int ms);
+
+ QMediaRecorder *q_ptr;
+};
+
+QMediaRecorderPrivate::QMediaRecorderPrivate():
+ mediaObject(0),
+ control(0),
+ formatControl(0),
+ audioControl(0),
+ videoControl(0),
+ metaDataControl(0),
+ notifyTimer(0),
+ state(QMediaRecorder::StoppedState),
+ error(QMediaRecorder::NoError)
+{
+}
+
+#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
+
+void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
+{
+ Q_Q(QMediaRecorder);
+
+ if (ps == QMediaRecorder::RecordingState)
+ notifyTimer->start();
+ else
+ notifyTimer->stop();
+
+// qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
+ if (state != ps) {
+ emit q->stateChanged(ps);
+ }
+
+ state = ps;
+}
+
+
+void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
+{
+ Q_Q(QMediaRecorder);
+
+ this->error = QMediaRecorder::Error(error);
+ this->errorString = errorString;
+
+ emit q->error(this->error);
+}
+
+void QMediaRecorderPrivate::_q_serviceDestroyed()
+{
+ mediaObject = 0;
+ control = 0;
+ formatControl = 0;
+ audioControl = 0;
+ videoControl = 0;
+ metaDataControl = 0;
+}
+
+void QMediaRecorderPrivate::_q_notify()
+{
+ emit q_func()->durationChanged(q_func()->duration());
+}
+
+void QMediaRecorderPrivate::_q_updateNotifyInterval(int ms)
+{
+ notifyTimer->setInterval(ms);
+}
+
+
+/*!
+ Constructs a media recorder which records the media produced by \a mediaObject.
+
+ The \a parent is passed to QMediaObject.
+ \since 1.0
+*/
+
+QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
+ QObject(parent),
+ d_ptr(new QMediaRecorderPrivate)
+{
+ Q_D(QMediaRecorder);
+ d->q_ptr = this;
+ setMediaObject(mediaObject);
+
+ d->notifyTimer = new QTimer(this);
+ d->notifyTimer->setInterval(mediaObject->notifyInterval());
+ connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+ connect(mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int)));
+}
+
+/*!
+ Destroys a media recorder object.
+*/
+
+QMediaRecorder::~QMediaRecorder()
+{
+}
+
+/*!
+ Returns the QMediaObject instance that this QMediaRecorder is bound too,
+ or 0 otherwise.
+ \since 1.0
+*/
+QMediaObject *QMediaRecorder::mediaObject() const
+{
+ return d_func()->mediaObject;
+}
+
+/*!
+ \internal
+ \since 1.0
+*/
+bool QMediaRecorder::setMediaObject(QMediaObject *object)
+{
+ Q_D(QMediaRecorder);
+
+ if (object == d->mediaObject)
+ return true;
+
+ if (d->mediaObject) {
+ if (d->control) {
+ disconnect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
+ this, SLOT(_q_stateChanged(QMediaRecorder::State)));
+
+ disconnect(d->control, SIGNAL(mutedChanged(bool)),
+ this, SIGNAL(mutedChanged(bool)));
+
+ disconnect(d->control, SIGNAL(durationChanged(qint64)),
+ this, SIGNAL(durationChanged(qint64)));
+
+ disconnect(d->control, SIGNAL(error(int,QString)),
+ this, SLOT(_q_error(int,QString)));
+ }
+
+ QMediaService *service = d->mediaObject->service();
+
+ if (service) {
+ disconnect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
+
+ if (d->control)
+ service->releaseControl(d->control);
+ if (d->formatControl)
+ service->releaseControl(d->formatControl);
+ if (d->audioControl)
+ service->releaseControl(d->audioControl);
+ if (d->videoControl)
+ service->releaseControl(d->videoControl);
+ if (d->metaDataControl) {
+ disconnect(d->metaDataControl, SIGNAL(metaDataChanged()),
+ this, SIGNAL(metaDataChanged()));
+ disconnect(d->metaDataControl, SIGNAL(metaDataAvailableChanged(bool)),
+ this, SIGNAL(metaDataAvailableChanged(bool)));
+ disconnect(d->metaDataControl, SIGNAL(writableChanged(bool)),
+ this, SIGNAL(metaDataWritableChanged(bool)));
+
+ service->releaseControl(d->metaDataControl);
+ }
+ }
+ }
+
+ d->control = 0;
+ d->formatControl = 0;
+ d->audioControl = 0;
+ d->videoControl = 0;
+ d->metaDataControl = 0;
+
+ d->mediaObject = object;
+
+ if (d->mediaObject) {
+ QMediaService *service = d->mediaObject->service();
+
+ if (service) {
+ d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid));
+
+ if (d->control) {
+ d->formatControl = qobject_cast<QMediaContainerControl *>(service->requestControl(QMediaContainerControl_iid));
+ d->audioControl = qobject_cast<QAudioEncoderControl *>(service->requestControl(QAudioEncoderControl_iid));
+ d->videoControl = qobject_cast<QVideoEncoderControl *>(service->requestControl(QVideoEncoderControl_iid));
+
+ QMediaControl *control = service->requestControl(QMetaDataWriterControl_iid);
+ if (control) {
+ d->metaDataControl = qobject_cast<QMetaDataWriterControl *>(control);
+ if (!d->metaDataControl) {
+ service->releaseControl(control);
+ } else {
+ connect(d->metaDataControl,
+ SIGNAL(metaDataChanged()),
+ SIGNAL(metaDataChanged()));
+ connect(d->metaDataControl,
+ SIGNAL(metaDataAvailableChanged(bool)),
+ SIGNAL(metaDataAvailableChanged(bool)));
+ connect(d->metaDataControl,
+ SIGNAL(writableChanged(bool)),
+ SIGNAL(metaDataWritableChanged(bool)));
+ }
+ }
+
+ connect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
+ this, SLOT(_q_stateChanged(QMediaRecorder::State)));
+
+ connect(d->control, SIGNAL(mutedChanged(bool)),
+ this, SIGNAL(mutedChanged(bool)));
+
+ connect(d->control, SIGNAL(durationChanged(qint64)),
+ this, SIGNAL(durationChanged(qint64)));
+
+ connect(d->control, SIGNAL(error(int,QString)),
+ this, SLOT(_q_error(int,QString)));
+
+ connect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
+
+
+ return true;
+ }
+ }
+
+ d->mediaObject = 0;
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ \property QMediaRecorder::outputLocation
+ \brief the destination location of media content.
+
+ Setting the location can fail, for example when the service supports only
+ local file system locations but a network URL was passed. If the service
+ does not support media recording this setting the output location will
+ always fail.
+
+ The \a location can be relative or empty;
+ in this case the recorder uses the system specific place and file naming scheme.
+ After recording has stated, QMediaRecorder::outputLocation() returns the actual output location.
+ \since 1.0
+*/
+
+/*!
+ Returns true if media recorder service ready to use.
+ \since 1.0
+*/
+bool QMediaRecorder::isAvailable() const
+{
+ if (d_func()->control != NULL)
+ return true;
+ else
+ return false;
+}
+
+/*!
+ Returns the availability error code.
+ \since 1.0
+*/
+QtMultimedia::AvailabilityError QMediaRecorder::availabilityError() const
+{
+ if (d_func()->control != NULL)
+ return QtMultimedia::NoError;
+ else
+ return QtMultimedia::ServiceMissingError;
+}
+
+QUrl QMediaRecorder::outputLocation() const
+{
+ return d_func()->control ? d_func()->control->outputLocation() : QUrl();
+}
+
+bool QMediaRecorder::setOutputLocation(const QUrl &location)
+{
+ Q_D(QMediaRecorder);
+ return d->control ? d->control->setOutputLocation(location) : false;
+}
+
+/*!
+ Returns the current media recorder state.
+
+ \since 1.0
+ \sa QMediaRecorder::State
+*/
+
+QMediaRecorder::State QMediaRecorder::state() const
+{
+ return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
+}
+
+/*!
+ Returns the current error state.
+
+ \since 1.0
+ \sa errorString()
+*/
+
+QMediaRecorder::Error QMediaRecorder::error() const
+{
+ return d_func()->error;
+}
+
+/*!
+ Returns a string describing the current error state.
+
+ \since 1.0
+ \sa error()
+*/
+
+QString QMediaRecorder::errorString() const
+{
+ return d_func()->errorString;
+}
+
+/*!
+ \property QMediaRecorder::duration
+
+ \brief the recorded media duration in milliseconds.
+ \since 1.0
+*/
+
+qint64 QMediaRecorder::duration() const
+{
+ return d_func()->control ? d_func()->control->duration() : 0;
+}
+
+/*!
+ \property QMediaRecorder::muted
+
+ \brief whether a recording audio stream is muted.
+ \since 1.0
+*/
+
+bool QMediaRecorder::isMuted() const
+{
+ return d_func()->control ? d_func()->control->isMuted() : 0;
+}
+
+void QMediaRecorder::setMuted(bool muted)
+{
+ Q_D(QMediaRecorder);
+
+ if (d->control)
+ d->control->setMuted(muted);
+}
+
+/*!
+ Returns a list of MIME types of supported container formats.
+ \since 1.0
+*/
+QStringList QMediaRecorder::supportedContainers() const
+{
+ return d_func()->formatControl ?
+ d_func()->formatControl->supportedContainers() : QStringList();
+}
+
+/*!
+ Returns a description of a container format \a mimeType.
+ \since 1.0
+*/
+QString QMediaRecorder::containerDescription(const QString &mimeType) const
+{
+ return d_func()->formatControl ?
+ d_func()->formatControl->containerDescription(mimeType) : QString();
+}
+
+/*!
+ Returns the MIME type of the selected container format.
+ \since 1.0
+*/
+
+QString QMediaRecorder::containerMimeType() const
+{
+ return d_func()->formatControl ?
+ d_func()->formatControl->containerMimeType() : QString();
+}
+
+/*!
+ Returns a list of supported audio codecs.
+ \since 1.0
+*/
+QStringList QMediaRecorder::supportedAudioCodecs() const
+{
+ return d_func()->audioControl ?
+ d_func()->audioControl->supportedAudioCodecs() : QStringList();
+}
+
+/*!
+ Returns a description of an audio \a codec.
+ \since 1.0
+*/
+QString QMediaRecorder::audioCodecDescription(const QString &codec) const
+{
+ return d_func()->audioControl ?
+ d_func()->audioControl->codecDescription(codec) : QString();
+}
+
+/*!
+ Returns a list of supported audio sample rates.
+
+ If non null audio \a settings parameter is passed, the returned list is
+ reduced to sample rates supported with partial settings applied.
+
+ This can be used to query the list of sample rates, supported by specific
+ audio codec.
+
+ If the encoder supports arbitrary sample rates within the supported rates
+ range, *\a continuous is set to true, otherwise *\a continuous is set to
+ false.
+ \since 1.0
+*/
+
+QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ return d_func()->audioControl ?
+ d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>();
+}
+
+/*!
+ Returns a list of resolutions video can be encoded at.
+
+ If non null video \a settings parameter is passed, the returned list is
+ reduced to resolution supported with partial settings like video codec or
+ framerate applied.
+
+ If the encoder supports arbitrary resolutions within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+
+ \since 1.0
+ \sa QVideoEncoderSettings::resolution()
+*/
+QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ return d_func()->videoControl ?
+ d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>();
+}
+
+/*!
+ Returns a list of frame rates video can be encoded at.
+
+ If non null video \a settings parameter is passed, the returned list is
+ reduced to frame rates supported with partial settings like video codec or
+ resolution applied.
+
+ If the encoder supports arbitrary frame rates within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+
+ \since 1.0
+ \sa QVideoEncoderSettings::frameRate()
+*/
+QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ return d_func()->videoControl ?
+ d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>();
+}
+
+/*!
+ Returns a list of supported video codecs.
+ \since 1.0
+*/
+QStringList QMediaRecorder::supportedVideoCodecs() const
+{
+ return d_func()->videoControl ?
+ d_func()->videoControl->supportedVideoCodecs() : QStringList();
+}
+
+/*!
+ Returns a description of a video \a codec.
+
+ \since 1.0
+ \sa setEncodingSettings()
+*/
+QString QMediaRecorder::videoCodecDescription(const QString &codec) const
+{
+ return d_func()->videoControl ?
+ d_func()->videoControl->videoCodecDescription(codec) : QString();
+}
+
+/*!
+ Returns the audio encoder settings being used.
+
+ \since 1.0
+ \sa setEncodingSettings()
+*/
+
+QAudioEncoderSettings QMediaRecorder::audioSettings() const
+{
+ return d_func()->audioControl ?
+ d_func()->audioControl->audioSettings() : QAudioEncoderSettings();
+}
+
+/*!
+ Returns the video encoder settings being used.
+
+ \since 1.0
+ \sa setEncodingSettings()
+*/
+
+QVideoEncoderSettings QMediaRecorder::videoSettings() const
+{
+ return d_func()->videoControl ?
+ d_func()->videoControl->videoSettings() : QVideoEncoderSettings();
+}
+
+/*!
+ Sets the \a audio and \a video encoder settings and \a container format MIME type.
+
+ If some parameters are not specified, or null settings are passed, the
+ encoder will choose default encoding parameters, depending on media
+ source properties.
+ While setEncodingSettings is optional, the backend can preload
+ encoding pipeline to improve recording startup time.
+
+ It's only possible to change settings when the encoder is in the
+ QMediaEncoder::StoppedState state.
+
+ \since 1.0
+ \sa audioSettings(), videoSettings(), containerMimeType()
+*/
+
+void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
+ const QVideoEncoderSettings &video,
+ const QString &container)
+{
+ Q_D(QMediaRecorder);
+
+ QCamera *camera = qobject_cast<QCamera*>(d->mediaObject);
+ if (camera && camera->captureMode() == QCamera::CaptureVideo) {
+ QMetaObject::invokeMethod(camera,
+ "_q_preparePropertyChange",
+ Qt::DirectConnection,
+ Q_ARG(int, QCameraControl::VideoEncodingSettings));
+ }
+
+ if (d->audioControl)
+ d->audioControl->setAudioSettings(audio);
+
+ if (d->videoControl)
+ d->videoControl->setVideoSettings(video);
+
+ if (d->formatControl)
+ d->formatControl->setContainerMimeType(container);
+
+ if (d->control)
+ d->control->applySettings();
+}
+
+
+/*!
+ Start recording.
+
+ This is an asynchronous call, with signal
+ stateCahnged(QMediaRecorder::RecordingState) being emitted when recording
+ started, otherwise the error() signal is emitted.
+ \since 1.0
+*/
+
+void QMediaRecorder::record()
+{
+ Q_D(QMediaRecorder);
+
+ // reset error
+ d->error = NoError;
+ d->errorString = QString();
+
+ if (d->control)
+ d->control->record();
+}
+
+/*!
+ Pause recording.
+ \since 1.0
+*/
+
+void QMediaRecorder::pause()
+{
+ Q_D(QMediaRecorder);
+ if (d->control)
+ d->control->pause();
+}
+
+/*!
+ Stop recording.
+ \since 1.0
+*/
+
+void QMediaRecorder::stop()
+{
+ Q_D(QMediaRecorder);
+ if (d->control)
+ d->control->stop();
+}
+
+/*!
+ \enum QMediaRecorder::State
+
+ \value StoppedState The recorder is not active.
+ \value RecordingState The recorder is currently active and producing data.
+ \value PausedState The recorder is paused.
+*/
+
+/*!
+ \enum QMediaRecorder::Error
+
+ \value NoError No Errors.
+ \value ResourceError Device is not ready or not available.
+ \value FormatError Current format is not supported.
+*/
+
+/*!
+ \fn QMediaRecorder::stateChanged(State state)
+
+ Signals that a media recorder's \a state has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaRecorder::durationChanged(qint64 duration)
+
+ Signals that the \a duration of the recorded media has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaRecorder::error(QMediaRecorder::Error error)
+
+ Signals that an \a error has occurred.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaRecorder::mutedChanged(bool muted)
+
+ Signals that the \a muted state has changed. If true the recording is being muted.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaRecorder::metaDataAvailable
+ \brief whether access to a media object's meta-data is available.
+
+ If this is true there is meta-data available, otherwise there is no meta-data available.
+ \since 1.0
+*/
+
+bool QMediaRecorder::isMetaDataAvailable() const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->isMetaDataAvailable()
+ : false;
+}
+
+/*!
+ \fn QMediaRecorder::metaDataAvailableChanged(bool available)
+
+ Signals that the \a available state of a media object's meta-data has changed.
+ \since 1.0
+*/
+
+/*!
+ \property QMediaRecorder::metaDataWritable
+ \brief whether a media object's meta-data is writable.
+
+ If this is true the meta-data is writable, otherwise the meta-data is read-only.
+ \since 1.0
+*/
+
+bool QMediaRecorder::isMetaDataWritable() const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->isWritable()
+ : false;
+}
+
+/*!
+ \fn QMediaRecorder::metaDataWritableChanged(bool writable)
+
+ Signals that the \a writable state of a media object's meta-data has changed.
+ \since 1.0
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+ \since 1.0
+*/
+QVariant QMediaRecorder::metaData(QtMultimedia::MetaData key) const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->metaData(key)
+ : QVariant();
+}
+
+/*!
+ Sets a \a value for a meta-data \a key.
+
+ \note To ensure that meta data is set corretly, it should be set before starting the recording.
+ Once the recording is stopped, any meta data set will be attached to the next recording.
+ \since 1.0
+*/
+void QMediaRecorder::setMetaData(QtMultimedia::MetaData key, const QVariant &value)
+{
+ Q_D(QMediaRecorder);
+
+ if (d->metaDataControl)
+ d->metaDataControl->setMetaData(key, value);
+}
+
+/*!
+ Returns a list of keys there is meta-data available for.
+ \since 1.0
+*/
+QList<QtMultimedia::MetaData> QMediaRecorder::availableMetaData() const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableMetaData()
+ : QList<QtMultimedia::MetaData>();
+}
+
+/*!
+ \fn QMediaRecorder::metaDataChanged()
+
+ Signals that a media object's meta-data has changed.
+ \since 1.0
+*/
+
+/*!
+ Returns the value associated with a meta-data \a key.
+
+ The naming and type of extended meta-data is not standardized, so the values and meaning
+ of keys may vary between backends.
+ \since 1.0
+*/
+QVariant QMediaRecorder::extendedMetaData(const QString &key) const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->extendedMetaData(key)
+ : QVariant();
+}
+
+/*!
+ Sets a \a value for a meta-data \a key.
+
+ The naming and type of extended meta-data is not standardized, so the values and meaning
+ of keys may vary between backends.
+ \since 1.0
+*/
+void QMediaRecorder::setExtendedMetaData(const QString &key, const QVariant &value)
+{
+ Q_D(QMediaRecorder);
+
+ if (d->metaDataControl)
+ d->metaDataControl->setExtendedMetaData(key, value);
+}
+
+/*!
+ Returns a list of keys there is extended meta-data available for.
+ \since 1.0
+*/
+QStringList QMediaRecorder::availableExtendedMetaData() const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->metaDataControl
+ ? d->metaDataControl->availableExtendedMetaData()
+ : QStringList();
+}
+
+#include "moc_qmediarecorder.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediarecorder.h b/src/multimedia/qmediarecorder.h
new file mode 100644
index 000000000..fbd47ddde
--- /dev/null
+++ b/src/multimedia/qmediarecorder.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIARECORDER_H
+#define QMEDIARECORDER_H
+
+#include <qmediaobject.h>
+#include <qmediaserviceprovider.h>
+#include <qmediaencodersettings.h>
+#include <qmediabindableinterface.h>
+#include <qmediaenumdebug.h>
+
+#include <QtCore/qpair.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QUrl;
+class QSize;
+class QAudioFormat;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class QMediaRecorderService;
+class QAudioEncoderSettings;
+class QVideoEncoderSettings;
+
+class QMediaRecorderPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject, public QMediaBindableInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaBindableInterface)
+ Q_ENUMS(State)
+ Q_ENUMS(Error)
+ Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(bool metaDataAvailable READ isMetaDataAvailable NOTIFY metaDataAvailableChanged)
+ Q_PROPERTY(bool metaDataWritable READ isMetaDataWritable NOTIFY metaDataWritableChanged)
+public:
+
+ enum State
+ {
+ StoppedState,
+ RecordingState,
+ PausedState
+ };
+
+ enum Error
+ {
+ NoError,
+ ResourceError,
+ FormatError
+ };
+
+ QMediaRecorder(QMediaObject *mediaObject, QObject *parent = 0);
+ ~QMediaRecorder();
+
+ QMediaObject *mediaObject() const;
+
+ bool isAvailable() const;
+ QtMultimedia::AvailabilityError availabilityError() const;
+
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &location);
+
+ State state() const;
+
+ Error error() const;
+ QString errorString() const;
+
+ qint64 duration() const;
+
+ bool isMuted() const;
+
+ QStringList supportedContainers() const;
+ QString containerDescription(const QString &containerMimeType) const;
+
+ QStringList supportedAudioCodecs() const;
+ QString audioCodecDescription(const QString &codecName) const;
+
+ QList<int> supportedAudioSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(),
+ bool *continuous = 0) const;
+
+ QStringList supportedVideoCodecs() const;
+ QString videoCodecDescription(const QString &codecName) const;
+
+ QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
+ bool *continuous = 0) const;
+
+ QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
+ bool *continuous = 0) const;
+
+ QAudioEncoderSettings audioSettings() const;
+ QVideoEncoderSettings videoSettings() const;
+ QString containerMimeType() const;
+
+ void setEncodingSettings(const QAudioEncoderSettings &audioSettings,
+ const QVideoEncoderSettings &videoSettings = QVideoEncoderSettings(),
+ const QString &containerMimeType = QString());
+
+
+ bool isMetaDataAvailable() const;
+ bool isMetaDataWritable() const;
+
+ QVariant metaData(QtMultimedia::MetaData key) const;
+ void setMetaData(QtMultimedia::MetaData key, const QVariant &value);
+ QList<QtMultimedia::MetaData> availableMetaData() const;
+
+ QVariant extendedMetaData(const QString &key) const;
+ void setExtendedMetaData(const QString &key, const QVariant &value);
+ QStringList availableExtendedMetaData() const;
+
+public Q_SLOTS:
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool muted);
+
+Q_SIGNALS:
+ void stateChanged(QMediaRecorder::State state);
+ void durationChanged(qint64 duration);
+ void mutedChanged(bool muted);
+
+ void error(QMediaRecorder::Error error);
+
+ void metaDataAvailableChanged(bool available);
+ void metaDataWritableChanged(bool writable);
+ void metaDataChanged();
+
+protected:
+ bool setMediaObject(QMediaObject *object);
+
+private:
+ QMediaRecorderPrivate *d_ptr;
+ Q_DISABLE_COPY(QMediaRecorder)
+ Q_DECLARE_PRIVATE(QMediaRecorder)
+ Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_notify())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateNotifyInterval(int))
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaRecorder::State)
+Q_DECLARE_METATYPE(QMediaRecorder::Error)
+
+Q_MEDIA_ENUM_DEBUG(QMediaRecorder, State)
+Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Error)
+
+QT_END_HEADER
+
+#endif // QMEDIARECORDER_H
diff --git a/src/multimedia/qmediarecordercontrol.cpp b/src/multimedia/qmediarecordercontrol.cpp
new file mode 100644
index 000000000..ffc51021b
--- /dev/null
+++ b/src/multimedia/qmediarecordercontrol.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediarecordercontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMediaRecorderControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMediaRecorderControl class provides access to the recording
+ functionality of a QMediaService.
+
+ If a QMediaService can record media it will implement QMediaRecorderControl.
+ This control provides a means to set the \l {outputLocation()}{output location},
+ and \l {record()}{start}, \l {pause()}{pause} and \l {stop()}{stop}
+ recording. It also provides feedback on the \l {duration()}{duration}
+ of the recording.
+
+ The functionality provided by this control is exposed to application
+ code through the QMediaRecorder class.
+
+ The interface name of QMediaRecorderControl is \c com.nokia.Qt.QMediaRecorderControl/1.0 as
+ defined in QMediaRecorderControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaRecorder
+
+*/
+
+/*!
+ \macro QMediaRecorderControl_iid
+
+ \c com.nokia.Qt.QMediaRecorderControl/1.0
+
+ Defines the interface name of the QMediaRecorderControl class.
+
+ \relates QMediaRecorderControl
+*/
+
+/*!
+ Constructs a media recorder control with the given \a parent.
+*/
+
+QMediaRecorderControl::QMediaRecorderControl(QObject* parent)
+ : QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a media recorder control.
+*/
+
+QMediaRecorderControl::~QMediaRecorderControl()
+{
+}
+
+/*!
+ \fn QUrl QMediaRecorderControl::outputLocation() const
+
+ Returns the current output location being used.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QMediaRecorderControl::setOutputLocation(const QUrl &location)
+
+ Sets the output \a location and returns if this operation is successful.
+ If file at the output location already exists, it should be overwritten.
+
+ The \a location can be relative or empty;
+ in this case the service should use the system specific place and file naming scheme.
+ After recording has stated, QMediaRecorderControl::outputLocation() should return the actual output location.
+ \since 1.0
+*/
+
+/*!
+ \fn int QMediaRecorderControl::state() const
+
+ Return the current recording state.
+ \since 1.0
+*/
+
+/*!
+ \fn qint64 QMediaRecorderControl::duration() const
+
+ Return the current duration in milliseconds.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::record()
+
+ Start recording.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::pause()
+
+ Pause recording.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::stop()
+
+ Stop recording.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::applySettings()
+
+ Commits the encoder settings and performs pre-initialization to reduce delays when recording
+ is started.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QMediaRecorderControl::isMuted() const
+
+ Returns true if the recorder is muted, and false if it is not.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::setMuted(bool muted)
+
+ Sets the \a muted state of a media recorder.
+ \since 1.0
+*/
+
+
+/*!
+ \fn void QMediaRecorderControl::stateChanged(QMediaRecorder::State state)
+
+ Signals that the \a state of a media recorder has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::durationChanged(qint64 duration)
+
+ Signals that the \a duration of the recorded media has changed.
+
+ This only emitted when there is a discontinuous change in the duration such as being reset to 0.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::mutedChanged(bool muted)
+
+ Signals that the \a muted state of a media recorder has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaRecorderControl::error(int error, const QString &errorString)
+
+ Signals that an \a error has occurred. The \a errorString describes the error.
+ \since 1.0
+*/
+
+#include "moc_qmediarecordercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediarecordercontrol.h b/src/multimedia/qmediarecordercontrol.h
new file mode 100644
index 000000000..26f244c08
--- /dev/null
+++ b/src/multimedia/qmediarecordercontrol.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIARECORDERCONTROL_H
+#define QMEDIARECORDERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediarecorder.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QUrl;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QMediaRecorderControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QMediaRecorderControl();
+
+ virtual QUrl outputLocation() const = 0;
+ virtual bool setOutputLocation(const QUrl &location) = 0;
+
+ virtual QMediaRecorder::State state() const = 0;
+
+ virtual qint64 duration() const = 0;
+
+ virtual bool isMuted() const = 0;
+
+ virtual void applySettings() = 0;
+
+Q_SIGNALS:
+ void stateChanged(QMediaRecorder::State state);
+ void durationChanged(qint64 position);
+ void mutedChanged(bool muted);
+ void error(int error, const QString &errorString);
+
+public Q_SLOTS:
+ virtual void record() = 0;
+ virtual void pause() = 0;
+ virtual void stop() = 0;
+ virtual void setMuted(bool muted) = 0;
+
+protected:
+ QMediaRecorderControl(QObject* parent = 0);
+};
+
+#define QMediaRecorderControl_iid "com.nokia.Qt.QMediaRecorderControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaRecorderControl, QMediaRecorderControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qmediaresource.cpp b/src/multimedia/qmediaresource.cpp
new file mode 100644
index 000000000..a80168830
--- /dev/null
+++ b/src/multimedia/qmediaresource.cpp
@@ -0,0 +1,440 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaresource.h"
+
+#include <QtCore/qsize.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaResource
+
+ \brief The QMediaResource class provides a description of a media resource.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ A media resource is composed of a \l {url()}{URL} containing the
+ location of the resource and a set of properties that describe the
+ format of the resource. The properties provide a means to assess a
+ resource without first attempting to load it, and in situations where
+ media be represented by multiple alternative representations provide a
+ means to select the appropriate resource.
+
+ Media made available by a remote services can often be available in
+ multiple encodings or quality levels, this allows a client to select
+ an appropriate resource based on considerations such as codecs supported,
+ network bandwidth, and display constraints. QMediaResource includes
+ information such as the \l {mimeType()}{MIME type}, \l {audioCodec()}{audio}
+ and \l {videoCodec()}{video} codecs, \l {audioBitRate()}{audio} and
+ \l {videoBitRate()}{video} bit rates, and \l {resolution()}{resolution}
+ so these constraints and others can be evaluated.
+
+ The only mandatory property of a QMediaResource is the url().
+
+ \sa QMediaContent
+*/
+
+/*!
+ \typedef QMediaResourceList
+
+ Synonym for \c QList<QMediaResource>
+*/
+
+/*!
+ Constructs a null media resource.
+*/
+QMediaResource::QMediaResource()
+{
+}
+
+/*!
+ Constructs a media resource with the given \a mimeType from a \a url.
+ \since 1.0
+*/
+QMediaResource::QMediaResource(const QUrl &url, const QString &mimeType)
+{
+ values.insert(Url, url);
+ values.insert(MimeType, mimeType);
+}
+
+/*!
+ Constructs a media resource with the given \a mimeType from a network \a request.
+ \since 1.0
+*/
+QMediaResource::QMediaResource(const QNetworkRequest &request, const QString &mimeType)
+{
+ values.insert(Request, QVariant::fromValue(request));
+ values.insert(Url, request.url());
+ values.insert(MimeType, mimeType);
+}
+
+/*!
+ Constructs a copy of a media resource \a other.
+ \since 1.0
+*/
+QMediaResource::QMediaResource(const QMediaResource &other)
+ : values(other.values)
+{
+}
+
+/*!
+ Assigns the value of \a other to a media resource.
+ \since 1.0
+*/
+QMediaResource &QMediaResource::operator =(const QMediaResource &other)
+{
+ values = other.values;
+
+ return *this;
+}
+
+/*!
+ Destroys a media resource.
+*/
+QMediaResource::~QMediaResource()
+{
+}
+
+
+/*!
+ Compares a media resource to \a other.
+
+ Returns true if the resources are identical, and false otherwise.
+ \since 1.0
+*/
+bool QMediaResource::operator ==(const QMediaResource &other) const
+{
+ // Compare requests directly as QNetworkRequests are "custom types".
+ foreach (int key, values.keys()) {
+ switch (key) {
+ case Request:
+ if (request() != other.request())
+ return false;
+ break;
+ default:
+ if (values.value(key) != other.values.value(key))
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ Compares a media resource to \a other.
+
+ Returns true if they are different, and false otherwise.
+ \since 1.0
+*/
+bool QMediaResource::operator !=(const QMediaResource &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Identifies if a media resource is null.
+
+ Returns true if the resource is null, and false otherwise.
+ \since 1.0
+*/
+bool QMediaResource::isNull() const
+{
+ return values.isEmpty();
+}
+
+/*!
+ Returns the URL of a media resource.
+ \since 1.0
+*/
+QUrl QMediaResource::url() const
+{
+ return qvariant_cast<QUrl>(values.value(Url));
+}
+
+/*!
+ Returns the network request associated with this media resource.
+ \since 1.0
+*/
+QNetworkRequest QMediaResource::request() const
+{
+ if(values.contains(Request))
+ return qvariant_cast<QNetworkRequest>(values.value(Request));
+
+ return QNetworkRequest(url());
+}
+
+/*!
+ Returns the MIME type of a media resource.
+
+ This may be null if the MIME type is unknown.
+ \since 1.0
+*/
+QString QMediaResource::mimeType() const
+{
+ return qvariant_cast<QString>(values.value(MimeType));
+}
+
+/*!
+ Returns the language of a media resource as an ISO 639-2 code.
+
+ This may be null if the language is unknown.
+ \since 1.0
+*/
+QString QMediaResource::language() const
+{
+ return qvariant_cast<QString>(values.value(Language));
+}
+
+/*!
+ Sets the \a language of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setLanguage(const QString &language)
+{
+ if (!language.isNull())
+ values.insert(Language, language);
+ else
+ values.remove(Language);
+}
+
+/*!
+ Returns the audio codec of a media resource.
+
+ This may be null if the media resource does not contain an audio stream, or the codec is
+ unknown.
+ \since 1.0
+*/
+QString QMediaResource::audioCodec() const
+{
+ return qvariant_cast<QString>(values.value(AudioCodec));
+}
+
+/*!
+ Sets the audio \a codec of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setAudioCodec(const QString &codec)
+{
+ if (!codec.isNull())
+ values.insert(AudioCodec, codec);
+ else
+ values.remove(AudioCodec);
+}
+
+/*!
+ Returns the video codec of a media resource.
+
+ This may be null if the media resource does not contain a video stream, or the codec is
+ unknonwn.
+ \since 1.0
+*/
+QString QMediaResource::videoCodec() const
+{
+ return qvariant_cast<QString>(values.value(VideoCodec));
+}
+
+/*!
+ Sets the video \a codec of media resource.
+ \since 1.0
+*/
+void QMediaResource::setVideoCodec(const QString &codec)
+{
+ if (!codec.isNull())
+ values.insert(VideoCodec, codec);
+ else
+ values.remove(VideoCodec);
+}
+
+/*!
+ Returns the size in bytes of a media resource.
+
+ This may be zero if the size is unknown.
+ \since 1.0
+*/
+qint64 QMediaResource::dataSize() const
+{
+ return qvariant_cast<qint64>(values.value(DataSize));
+}
+
+/*!
+ Sets the \a size in bytes of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setDataSize(const qint64 size)
+{
+ if (size != 0)
+ values.insert(DataSize, size);
+ else
+ values.remove(DataSize);
+}
+
+/*!
+ Returns the bit rate in bits per second of a media resource's audio stream.
+
+ This may be zero if the bit rate is unknown, or the resource contains no audio stream.
+ \since 1.0
+*/
+int QMediaResource::audioBitRate() const
+{
+ return values.value(AudioBitRate).toInt();
+}
+
+/*!
+ Sets the bit \a rate in bits per second of a media resource's video stream.
+ \since 1.0
+*/
+void QMediaResource::setAudioBitRate(int rate)
+{
+ if (rate != 0)
+ values.insert(AudioBitRate, rate);
+ else
+ values.remove(AudioBitRate);
+}
+
+/*!
+ Returns the audio sample rate of a media resource.
+
+ This may be zero if the sample size is unknown, or the resource contains no audio stream.
+ \since 1.0
+*/
+int QMediaResource::sampleRate() const
+{
+ return qvariant_cast<int>(values.value(SampleRate));
+}
+
+/*!
+ Sets the audio \a sampleRate of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setSampleRate(int sampleRate)
+{
+ if (sampleRate != 0)
+ values.insert(SampleRate, sampleRate);
+ else
+ values.remove(SampleRate);
+}
+
+/*!
+ Returns the number of audio channels in a media resource.
+
+ This may be zero if the sample size is unknown, or the resource contains no audio stream.
+ \since 1.0
+*/
+int QMediaResource::channelCount() const
+{
+ return qvariant_cast<int>(values.value(ChannelCount));
+}
+
+/*!
+ Sets the number of audio \a channels in a media resource.
+ \since 1.0
+*/
+void QMediaResource::setChannelCount(int channels)
+{
+ if (channels != 0)
+ values.insert(ChannelCount, channels);
+ else
+ values.remove(ChannelCount);
+}
+
+/*!
+ Returns the bit rate in bits per second of a media resource's video stream.
+
+ This may be zero if the bit rate is unknown, or the resource contains no video stream.
+ \since 1.0
+*/
+int QMediaResource::videoBitRate() const
+{
+ return values.value(VideoBitRate).toInt();
+}
+
+/*!
+ Sets the bit \a rate in bits per second of a media resource's video stream.
+ \since 1.0
+*/
+void QMediaResource::setVideoBitRate(int rate)
+{
+ if (rate != 0)
+ values.insert(VideoBitRate, rate);
+ else
+ values.remove(VideoBitRate);
+}
+
+/*!
+ Returns the resolution in pixels of a media resource.
+
+ This may be null is the resolution is unknown, or the resource contains no pixel data (i.e. the
+ resource is an audio stream.
+ \since 1.0
+*/
+QSize QMediaResource::resolution() const
+{
+ return qvariant_cast<QSize>(values.value(Resolution));
+}
+
+/*!
+ Sets the \a resolution in pixels of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setResolution(const QSize &resolution)
+{
+ if (resolution.width() != -1 || resolution.height() != -1)
+ values.insert(Resolution, resolution);
+ else
+ values.remove(Resolution);
+}
+
+/*!
+ Sets the \a width and \a height in pixels of a media resource.
+ \since 1.0
+*/
+void QMediaResource::setResolution(int width, int height)
+{
+ if (width != -1 || height != -1)
+ values.insert(Resolution, QSize(width, height));
+ else
+ values.remove(Resolution);
+}
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaresource.h b/src/multimedia/qmediaresource.h
new file mode 100644
index 000000000..b06c61dcb
--- /dev/null
+++ b/src/multimedia/qmediaresource.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIARESOURCE_H
+#define QMEDIARESOURCE_H
+
+#include <QtCore/qmap.h>
+#include <QtCore/qmetatype.h>
+#include <QtNetwork/qnetworkrequest.h>
+
+#include <qtmultimediadefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaResource
+{
+public:
+ QMediaResource();
+ QMediaResource(const QUrl &url, const QString &mimeType = QString());
+ QMediaResource(const QNetworkRequest &request, const QString &mimeType = QString());
+ QMediaResource(const QMediaResource &other);
+ QMediaResource &operator =(const QMediaResource &other);
+ ~QMediaResource();
+
+ bool isNull() const;
+
+ bool operator ==(const QMediaResource &other) const;
+ bool operator !=(const QMediaResource &other) const;
+
+ QUrl url() const;
+ QNetworkRequest request() const;
+ QString mimeType() const;
+
+ QString language() const;
+ void setLanguage(const QString &language);
+
+ QString audioCodec() const;
+ void setAudioCodec(const QString &codec);
+
+ QString videoCodec() const;
+ void setVideoCodec(const QString &codec);
+
+ qint64 dataSize() const;
+ void setDataSize(const qint64 size);
+
+ int audioBitRate() const;
+ void setAudioBitRate(int rate);
+
+ int sampleRate() const;
+ void setSampleRate(int frequency);
+
+ int channelCount() const;
+ void setChannelCount(int channels);
+
+ int videoBitRate() const;
+ void setVideoBitRate(int rate);
+
+ QSize resolution() const;
+ void setResolution(const QSize &resolution);
+ void setResolution(int width, int height);
+
+
+private:
+ enum Property
+ {
+ Url,
+ Request,
+ MimeType,
+ Language,
+ AudioCodec,
+ VideoCodec,
+ DataSize,
+ AudioBitRate,
+ VideoBitRate,
+ SampleRate,
+ ChannelCount,
+ Resolution
+ };
+ QMap<int, QVariant> values;
+};
+
+typedef QList<QMediaResource> QMediaResourceList;
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaResource)
+Q_DECLARE_METATYPE(QMediaResourceList)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qmediaservice.cpp b/src/multimedia/qmediaservice.cpp
new file mode 100644
index 000000000..d97b3613c
--- /dev/null
+++ b/src/multimedia/qmediaservice.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediaservice.h"
+#include "qmediaservice_p.h"
+
+#include <QtCore/qtimer.h>
+
+
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMediaService
+ \brief The QMediaService class provides a common base class for media
+ service implementations.
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ Media services provide implementations of the functionality promised
+ by media objects, and allow multiple providers to implement a QMediaObject.
+
+ To provide the functionality of a QMediaObject media services implement
+ QMediaControl interfaces. Services typically implement one core media
+ control which provides the core feature of a media object, and some
+ number of additional controls which provide either optional features of
+ the media object, or features of a secondary media object or peripheral
+ object.
+
+ A pointer to media service's QMediaControl implementation can be obtained
+ by passing the control's interface name to the requestControl() function.
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Request control
+
+ Media objects can use services loaded dynamically from plug-ins or
+ implemented statically within an applications. Plug-in based services
+ should also implement the QMediaServiceProviderPlugin interface. Static
+ services should implement the QMediaServiceProvider interface.
+
+ \sa QMediaObject, QMediaControl, QMediaServiceProvider, QMediaServiceProviderPlugin
+*/
+
+/*!
+ Construct a media service with the given \a parent. This class is meant as a
+ base class for Multimedia services so this constructor is protected.
+*/
+
+QMediaService::QMediaService(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMediaServicePrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \internal
+*/
+QMediaService::QMediaService(QMediaServicePrivate &dd, QObject *parent)
+ : QObject(parent)
+ , d_ptr(&dd)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys a media service.
+*/
+
+QMediaService::~QMediaService()
+{
+ delete d_ptr;
+}
+
+/*!
+ \fn QMediaControl* QMediaService::requestControl(const char *interface)
+
+ Returns a pointer to the media control implementing \a interface.
+
+ If the service does not implement the control, or if it is unavailable a
+ null pointer is returned instead.
+
+ Controls must be returned to the service when no longer needed using the
+ releaseControl() function.
+ \since 1.0
+*/
+
+/*!
+ \fn T QMediaService::requestControl()
+
+ Returns a pointer to the media control of type T implemented by a media service.
+
+ If the service does not implement the control, or if it is unavailable a
+ null pointer is returned instead.
+
+ Controls must be returned to the service when no longer needed using the
+ releaseControl() function.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMediaService::releaseControl(QMediaControl *control);
+
+ Releases a \a control back to the service.
+ \since 1.0
+*/
+
+#include "moc_qmediaservice.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaservice.h b/src/multimedia/qmediaservice.h
new file mode 100644
index 000000000..64aa7099f
--- /dev/null
+++ b/src/multimedia/qmediaservice.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIASERVICE_H
+#define QABSTRACTMEDIASERVICE_H
+
+#include <qtmultimediadefs.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+
+#include "qmediacontrol.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaServicePrivate;
+class Q_MULTIMEDIA_EXPORT QMediaService : public QObject
+{
+ Q_OBJECT
+
+public:
+ ~QMediaService();
+
+ virtual QMediaControl* requestControl(const char *name) = 0;
+
+#ifndef QT_NO_MEMBER_TEMPLATES
+ template <typename T> inline T requestControl() {
+ if (QMediaControl *control = requestControl(qmediacontrol_iid<T>())) {
+ if (T typedControl = qobject_cast<T>(control))
+ return typedControl;
+ releaseControl(control);
+ }
+ return 0;
+ }
+#endif
+
+ virtual void releaseControl(QMediaControl *control) = 0;
+
+protected:
+ QMediaService(QObject* parent);
+ QMediaService(QMediaServicePrivate &dd, QObject *parent);
+
+ QMediaServicePrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QMediaService)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QABSTRACTMEDIASERVICE_H
+
diff --git a/src/multimedia/qmediaservice_p.h b/src/multimedia/qmediaservice_p.h
new file mode 100644
index 000000000..83fd7287f
--- /dev/null
+++ b/src/multimedia/qmediaservice_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTMEDIASERVICE_P_H
+#define QABSTRACTMEDIASERVICE_P_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_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAudioDeviceControl;
+
+class QMediaServicePrivate
+{
+public:
+ QMediaServicePrivate(): q_ptr(0) {}
+ virtual ~QMediaServicePrivate() {}
+
+ QMediaService *q_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+
+#endif
diff --git a/src/multimedia/qmediaserviceprovider.cpp b/src/multimedia/qmediaserviceprovider.cpp
new file mode 100644
index 000000000..0017349c4
--- /dev/null
+++ b/src/multimedia/qmediaserviceprovider.cpp
@@ -0,0 +1,783 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qmap.h>
+
+#include "qmediaservice.h"
+#include "qmediaserviceprovider.h"
+#include "qmediaserviceproviderplugin.h"
+#include "qmediapluginloader_p.h"
+#include "qmediaplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMediaServiceProviderHintPrivate : public QSharedData
+{
+public:
+ QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
+ :type(type), features(0)
+ {
+ }
+
+ QMediaServiceProviderHintPrivate(const QMediaServiceProviderHintPrivate &other)
+ :QSharedData(other),
+ type(other.type),
+ device(other.device),
+ mimeType(other.mimeType),
+ codecs(other.codecs),
+ features(other.features)
+ {
+ }
+
+ ~QMediaServiceProviderHintPrivate()
+ {
+ }
+
+ QMediaServiceProviderHint::Type type;
+ QByteArray device;
+ QString mimeType;
+ QStringList codecs;
+ QMediaServiceProviderHint::Features features;
+};
+
+/*!
+ \class QMediaServiceProviderHint
+
+ \brief The QMediaServiceProviderHint class describes what is required of a QMediaService.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ The QMediaServiceProvider class uses hints to select an appropriate media service.
+*/
+
+/*!
+ \enum QMediaServiceProviderHint::Feature
+
+ Enumerates features a media service may provide.
+
+ \value LowLatencyPlayback
+ The service is expected to play simple audio formats,
+ but playback should start without significant delay.
+ Such playback service can be used for beeps, ringtones, etc.
+
+ \value RecordingSupport
+ The service provides audio or video recording functions.
+
+ \value StreamPlayback
+ The service is capable of playing QIODevice based streams.
+
+ \value VideoSurface
+ The service is capable of renderering to a QAbstractVideoSurface
+ output.
+
+ \value BackgroundPlayback
+ The service is capable of doing playback in the background
+*/
+
+/*!
+ \enum QMediaServiceProviderHint::Type
+
+ Enumerates the possible types of media service provider hint.
+
+ \value Null En empty hint, use the default service.
+ \value ContentType Select media service most suitable for certain content type.
+ \value Device Select media service which supports certain device.
+ \value SupportedFeatures Select media service supporting the set of optional features.
+*/
+
+
+/*!
+ Constructs an empty media service provider hint.
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint()
+ :d(new QMediaServiceProviderHintPrivate(Null))
+{
+}
+
+/*!
+ Constructs a ContentType media service provider hint.
+
+ This type of hint describes a service that is able to play content of a specific MIME \a type
+ encoded with one or more of the listed \a codecs.
+ \since 1.0
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QString &type, const QStringList& codecs)
+ :d(new QMediaServiceProviderHintPrivate(ContentType))
+{
+ d->mimeType = type;
+ d->codecs = codecs;
+}
+
+/*!
+ Constructs a Device media service provider hint.
+
+ This type of hint describes a media service that utilizes a specific \a device.
+ \since 1.0
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QByteArray &device)
+ :d(new QMediaServiceProviderHintPrivate(Device))
+{
+ d->device = device;
+}
+
+/*!
+ Constructs a SupportedFeatures media service provider hint.
+
+ This type of hint describes a service which supports a specific set of \a features.
+ \since 1.0
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(QMediaServiceProviderHint::Features features)
+ :d(new QMediaServiceProviderHintPrivate(SupportedFeatures))
+{
+ d->features = features;
+}
+
+/*!
+ Constructs a copy of the media service provider hint \a other.
+ \since 1.0
+*/
+QMediaServiceProviderHint::QMediaServiceProviderHint(const QMediaServiceProviderHint &other)
+ :d(other.d)
+{
+}
+
+/*!
+ Destroys a media service provider hint.
+*/
+QMediaServiceProviderHint::~QMediaServiceProviderHint()
+{
+}
+
+/*!
+ Assigns the value \a other to a media service provider hint.
+ \since 1.0
+*/
+QMediaServiceProviderHint& QMediaServiceProviderHint::operator=(const QMediaServiceProviderHint &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Identifies if \a other is of equal value to a media service provider hint.
+
+ Returns true if the hints are equal, and false if they are not.
+ \since 1.0
+*/
+bool QMediaServiceProviderHint::operator == (const QMediaServiceProviderHint &other) const
+{
+ return (d == other.d) ||
+ (d->type == other.d->type &&
+ d->device == other.d->device &&
+ d->mimeType == other.d->mimeType &&
+ d->codecs == other.d->codecs &&
+ d->features == other.d->features);
+}
+
+/*!
+ Identifies if \a other is not of equal value to a media service provider hint.
+
+ Returns true if the hints are not equal, and false if they are.
+ \since 1.0
+*/
+bool QMediaServiceProviderHint::operator != (const QMediaServiceProviderHint &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ Returns true if a media service provider is null.
+ \since 1.0
+*/
+bool QMediaServiceProviderHint::isNull() const
+{
+ return d->type == Null;
+}
+
+/*!
+ Returns the type of a media service provider hint.
+ \since 1.0
+*/
+QMediaServiceProviderHint::Type QMediaServiceProviderHint::type() const
+{
+ return d->type;
+}
+
+/*!
+ Returns the mime type of the media a service is expected to be able play.
+ \since 1.0
+*/
+QString QMediaServiceProviderHint::mimeType() const
+{
+ return d->mimeType;
+}
+
+/*!
+ Returns a list of codes a media service is expected to be able to decode.
+ \since 1.0
+*/
+QStringList QMediaServiceProviderHint::codecs() const
+{
+ return d->codecs;
+}
+
+/*!
+ Returns the name of a device a media service is expected to utilize.
+ \since 1.0
+*/
+QByteArray QMediaServiceProviderHint::device() const
+{
+ return d->device;
+}
+
+/*!
+ Returns a set of features a media service is expected to provide.
+ \since 1.0
+*/
+QMediaServiceProviderHint::Features QMediaServiceProviderHint::features() const
+{
+ return d->features;
+}
+
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, loader,
+ (QMediaServiceProviderFactoryInterface_iid, QLatin1String("mediaservice"), Qt::CaseInsensitive))
+
+
+class QPluginServiceProvider : public QMediaServiceProvider
+{
+ QMap<QMediaService*, QMediaServiceProviderPlugin*> pluginMap;
+
+public:
+ QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint)
+ {
+ QString key(QLatin1String(type.constData()));
+
+ QList<QMediaServiceProviderPlugin *>plugins;
+ foreach (QObject *obj, loader()->instances(key)) {
+ QMediaServiceProviderPlugin *plugin =
+ qobject_cast<QMediaServiceProviderPlugin*>(obj);
+ if (plugin)
+ plugins << plugin;
+ }
+
+ if (!plugins.isEmpty()) {
+ QMediaServiceProviderPlugin *plugin = 0;
+
+ switch (hint.type()) {
+ case QMediaServiceProviderHint::Null:
+ plugin = plugins[0];
+ //special case for media player, if low latency was not asked,
+ //prefer services not offering it, since they are likely to support
+ //more formats
+ if (type == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)) {
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
+
+ if (!iface || !(iface->supportedFeatures(type) &
+ QMediaServiceProviderHint::LowLatencyPlayback)) {
+ plugin = currentPlugin;
+ break;
+ }
+
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::SupportedFeatures:
+ plugin = plugins[0];
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
+
+ if (iface) {
+ if ((iface->supportedFeatures(type) & hint.features()) == hint.features()) {
+ plugin = currentPlugin;
+ break;
+ }
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::Device: {
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin);
+
+ if (!iface) {
+ // the plugin may support the device,
+ // but this choice still can be overridden
+ plugin = currentPlugin;
+ } else {
+ if (iface->devices(type).contains(hint.device())) {
+ plugin = currentPlugin;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case QMediaServiceProviderHint::ContentType: {
+ QtMultimedia::SupportEstimate estimate = QtMultimedia::NotSupported;
+ foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
+ QtMultimedia::SupportEstimate currentEstimate = QtMultimedia::MaybeSupported;
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(currentPlugin);
+
+ if (iface)
+ currentEstimate = iface->hasSupport(hint.mimeType(), hint.codecs());
+
+ if (currentEstimate > estimate) {
+ estimate = currentEstimate;
+ plugin = currentPlugin;
+
+ if (currentEstimate == QtMultimedia::PreferredService)
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if (plugin != 0) {
+ QMediaService *service = plugin->create(key);
+ if (service != 0)
+ pluginMap.insert(service, plugin);
+
+ return service;
+ }
+ }
+
+ qWarning() << "defaultServiceProvider::requestService(): no service found for -" << key;
+ return 0;
+ }
+
+ void releaseService(QMediaService *service)
+ {
+ if (service != 0) {
+ QMediaServiceProviderPlugin *plugin = pluginMap.take(service);
+
+ if (plugin != 0)
+ plugin->release(service);
+ }
+ }
+
+ QtMultimedia::SupportEstimate hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags) const
+ {
+ QList<QObject*> instances = loader()->instances(QLatin1String(serviceType));
+
+ if (instances.isEmpty())
+ return QtMultimedia::NotSupported;
+
+ bool allServicesProvideInterface = true;
+ QtMultimedia::SupportEstimate supportEstimate = QtMultimedia::NotSupported;
+
+ foreach(QObject *obj, instances) {
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
+
+
+ if (flags) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(obj);
+
+ if (iface) {
+ QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
+
+ //if low latency playback was asked, skip services known
+ //not to provide low latency playback
+ if ((flags & QMediaPlayer::LowLatency) &&
+ !(features & QMediaServiceProviderHint::LowLatencyPlayback))
+ continue;
+
+ //the same for QIODevice based streams support
+ if ((flags & QMediaPlayer::StreamPlayback) &&
+ !(features & QMediaServiceProviderHint::StreamPlayback))
+ continue;
+ }
+ }
+
+ if (iface)
+ supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs));
+ else
+ allServicesProvideInterface = false;
+ }
+
+ //don't return PreferredService
+ supportEstimate = qMin(supportEstimate, QtMultimedia::ProbablySupported);
+
+ //Return NotSupported only if no services are available of serviceType
+ //or all the services returned NotSupported, otherwise return at least MaybeSupported
+ if (!allServicesProvideInterface)
+ supportEstimate = qMax(QtMultimedia::MaybeSupported, supportEstimate);
+
+ return supportEstimate;
+ }
+
+ QStringList supportedMimeTypes(const QByteArray &serviceType, int flags) const
+ {
+ QList<QObject*> instances = loader()->instances(QLatin1String(serviceType));
+
+ QStringList supportedTypes;
+
+ foreach(QObject *obj, instances) {
+ QMediaServiceSupportedFormatsInterface *iface =
+ qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
+
+
+ if (flags) {
+ QMediaServiceFeaturesInterface *iface =
+ qobject_cast<QMediaServiceFeaturesInterface*>(obj);
+
+ if (iface) {
+ QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
+
+ // If low latency playback was asked for, skip MIME types from services known
+ // not to provide low latency playback
+ if ((flags & QMediaPlayer::LowLatency) &&
+ !(features & QMediaServiceProviderHint::LowLatencyPlayback))
+ continue;
+
+ //the same for QIODevice based streams support
+ if ((flags & QMediaPlayer::StreamPlayback) &&
+ !(features & QMediaServiceProviderHint::StreamPlayback))
+ continue;
+
+ //the same for QAbstractVideoSurface support
+ if ((flags & QMediaPlayer::VideoSurface) &&
+ !(features & QMediaServiceProviderHint::VideoSurface))
+ continue;
+ }
+ }
+
+ if (iface) {
+ supportedTypes << iface->supportedMimeTypes();
+ }
+ }
+
+ // Multiple services may support the same MIME type
+ supportedTypes.removeDuplicates();
+
+ return supportedTypes;
+ }
+
+ QList<QByteArray> devices(const QByteArray &serviceType) const
+ {
+ QList<QByteArray> res;
+
+ foreach (QObject *obj, loader()->instances(QLatin1String(serviceType))) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
+
+ if (iface) {
+ res.append(iface->devices(serviceType));
+ }
+ }
+
+ return res;
+ }
+
+ QString deviceDescription(const QByteArray &serviceType, const QByteArray &device)
+ {
+ foreach (QObject *obj, loader()->instances(QLatin1String(serviceType))) {
+ QMediaServiceSupportedDevicesInterface *iface =
+ qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
+
+ if (iface) {
+ if (iface->devices(serviceType).contains(device))
+ return iface->deviceDescription(serviceType, device);
+ }
+ }
+
+ return QString();
+ }
+};
+
+Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider);
+
+/*!
+ \class QMediaServiceProvider
+
+ \brief The QMediaServiceProvider class provides an abstract allocator for media services.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceProvider::requestService(const QByteArray &type, const QMediaServiceProviderHint &hint)
+
+ Requests an instance of a \a type service which best matches the given \a
+ hint.
+
+ Returns a pointer to the requested service, or a null pointer if there is
+ no suitable service.
+
+ The returned service must be released with releaseService when it is
+ finished with.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceProvider::releaseService(QMediaService *service)
+
+ Releases a media \a service requested with requestService().
+ \since 1.0
+*/
+
+/*!
+ \fn QtMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType, const QString &mimeType, const QStringList& codecs, int flags) const
+
+ Returns how confident a media service provider is that is can provide a \a
+ serviceType service that is able to play media of a specific \a mimeType
+ that is encoded using the listed \a codecs while adhering to constraints
+ identified in \a flags.
+ \since 1.0
+*/
+QtMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags) const
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(mimeType);
+ Q_UNUSED(codecs);
+ Q_UNUSED(flags);
+
+ return QtMultimedia::MaybeSupported;
+}
+
+/*!
+ \fn QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
+
+ Returns a list of MIME types supported by the service provider for the
+ specified \a serviceType.
+
+ The resultant list is restricted to MIME types which can be supported given
+ the constraints in \a flags.
+ \since 1.0
+*/
+QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(flags);
+
+ return QStringList();
+}
+
+/*!
+ Returns the list of devices related to \a service type.
+ \since 1.0
+*/
+QList<QByteArray> QMediaServiceProvider::devices(const QByteArray &service) const
+{
+ Q_UNUSED(service);
+ return QList<QByteArray>();
+}
+
+/*!
+ Returns the description of \a device related to \a serviceType, suitable for use by
+ an application for display.
+ \since 1.0
+*/
+QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType, const QByteArray &device)
+{
+ Q_UNUSED(serviceType);
+ Q_UNUSED(device);
+ return QString();
+}
+
+
+#ifdef QT_BUILD_INTERNAL
+
+static QMediaServiceProvider *qt_defaultMediaServiceProvider = 0;
+
+/*!
+ Sets a media service \a provider as the default.
+
+ \internal
+ \since 1.0
+*/
+void QMediaServiceProvider::setDefaultServiceProvider(QMediaServiceProvider *provider)
+{
+ qt_defaultMediaServiceProvider = provider;
+}
+
+#endif
+
+/*!
+ Returns a default provider of media services.
+*/
+QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider()
+{
+#ifdef QT_BUILD_INTERNAL
+ return qt_defaultMediaServiceProvider != 0
+ ? qt_defaultMediaServiceProvider
+ : static_cast<QMediaServiceProvider *>(pluginProvider());
+#else
+ return pluginProvider();
+#endif
+}
+
+/*!
+ \class QMediaServiceProviderPlugin
+
+ \brief The QMediaServiceProviderPlugin class interface provides an interface for QMediaService
+ plug-ins.
+ \since 1.0
+
+ A media service provider plug-in may implement one or more of
+ QMediaServiceSupportedFormatsInterface,
+ QMediaServiceSupportedDevicesInterface, and QMediaServiceFeaturesInterface
+ to identify the features it supports.
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::keys() const
+
+ Returns a list of keys for media services a plug-in can create.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::create(const QString &key)
+
+ Constructs a new instance of the QMediaService identified by \a key.
+
+ The QMediaService returned must be destroyed with release().
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceProviderPlugin::release(QMediaService *service)
+
+ Destroys a media \a service constructed with create().
+ \since 1.0
+*/
+
+
+/*!
+ \class QMediaServiceSupportedFormatsInterface
+ \brief The QMediaServiceSupportedFormatsInterface class interface
+ identifies if a media service plug-in supports a media format.
+ \since 1.0
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::~QMediaServiceSupportedFormatsInterface()
+
+ Destroys a media service supported formats interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::hasSupport(const QString &mimeType, const QStringList& codecs) const
+
+ Returns the level of support a media service plug-in has for a \a mimeType
+ and set of \a codecs.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceSupportedFormatsInterface::supportedMimeTypes() const
+
+ Returns a list of MIME types supported by the media service plug-in.
+ \since 1.0
+*/
+
+/*!
+ \class QMediaServiceSupportedDevicesInterface
+ \brief The QMediaServiceSupportedDevicesInterface class interface
+ identifies the devices supported by a media service plug-in.
+ \since 1.0
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::~QMediaServiceSupportedDevicesInterface()
+
+ Destroys a media service supported devices interface.
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const
+
+ Returns a list of devices supported by a plug-in \a service.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device)
+
+ Returns a description of a \a device supported by a plug-in \a service.
+ \since 1.0
+*/
+
+/*!
+ \class QMediaServiceFeaturesInterface
+ \brief The QMediaServiceFeaturesInterface class interface identifies
+ features supported by a media service plug-in.
+ \since 1.0
+
+ A QMediaServiceProviderPlugin may implement this interface.
+*/
+
+/*!
+ \fn QMediaServiceFeaturesInterface::~QMediaServiceFeaturesInterface()
+
+ Destroys a media service features interface.
+*/
+/*!
+ \fn QMediaServiceFeaturesInterface::supportedFeatures(const QByteArray &service) const
+
+ Returns a set of features supported by a plug-in \a service.
+ \since 1.0
+*/
+
+#include "moc_qmediaserviceprovider.cpp"
+#include "moc_qmediaserviceproviderplugin.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediaserviceprovider.h b/src/multimedia/qmediaserviceprovider.h
new file mode 100644
index 000000000..8ad2e2f6c
--- /dev/null
+++ b/src/multimedia/qmediaserviceprovider.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIASERVICEPROVIDER_H
+#define QMEDIASERVICEPROVIDER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaService;
+
+class QMediaServiceProviderHintPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaServiceProviderHint
+{
+public:
+ enum Type { Null, ContentType, Device, SupportedFeatures };
+
+ enum Feature {
+ LowLatencyPlayback = 0x01,
+ RecordingSupport = 0x02,
+ StreamPlayback = 0x04,
+ VideoSurface = 0x08,
+ BackgroundPlayback = 0x10,
+ };
+ Q_DECLARE_FLAGS(Features, Feature)
+
+ QMediaServiceProviderHint();
+ QMediaServiceProviderHint(const QString &mimeType, const QStringList& codecs);
+ QMediaServiceProviderHint(const QByteArray &device);
+ QMediaServiceProviderHint(Features features);
+ QMediaServiceProviderHint(const QMediaServiceProviderHint &other);
+ ~QMediaServiceProviderHint();
+
+ QMediaServiceProviderHint& operator=(const QMediaServiceProviderHint &other);
+
+ bool operator == (const QMediaServiceProviderHint &other) const;
+ bool operator != (const QMediaServiceProviderHint &other) const;
+
+ bool isNull() const;
+
+ Type type() const;
+
+ QString mimeType() const;
+ QStringList codecs() const;
+
+ QByteArray device() const;
+
+ Features features() const;
+
+ //to be extended, if necessary
+
+private:
+ QSharedDataPointer<QMediaServiceProviderHintPrivate> d;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMediaServiceProviderHint::Features)
+
+class Q_MULTIMEDIA_EXPORT QMediaServiceProvider : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint = QMediaServiceProviderHint()) = 0;
+ virtual void releaseService(QMediaService *service) = 0;
+
+ virtual QtMultimedia::SupportEstimate hasSupport(const QByteArray &serviceType,
+ const QString &mimeType,
+ const QStringList& codecs,
+ int flags = 0) const;
+ virtual QStringList supportedMimeTypes(const QByteArray &serviceType, int flags = 0) const;
+
+ virtual QList<QByteArray> devices(const QByteArray &serviceType) const;
+ virtual QString deviceDescription(const QByteArray &serviceType, const QByteArray &device);
+
+ static QMediaServiceProvider* defaultServiceProvider();
+
+#ifdef QT_BUILD_INTERNAL
+ static void setDefaultServiceProvider(QMediaServiceProvider *provider);
+#endif
+};
+
+/*!
+ Service with support for media playback
+ Required Controls: QMediaPlayerControl
+ Optional Controls: QMediaPlaylistControl, QAudioDeviceControl
+ Video Output Controls (used by QWideoWidget and QGraphicsVideoItem):
+ Required: QVideoOutputControl
+ Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl
+*/
+#define Q_MEDIASERVICE_MEDIAPLAYER "com.nokia.qt.mediaplayer"
+
+/*!
+ Service with support for background media playback
+ Required Controls: QMediaPlayerControl, QMediaBackgroundPlaybackControl
+ Optional Controls: QMediaPlaylistControl, QAudioDeviceControl
+*/
+#define Q_MEDIASERVICE_BACKGROUNDMEDIAPLAYER "com.nokia.qt.backgroundmediaplayer"
+
+/*!
+ Service with support for recording from audio sources
+ Required Controls: QAudioDeviceControl
+ Recording Controls (QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl
+ Optional: QMediaContainerControl
+*/
+#define Q_MEDIASERVICE_AUDIOSOURCE "com.nokia.qt.audiosource"
+
+/*!
+ Service with support for camera use.
+ Required Controls: QCameraControl
+ Optional Controls: QCameraExposureControl, QCameraFocusControl, QCameraImageProcessingControl
+ Still Capture Controls: QCameraImageCaptureControl
+ Video Capture Controls (QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl, QVideoEncoderControl, QMediaContainerControl
+ Viewfinder Video Output Controls (used by QCameraViewfinder and QGraphicsVideoItem):
+ Required: QVideoOutputControl
+ Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl
+*/
+#define Q_MEDIASERVICE_CAMERA "com.nokia.qt.camera"
+
+/*!
+ Service with support for radio tuning.
+ Required Controls: QRadioTunerControl
+ Recording Controls (Optional, used by QMediaRecorder):
+ Required: QMediaRecorderControl
+ Recommended: QAudioEncoderControl
+ Optional: QMediaContainerControl
+*/
+#define Q_MEDIASERVICE_RADIO "com.nokia.qt.radio"
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIASERVICEPROVIDER_H
diff --git a/src/multimedia/qmediaserviceproviderplugin.h b/src/multimedia/qmediaserviceproviderplugin.h
new file mode 100644
index 000000000..669723e2b
--- /dev/null
+++ b/src/multimedia/qmediaserviceproviderplugin.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIASERVICEPROVIDERPLUGIN_H
+#define QMEDIASERVICEPROVIDERPLUGIN_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <qtmultimediadefs.h>
+#include "qmediaserviceprovider.h"
+
+#ifdef Q_MOC_RUN
+# pragma Q_MOC_EXPAND_MACROS
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaService;
+
+struct Q_MULTIMEDIA_EXPORT QMediaServiceProviderFactoryInterface : public QFactoryInterface
+{
+ virtual QStringList keys() const = 0;
+ virtual QMediaService* create(QString const& key) = 0;
+ virtual void release(QMediaService *service) = 0;
+};
+
+#define QMediaServiceProviderFactoryInterface_iid \
+ "com.nokia.Qt.QMediaServiceProviderFactoryInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceProviderFactoryInterface, QMediaServiceProviderFactoryInterface_iid)
+
+
+struct Q_MULTIMEDIA_EXPORT QMediaServiceSupportedFormatsInterface
+{
+ virtual ~QMediaServiceSupportedFormatsInterface() {}
+ virtual QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const = 0;
+ virtual QStringList supportedMimeTypes() const = 0;
+};
+
+#define QMediaServiceSupportedFormatsInterface_iid \
+ "com.nokia.Qt.QMediaServiceSupportedFormatsInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceSupportedFormatsInterface, QMediaServiceSupportedFormatsInterface_iid)
+
+
+struct Q_MULTIMEDIA_EXPORT QMediaServiceSupportedDevicesInterface
+{
+ virtual ~QMediaServiceSupportedDevicesInterface() {}
+ virtual QList<QByteArray> devices(const QByteArray &service) const = 0;
+ virtual QString deviceDescription(const QByteArray &service, const QByteArray &device) = 0;
+};
+
+#define QMediaServiceSupportedDevicesInterface_iid \
+ "com.nokia.Qt.QMediaServiceSupportedDevicesInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceSupportedDevicesInterface, QMediaServiceSupportedDevicesInterface_iid)
+
+
+
+struct Q_MULTIMEDIA_EXPORT QMediaServiceFeaturesInterface
+{
+ virtual ~QMediaServiceFeaturesInterface() {}
+ virtual QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const = 0;
+};
+
+#define QMediaServiceFeaturesInterface_iid \
+ "com.nokia.Qt.QMediaServiceFeaturesInterface/1.0"
+Q_DECLARE_INTERFACE(QMediaServiceFeaturesInterface, QMediaServiceFeaturesInterface_iid)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaServiceProviderPlugin : public QObject, public QMediaServiceProviderFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceProviderFactoryInterface:QFactoryInterface)
+
+public:
+ virtual QStringList keys() const = 0;
+ virtual QMediaService* create(const QString& key) = 0;
+ virtual void release(QMediaService *service) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+
+#endif // QMEDIASERVICEPROVIDERPLUGIN_H
diff --git a/src/multimedia/qmediastreamscontrol.cpp b/src/multimedia/qmediastreamscontrol.cpp
new file mode 100644
index 000000000..65614b612
--- /dev/null
+++ b/src/multimedia/qmediastreamscontrol.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediastreamscontrol.h"
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaStreamsControl
+ \preliminary
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \brief The QMediaStreamsControl class provides a media stream selection control.
+
+ \since 1.0
+
+ The QMediaStreamsControl class provides descriptions of the available media streams
+ and allows individual streams to be activated and deactivated.
+
+ The interface name of QMediaStreamsControl is \c com.nokia.Qt.MediaStreamsControl as
+ defined in QMediaStreamsControl_iid.
+
+ \sa QMediaService::requestControl()
+*/
+
+/*!
+ \macro QMediaStreamsControl_iid
+
+ \c com.nokia.Qt.MediaStreamsControl
+
+ Defines the interface name of the QMediaStreamsControl class.
+
+ \relates QMediaStreamsControl
+ \since 1.0
+*/
+
+/*!
+ Constructs a new media streams control with the given \a parent.
+*/
+QMediaStreamsControl::QMediaStreamsControl(QObject *parent)
+ :QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys a media streams control.
+*/
+QMediaStreamsControl::~QMediaStreamsControl()
+{
+}
+
+/*!
+ \enum QMediaStreamsControl::StreamType
+
+ Media stream type.
+
+ \value AudioStream Audio stream.
+ \value VideoStream Video stream.
+ \value SubPictureStream Subpicture or teletext stream.
+ \value UnknownStream The stream type is unknown.
+ \value DataStream
+*/
+
+/*!
+ \fn QMediaStreamsControl::streamCount()
+
+ Returns the number of media streams.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::streamType(int stream)
+
+ Return the type of a media \a stream.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::metaData(int stream, QtMultimedia::MetaData key)
+
+ Returns the meta-data value of \a key for a given \a stream.
+
+ Useful metadata keya are QtMultimedia::Title, QtMultimedia::Description and QtMultimedia::Language.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::isActive(int stream)
+
+ Returns true if the media \a stream is active.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::setActive(int stream, bool state)
+
+ Sets the active \a state of a media \a stream.
+
+ Setting the active state of a media stream to true will activate it. If any other stream
+ of the same type was previously active it will be deactivated. Setting the active state fo a
+ media stream to false will deactivate it.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::streamsChanged()
+
+ The signal is emitted when the available streams list is changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QMediaStreamsControl::activeStreamsChanged()
+
+ The signal is emitted when the active streams list is changed.
+ \since 1.0
+*/
+
+#include "moc_qmediastreamscontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediastreamscontrol.h b/src/multimedia/qmediastreamscontrol.h
new file mode 100644
index 000000000..bbd8a2a43
--- /dev/null
+++ b/src/multimedia/qmediastreamscontrol.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMEDIASTREAMSCONTROL_H
+#define QMEDIASTREAMSCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qtmedianamespace.h"
+#include "qtmultimediadefs.h"
+#include <qmediaenumdebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QMediaStreamsControl : public QMediaControl
+{
+ Q_OBJECT
+ Q_ENUMS(SteamType)
+public:
+ enum StreamType { UnknownStream, VideoStream, AudioStream, SubPictureStream, DataStream };
+
+ virtual ~QMediaStreamsControl();
+
+ virtual int streamCount() = 0;
+ virtual StreamType streamType(int streamNumber) = 0;
+
+ virtual QVariant metaData(int streamNumber, QtMultimedia::MetaData key) = 0;
+
+ virtual bool isActive(int streamNumber) = 0;
+ virtual void setActive(int streamNumber, bool state) = 0;
+
+Q_SIGNALS:
+ void streamsChanged();
+ void activeStreamsChanged();
+
+protected:
+ QMediaStreamsControl(QObject *parent = 0);
+};
+
+#define QMediaStreamsControl_iid "com.nokia.Qt.QMediaStreamsControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMediaStreamsControl, QMediaStreamsControl_iid)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QMediaStreamsControl::StreamType)
+
+Q_MEDIA_ENUM_DEBUG(QMediaStreamsControl, StreamType)
+
+QT_END_HEADER
+
+#endif // QMEDIASTREAMSCONTROL_H
+
diff --git a/src/multimedia/qmediatimerange.cpp b/src/multimedia/qmediatimerange.cpp
new file mode 100644
index 000000000..34252de37
--- /dev/null
+++ b/src/multimedia/qmediatimerange.cpp
@@ -0,0 +1,759 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+
+#include "qmediatimerange.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMediaTimeInterval
+ \brief The QMediaTimeInterval class represents a time interval with integer precision.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ An interval is specified by an inclusive start() and end() time. These
+ must be set in the constructor, as this is an immutable class. The
+ specific units of time represented by the class have not been defined - it
+ is suitable for any times which can be represented by a signed 64 bit
+ integer.
+
+ The isNormal() method determines if a time interval is normal (a normal
+ time interval has start() <= end()). An abnormal interval can be converted
+ in to a normal interval by calling the normalized() method.
+
+ The contains() method determines if a specified time lies within the time
+ interval.
+
+ The translated() method returns a time interval which has been translated
+ forwards or backwards through time by a specified offset.
+
+ \sa QMediaTimeRange
+*/
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval()
+
+ Constructs an empty interval.
+*/
+QMediaTimeInterval::QMediaTimeInterval()
+ : s(0)
+ , e(0)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end)
+
+ Constructs an interval with the specified \a start and \a end times.
+ \since 1.0
+*/
+QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end)
+ : s(start)
+ , e(end)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other)
+
+ Constructs an interval by taking a copy of \a other.
+ \since 1.0
+*/
+QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other)
+ : s(other.s)
+ , e(other.e)
+{
+
+}
+
+/*!
+ \fn QMediaTimeInterval::start() const
+
+ Returns the start time of the interval.
+
+ \since 1.0
+ \sa end()
+*/
+qint64 QMediaTimeInterval::start() const
+{
+ return s;
+}
+
+/*!
+ \fn QMediaTimeInterval::end() const
+
+ Returns the end time of the interval.
+
+ \since 1.0
+ \sa start()
+*/
+qint64 QMediaTimeInterval::end() const
+{
+ return e;
+}
+
+/*!
+ \fn QMediaTimeInterval::contains(qint64 time) const
+
+ Returns true if the time interval contains the specified \a time.
+ That is, start() <= time <= end().
+ \since 1.0
+*/
+bool QMediaTimeInterval::contains(qint64 time) const
+{
+ return isNormal() ? (s <= time && time <= e)
+ : (e <= time && time <= s);
+}
+
+/*!
+ \fn QMediaTimeInterval::isNormal() const
+
+ Returns true if this time interval is normal.
+ A normal time interval has start() <= end().
+
+ \since 1.0
+ \sa normalized()
+*/
+bool QMediaTimeInterval::isNormal() const
+{
+ return s <= e;
+}
+
+/*!
+ \fn QMediaTimeInterval::normalized() const
+
+ Returns a normalized version of this interval.
+
+ If the start() time of the interval is greater than the end() time,
+ then the returned interval has the start and end times swapped.
+ \since 1.0
+*/
+QMediaTimeInterval QMediaTimeInterval::normalized() const
+{
+ if(s > e)
+ return QMediaTimeInterval(e, s);
+
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeInterval::translated(qint64 offset) const
+
+ Returns a copy of this time interval, translated by a value of \a offset.
+ An interval can be moved forward through time with a positive offset, or backward
+ through time with a negative offset.
+ \since 1.0
+*/
+QMediaTimeInterval QMediaTimeInterval::translated(qint64 offset) const
+{
+ return QMediaTimeInterval(s + offset, e + offset);
+}
+
+/*!
+ \fn operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+ \relates QMediaTimeRange
+
+ Returns true if \a a is exactly equal to \a b.
+ \since 1.0
+*/
+bool operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+{
+ return a.start() == b.start() && a.end() == b.end();
+}
+
+/*!
+ \fn operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+ \relates QMediaTimeRange
+
+ Returns true if \a a is not exactly equal to \a b.
+ \since 1.0
+*/
+bool operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b)
+{
+ return a.start() != b.start() || a.end() != b.end();
+}
+
+class QMediaTimeRangePrivate : public QSharedData
+{
+public:
+
+ QMediaTimeRangePrivate();
+ QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other);
+ QMediaTimeRangePrivate(const QMediaTimeInterval &interval);
+
+ QList<QMediaTimeInterval> intervals;
+
+ void addInterval(const QMediaTimeInterval &interval);
+ void removeInterval(const QMediaTimeInterval &interval);
+};
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate()
+ : QSharedData()
+{
+
+}
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other)
+ : QSharedData()
+ , intervals(other.intervals)
+{
+
+}
+
+QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeInterval &interval)
+ : QSharedData()
+{
+ if(interval.isNormal())
+ intervals << interval;
+}
+
+void QMediaTimeRangePrivate::addInterval(const QMediaTimeInterval &interval)
+{
+ // Handle normalized intervals only
+ if(!interval.isNormal())
+ return;
+
+ // Find a place to insert the interval
+ int i;
+ for (i = 0; i < intervals.count(); i++) {
+ // Insert before this element
+ if(interval.s < intervals[i].s) {
+ intervals.insert(i, interval);
+ break;
+ }
+ }
+
+ // Interval needs to be added to the end of the list
+ if (i == intervals.count())
+ intervals.append(interval);
+
+ // Do we need to correct the element before us?
+ if(i > 0 && intervals[i - 1].e >= interval.s - 1)
+ i--;
+
+ // Merge trailing ranges
+ while (i < intervals.count() - 1
+ && intervals[i].e >= intervals[i + 1].s - 1) {
+ intervals[i].e = qMax(intervals[i].e, intervals[i + 1].e);
+ intervals.removeAt(i + 1);
+ }
+}
+
+void QMediaTimeRangePrivate::removeInterval(const QMediaTimeInterval &interval)
+{
+ // Handle normalized intervals only
+ if(!interval.isNormal())
+ return;
+
+ for (int i = 0; i < intervals.count(); i++) {
+ QMediaTimeInterval r = intervals[i];
+
+ if (r.e < interval.s) {
+ // Before the removal interval
+ continue;
+ } else if (interval.e < r.s) {
+ // After the removal interval - stop here
+ break;
+ } else if (r.s < interval.s && interval.e < r.e) {
+ // Split case - a single range has a chunk removed
+ intervals[i].e = interval.s -1;
+ addInterval(QMediaTimeInterval(interval.e + 1, r.e));
+ break;
+ } else if (r.s < interval.s) {
+ // Trimming Tail Case
+ intervals[i].e = interval.s - 1;
+ } else if (interval.e < r.e) {
+ // Trimming Head Case - we can stop after this
+ intervals[i].s = interval.e + 1;
+ break;
+ } else {
+ // Complete coverage case
+ intervals.removeAt(i);
+ --i;
+ }
+ }
+}
+
+/*!
+ \class QMediaTimeRange
+ \brief The QMediaTimeRange class represents a set of zero or more disjoint
+ time intervals.
+ \ingroup multimedia
+ \since 1.0
+
+ \reentrant
+
+ The earliestTime(), latestTime(), intervals() and isEmpty()
+ methods are used to get information about the current time range.
+
+ The addInterval(), removeInterval() and clear() methods are used to modify
+ the current time range.
+
+ When adding or removing intervals from the time range, existing intervals
+ within the range may be expanded, trimmed, deleted, merged or split to ensure
+ that all intervals within the time range remain distinct and disjoint. As a
+ consequence, all intervals added or removed from a time range must be
+ \l{QMediaTimeInterval::isNormal()}{normal}.
+
+ \sa QMediaTimeInterval
+*/
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange()
+
+ Constructs an empty time range.
+*/
+QMediaTimeRange::QMediaTimeRange()
+ : d(new QMediaTimeRangePrivate)
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end)
+
+ Constructs a time range that contains an initial interval from
+ \a start to \a end inclusive.
+
+ If the interval is not \l{QMediaTimeInterval::isNormal()}{normal},
+ the resulting time range will be empty.
+
+ \since 1.0
+ \sa addInterval()
+*/
+QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end)
+ : d(new QMediaTimeRangePrivate(QMediaTimeInterval(start, end)))
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval)
+
+ Constructs a time range that contains an intitial interval, \a interval.
+
+ If \a interval is not \l{QMediaTimeInterval::isNormal()}{normal},
+ the resulting time range will be empty.
+
+ \since 1.0
+ \sa addInterval()
+*/
+QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval)
+ : d(new QMediaTimeRangePrivate(interval))
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range)
+
+ Constructs a time range by copying another time \a range.
+ \since 1.0
+*/
+QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range)
+ : d(range.d)
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::~QMediaTimeRange()
+
+ Destructor.
+*/
+QMediaTimeRange::~QMediaTimeRange()
+{
+
+}
+
+/*!
+ \fn QMediaTimeRange::operator=(const QMediaTimeRange &other)
+
+ Takes a copy of the \a other time range and returns itself.
+ \since 1.0
+*/
+QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeRange &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator=(const QMediaTimeInterval &interval)
+
+ Sets the time range to a single continuous interval, \a interval.
+ \since 1.0
+*/
+QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeInterval &interval)
+{
+ d = new QMediaTimeRangePrivate(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::earliestTime() const
+
+ Returns the earliest time within the time range.
+
+ For empty time ranges, this value is equal to zero.
+
+ \since 1.0
+ \sa latestTime()
+*/
+qint64 QMediaTimeRange::earliestTime() const
+{
+ if (!d->intervals.isEmpty())
+ return d->intervals[0].s;
+
+ return 0;
+}
+
+/*!
+ \fn QMediaTimeRange::latestTime() const
+
+ Returns the latest time within the time range.
+
+ For empty time ranges, this value is equal to zero.
+
+ \since 1.0
+ \sa earliestTime()
+*/
+qint64 QMediaTimeRange::latestTime() const
+{
+ if (!d->intervals.isEmpty())
+ return d->intervals[d->intervals.count() - 1].e;
+
+ return 0;
+}
+
+/*!
+ \fn QMediaTimeRange::addInterval(qint64 start, qint64 end)
+ \overload
+
+ Adds the interval specified by \a start and \a end
+ to the time range.
+
+ \since 1.0
+ \sa addInterval()
+*/
+void QMediaTimeRange::addInterval(qint64 start, qint64 end)
+{
+ d->addInterval(QMediaTimeInterval(start, end));
+}
+
+/*!
+ \fn QMediaTimeRange::addInterval(const QMediaTimeInterval &interval)
+
+ Adds the specified \a interval to the time range.
+
+ Adding intervals which are not \l{QMediaTimeInterval::isNormal()}{normal}
+ is invalid, and will be ignored.
+
+ If the specified interval is adjacent to, or overlaps existing
+ intervals within the time range, these intervals will be merged.
+
+ This operation takes \l{linear time}
+
+ \since 1.0
+ \sa removeInterval()
+*/
+void QMediaTimeRange::addInterval(const QMediaTimeInterval &interval)
+{
+ d->addInterval(interval);
+}
+
+/*!
+ \fn QMediaTimeRange::addTimeRange(const QMediaTimeRange &range)
+
+ Adds each of the intervals in \a range to this time range.
+
+ Equivalent to calling addInterval() for each interval in \a range.
+ \since 1.0
+*/
+void QMediaTimeRange::addTimeRange(const QMediaTimeRange &range)
+{
+ foreach(const QMediaTimeInterval &i, range.intervals()) {
+ d->addInterval(i);
+ }
+}
+
+/*!
+ \fn QMediaTimeRange::removeInterval(qint64 start, qint64 end)
+ \overload
+
+ Removes the interval specified by \a start and \a end
+ from the time range.
+
+ \since 1.0
+ \sa removeInterval()
+*/
+void QMediaTimeRange::removeInterval(qint64 start, qint64 end)
+{
+ d->removeInterval(QMediaTimeInterval(start, end));
+}
+
+/*!
+ \fn QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval)
+
+ Removes the specified \a interval from the time range.
+
+ Removing intervals which are not \l{QMediaTimeInterval::isNormal()}{normal}
+ is invalid, and will be ignored.
+
+ Intervals within the time range will be trimmed, split or deleted
+ such that no intervals within the time range include any part of the
+ target interval.
+
+ This operation takes \l{linear time}
+
+ \since 1.0
+ \sa addInterval()
+*/
+void QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval)
+{
+ d->removeInterval(interval);
+}
+
+/*!
+ \fn QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range)
+
+ Removes each of the intervals in \a range from this time range.
+
+ Equivalent to calling removeInterval() for each interval in \a range.
+ \since 1.0
+*/
+void QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range)
+{
+ foreach(const QMediaTimeInterval &i, range.intervals()) {
+ d->removeInterval(i);
+ }
+}
+
+/*!
+ \fn QMediaTimeRange::operator+=(const QMediaTimeRange &other)
+
+ Adds each interval in \a other to the time range and returns the result.
+ \since 1.0
+*/
+QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeRange &other)
+{
+ addTimeRange(other);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator+=(const QMediaTimeInterval &interval)
+
+ Adds the specified \a interval to the time range and returns the result.
+ \since 1.0
+*/
+QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeInterval &interval)
+{
+ addInterval(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator-=(const QMediaTimeRange &other)
+
+ Removes each interval in \a other from the time range and returns the result.
+ \since 1.0
+*/
+QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeRange &other)
+{
+ removeTimeRange(other);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::operator-=(const QMediaTimeInterval &interval)
+
+ Removes the specified \a interval from the time range and returns the result.
+ \since 1.0
+*/
+QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeInterval &interval)
+{
+ removeInterval(interval);
+ return *this;
+}
+
+/*!
+ \fn QMediaTimeRange::clear()
+
+ Removes all intervals from the time range.
+
+ \since 1.0
+ \sa removeInterval()
+*/
+void QMediaTimeRange::clear()
+{
+ d->intervals.clear();
+}
+
+/*!
+ \fn QMediaTimeRange::intervals() const
+
+ Returns the list of intervals covered by this time range.
+ \since 1.0
+*/
+QList<QMediaTimeInterval> QMediaTimeRange::intervals() const
+{
+ return d->intervals;
+}
+
+/*!
+ \fn QMediaTimeRange::isEmpty() const
+
+ Returns true if there are no intervals within the time range.
+
+ \since 1.0
+ \sa intervals()
+*/
+bool QMediaTimeRange::isEmpty() const
+{
+ return d->intervals.isEmpty();
+}
+
+/*!
+ \fn QMediaTimeRange::isContinuous() const
+
+ Returns true if the time range consists of a continuous interval.
+ That is, there is one or fewer disjoint intervals within the time range.
+ \since 1.0
+*/
+bool QMediaTimeRange::isContinuous() const
+{
+ return (d->intervals.count() <= 1);
+}
+
+/*!
+ \fn QMediaTimeRange::contains(qint64 time) const
+
+ Returns true if the specified \a time lies within the time range.
+ \since 1.0
+*/
+bool QMediaTimeRange::contains(qint64 time) const
+{
+ for (int i = 0; i < d->intervals.count(); i++) {
+ if (d->intervals[i].contains(time))
+ return true;
+
+ if (time < d->intervals[i].s)
+ break;
+ }
+
+ return false;
+}
+
+/*!
+ \fn operator==(const QMediaTimeRange &a, const QMediaTimeRange &b)
+ \relates QMediaTimeRange
+
+ Returns true if all intervals in \a a are present in \a b.
+ \since 1.0
+*/
+bool operator==(const QMediaTimeRange &a, const QMediaTimeRange &b)
+{
+ if (a.intervals().count() != b.intervals().count())
+ return false;
+
+ for (int i = 0; i < a.intervals().count(); i++)
+ {
+ if(a.intervals()[i] != b.intervals()[i])
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ \fn operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b)
+ \relates QMediaTimeRange
+
+ Returns true if one or more intervals in \a a are not present in \a b.
+ \since 1.0
+*/
+bool operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b)
+{
+ return !(a == b);
+}
+
+/*!
+ \fn operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+
+ Returns a time range containing the union between \a r1 and \a r2.
+ \since 1.0
+ */
+QMediaTimeRange operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+{
+ return (QMediaTimeRange(r1) += r2);
+}
+
+/*!
+ \fn operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+
+ Returns a time range containing \a r2 subtracted from \a r1.
+ \since 1.0
+ */
+QMediaTimeRange operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2)
+{
+ return (QMediaTimeRange(r1) -= r2);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QMediaTimeRange &range)
+{
+ dbg.nospace() << "QMediaTimeRange( ";
+ foreach (const QMediaTimeInterval &interval, range.intervals()) {
+ dbg.nospace() << "(" << interval.start() << ", " << interval.end() << ") ";
+ }
+ dbg.space() << ")";
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmediatimerange.h b/src/multimedia/qmediatimerange.h
new file mode 100644
index 000000000..d506bbe52
--- /dev/null
+++ b/src/multimedia/qmediatimerange.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEDIATIMERANGE_H
+#define QMEDIATIMERANGE_H
+
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMediaTimeRangePrivate;
+
+class Q_MULTIMEDIA_EXPORT QMediaTimeInterval
+{
+public:
+ QMediaTimeInterval();
+ QMediaTimeInterval(qint64 start, qint64 end);
+ QMediaTimeInterval(const QMediaTimeInterval&);
+
+ qint64 start() const;
+ qint64 end() const;
+
+ bool contains(qint64 time) const;
+
+ bool isNormal() const;
+ QMediaTimeInterval normalized() const;
+ QMediaTimeInterval translated(qint64 offset) const;
+
+private:
+ friend class QMediaTimeRangePrivate;
+ friend class QMediaTimeRange;
+
+ qint64 s;
+ qint64 e;
+};
+
+Q_MULTIMEDIA_EXPORT bool operator==(const QMediaTimeInterval&, const QMediaTimeInterval&);
+Q_MULTIMEDIA_EXPORT bool operator!=(const QMediaTimeInterval&, const QMediaTimeInterval&);
+
+class Q_MULTIMEDIA_EXPORT QMediaTimeRange
+{
+public:
+
+ QMediaTimeRange();
+ QMediaTimeRange(qint64 start, qint64 end);
+ QMediaTimeRange(const QMediaTimeInterval&);
+ QMediaTimeRange(const QMediaTimeRange &range);
+ ~QMediaTimeRange();
+
+ QMediaTimeRange &operator=(const QMediaTimeRange&);
+ QMediaTimeRange &operator=(const QMediaTimeInterval&);
+
+ qint64 earliestTime() const;
+ qint64 latestTime() const;
+
+ QList<QMediaTimeInterval> intervals() const;
+ bool isEmpty() const;
+ bool isContinuous() const;
+
+ bool contains(qint64 time) const;
+
+ void addInterval(qint64 start, qint64 end);
+ void addInterval(const QMediaTimeInterval &interval);
+ void addTimeRange(const QMediaTimeRange&);
+
+ void removeInterval(qint64 start, qint64 end);
+ void removeInterval(const QMediaTimeInterval &interval);
+ void removeTimeRange(const QMediaTimeRange&);
+
+ QMediaTimeRange& operator+=(const QMediaTimeRange&);
+ QMediaTimeRange& operator+=(const QMediaTimeInterval&);
+ QMediaTimeRange& operator-=(const QMediaTimeRange&);
+ QMediaTimeRange& operator-=(const QMediaTimeInterval&);
+
+ void clear();
+
+private:
+ QSharedDataPointer<QMediaTimeRangePrivate> d;
+};
+
+Q_MULTIMEDIA_EXPORT bool operator==(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MULTIMEDIA_EXPORT bool operator!=(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MULTIMEDIA_EXPORT QMediaTimeRange operator+(const QMediaTimeRange&, const QMediaTimeRange&);
+Q_MULTIMEDIA_EXPORT QMediaTimeRange operator-(const QMediaTimeRange&, const QMediaTimeRange&);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QMediaTimeRange &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMEDIATIMERANGE_H
diff --git a/src/multimedia/qmetadatareadercontrol.cpp b/src/multimedia/qmetadatareadercontrol.cpp
new file mode 100644
index 000000000..a15cf6d7e
--- /dev/null
+++ b/src/multimedia/qmetadatareadercontrol.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmediacontrol_p.h>
+#include <qmetadatareadercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMetaDataReaderControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMetaDataReaderControl class provides read access to the
+ meta-data of a QMediaService's media.
+
+ If a QMediaService can provide read or write access to the meta-data of
+ its current media it will implement QMetaDataReaderControl. This control
+ provides functions for both retrieving and setting meta-data values.
+ Meta-data may be addressed by the well defined keys in the
+ QtMultimedia::MetaData enumeration using the metaData() functions, or by
+ string keys using the extendedMetaData() functions.
+
+ The functionality provided by this control is exposed to application
+ code by the meta-data members of QMediaObject, and so meta-data access
+ is potentially available in any of the media object classes. Any media
+ service may implement QMetaDataReaderControl.
+
+ The interface name of QMetaDataReaderControl is
+ \c com.nokia.Qt.QMetaDataReaderControl/1.0 as defined in
+ QMetaDataReaderControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaObject
+*/
+
+/*!
+ \macro QMetaDataReaderControl_iid
+
+ \c com.nokia.Qt.QMetaDataReaderControl/1.0
+
+ Defines the interface name of the QMetaDataReaderControl class.
+
+ \relates QMetaDataReaderControl
+*/
+
+/*!
+ Construct a QMetaDataReaderControl with \a parent. This class is meant as a base class
+ for service specific meta data providers so this constructor is protected.
+*/
+
+QMetaDataReaderControl::QMetaDataReaderControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroy the meta-data object.
+*/
+
+QMetaDataReaderControl::~QMetaDataReaderControl()
+{
+}
+
+/*!
+ \fn bool QMetaDataReaderControl::isMetaDataAvailable() const
+
+ Identifies if meta-data is available from a media service.
+
+ Returns true if the meta-data is available and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QVariant QMetaDataReaderControl::metaData(QtMultimedia::MetaData key) const
+
+ Returns the meta-data for the given \a key.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataReaderControl::availableMetaData() const
+
+ Returns a list of keys there is meta-data available for.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataReaderControl::extendedMetaData(const QString &key) const
+
+ Returns the metaData for an abitrary string \a key.
+
+ The valid selection of keys for extended meta-data is determined by the provider and the meaning
+ and type may differ between providers.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataReaderControl::availableExtendedMetaData() const
+
+ Returns a list of keys there is extended meta-data available for.
+ \since 1.0
+*/
+
+
+/*!
+ \fn void QMetaDataReaderControl::metaDataChanged()
+
+ Signal the changes of meta-data.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMetaDataReaderControl::metaDataAvailableChanged(bool available)
+
+ Signal the availability of meta-data has changed, \a available will
+ be true if the multimedia object has meta-data.
+ \since 1.0
+*/
+
+#include "moc_qmetadatareadercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmetadatareadercontrol.h b/src/multimedia/qmetadatareadercontrol.h
new file mode 100644
index 000000000..0d370b5c4
--- /dev/null
+++ b/src/multimedia/qmetadatareadercontrol.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMETADATAREADERCONTROL_H
+#define QMETADATAREADERCONTROL_H
+
+#include <qmediacontrol.h>
+#include <qmediaobject.h>
+
+#include <qmediaresource.h>
+
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class Q_MULTIMEDIA_EXPORT QMetaDataReaderControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ ~QMetaDataReaderControl();
+
+ virtual bool isMetaDataAvailable() const = 0;
+
+ virtual QVariant metaData(QtMultimedia::MetaData key) const = 0;
+ virtual QList<QtMultimedia::MetaData> availableMetaData() const = 0;
+
+ virtual QVariant extendedMetaData(const QString &key) const = 0;
+ virtual QStringList availableExtendedMetaData() const = 0;
+
+Q_SIGNALS:
+ void metaDataChanged();
+
+ void metaDataAvailableChanged(bool available);
+
+protected:
+ QMetaDataReaderControl(QObject *parent = 0);
+};
+
+#define QMetaDataReaderControl_iid "com.nokia.Qt.QMetaDataReaderControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMetaDataReaderControl, QMetaDataReaderControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QMETADATAPROVIDER_H
diff --git a/src/multimedia/qmetadatawritercontrol.cpp b/src/multimedia/qmetadatawritercontrol.cpp
new file mode 100644
index 000000000..0888bcfae
--- /dev/null
+++ b/src/multimedia/qmetadatawritercontrol.cpp
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmediacontrol_p.h>
+#include <qmetadatawritercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QMetaDataWriterControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QMetaDataWriterControl class provides write access to the
+ meta-data of a QMediaService's media.
+
+ If a QMediaService can provide write access to the meta-data of its
+ current media it will implement QMetaDataWriterControl. This control
+ provides functions for both retrieving and setting meta-data values.
+ Meta-data may be addressed by the well defined keys in the
+ QtMultimedia::MetaData enumeration using the metaData() functions, or
+ by string keys using the extendedMetaData() functions.
+
+ The functionality provided by this control is exposed to application code
+ by the meta-data members of QMediaObject, and so meta-data access is
+ potentially available in any of the media object classes. Any media
+ service may implement QMetaDataControl.
+
+ The interface name of QMetaDataWriterControl is \c com.nokia.Qt.QMetaDataWriterControl/1.0 as
+ defined in QMetaDataWriterControl_iid.
+
+ \sa QMediaService::requestControl(), QMediaObject
+*/
+
+/*!
+ \macro QMetaDataWriterControl_iid
+
+ \c com.nokia.Qt.QMetaDataWriterControl/1.0
+
+ Defines the interface name of the QMetaDataWriterControl class.
+
+ \relates QMetaDataWriterControl
+*/
+
+/*!
+ Construct a QMetaDataWriterControl with \a parent. This class is meant as a base class
+ for service specific meta data providers so this constructor is protected.
+*/
+
+QMetaDataWriterControl::QMetaDataWriterControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroy the meta-data writer control.
+*/
+
+QMetaDataWriterControl::~QMetaDataWriterControl()
+{
+}
+
+/*!
+ \fn bool QMetaDataWriterControl::isMetaDataAvailable() const
+
+ Identifies if meta-data is available from a media service.
+
+ Returns true if the meta-data is available and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QMetaDataWriterControl::isWritable() const
+
+ Identifies if a media service's meta-data can be edited.
+
+ Returns true if the meta-data is writable and false otherwise.
+ \since 1.0
+*/
+
+/*!
+ \fn QVariant QMetaDataWriterControl::metaData(QtMultimedia::MetaData key) const
+
+ Returns the meta-data for the given \a key.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMetaDataWriterControl::setMetaData(QtMultimedia::MetaData key, const QVariant &value)
+
+ Sets the \a value of the meta-data element with the given \a key.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataWriterControl::availableMetaData() const
+
+ Returns a list of keys there is meta-data available for.
+*/
+
+/*!
+ \fn QMetaDataWriterControl::extendedMetaData(const QString &key) const
+
+ Returns the meta-data for an abitrary string \a key.
+
+ The valid selection of keys for extended meta-data is determined by the provider and the meaning
+ and type may differ between providers.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataWriterControl::setExtendedMetaData(const QString &key, const QVariant &value)
+
+ Change the value of the meta-data element with an abitrary string \a key to \a value.
+
+ The valid selection of keys for extended meta-data is determined by the provider and the meaning
+ and type may differ between providers.
+ \since 1.0
+*/
+
+/*!
+ \fn QMetaDataWriterControl::availableExtendedMetaData() const
+
+ Returns a list of keys there is extended meta-data available for.
+ \since 1.0
+*/
+
+
+/*!
+ \fn void QMetaDataWriterControl::metaDataChanged()
+
+ Signal the changes of meta-data.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMetaDataWriterControl::metaDataAvailableChanged(bool available)
+
+ Signal the availability of meta-data has changed, \a available will
+ be true if the multimedia object has meta-data.
+ \since 1.0
+*/
+
+/*!
+ \fn void QMetaDataWriterControl::writableChanged(bool writable)
+
+ Signal a change in the writable status of meta-data, \a writable will be
+ true if meta-data elements can be added or adjusted.
+ \since 1.0
+*/
+
+#include "moc_qmetadatawritercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qmetadatawritercontrol.h b/src/multimedia/qmetadatawritercontrol.h
new file mode 100644
index 000000000..3f8b8c3f4
--- /dev/null
+++ b/src/multimedia/qmetadatawritercontrol.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMETADATAWRITERCONTROL_H
+#define QMETADATAWRITERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediaobject.h"
+
+#include "qmediaresource.h"
+
+#include <qtmultimediadefs.h>
+#include "qtmedianamespace.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+
+class Q_MULTIMEDIA_EXPORT QMetaDataWriterControl : public QMediaControl
+{
+ Q_OBJECT
+public:
+ ~QMetaDataWriterControl();
+
+ virtual bool isWritable() const = 0;
+ virtual bool isMetaDataAvailable() const = 0;
+
+ virtual QVariant metaData(QtMultimedia::MetaData key) const = 0;
+ virtual void setMetaData(QtMultimedia::MetaData key, const QVariant &value) = 0;
+ virtual QList<QtMultimedia::MetaData> availableMetaData() const = 0;
+
+ virtual QVariant extendedMetaData(const QString &key) const = 0;
+ virtual void setExtendedMetaData(const QString &key, const QVariant &value) = 0;
+ virtual QStringList availableExtendedMetaData() const = 0;
+
+
+Q_SIGNALS:
+ void metaDataChanged();
+
+ void writableChanged(bool writable);
+ void metaDataAvailableChanged(bool available);
+
+protected:
+ QMetaDataWriterControl(QObject *parent = 0);
+};
+
+#define QMetaDataWriterControl_iid "com.nokia.Qt.QMetaDataWriterControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QMetaDataWriterControl, QMetaDataWriterControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qradiotuner.cpp b/src/multimedia/qradiotuner.cpp
new file mode 100644
index 000000000..25f76b83a
--- /dev/null
+++ b/src/multimedia/qradiotuner.cpp
@@ -0,0 +1,614 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qradiotuner.h"
+#include "qmediaservice.h"
+#include "qmediaobject_p.h"
+#include "qradiotunercontrol.h"
+
+#include <QPair>
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QRadioTuner
+ \brief The QRadioTuner class provides an interface to the systems analog radio device.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \since 1.0
+
+ You can control the systems analog radio device using this interface, for example:
+
+ \snippet doc/src/snippets/multimedia-snippets/media.cpp Radio tuner
+
+ The radio object will emit signals for any changes in state such as:
+ bandChanged(), frequencyChanged(), stereoStatusChanged(), searchingChanged(),
+ signalStrengthChanged(), volumeChanged(), mutedChanged().
+
+ You can change between the frequency bands using setBand() however it is recommended
+ that you check to make sure the band is available first using isBandSupported().
+
+*/
+
+
+class QRadioTunerPrivate : public QMediaObjectPrivate
+{
+public:
+ QRadioTunerPrivate():provider(0), control(0) {}
+ QMediaServiceProvider *provider;
+ QRadioTunerControl* control;
+};
+
+
+
+/*!
+ Constructs a radio tuner based on a media service allocated by a media service \a provider.
+
+ The \a parent is passed to QMediaObject.
+ \since 1.0
+*/
+
+QRadioTuner::QRadioTuner(QObject *parent, QMediaServiceProvider* provider):
+ QMediaObject(*new QRadioTunerPrivate, parent, provider->requestService(Q_MEDIASERVICE_RADIO))
+{
+ Q_D(QRadioTuner);
+
+ d->provider = provider;
+
+ if (d->service != 0) {
+ d->control = qobject_cast<QRadioTunerControl*>(d->service->requestControl(QRadioTunerControl_iid));
+ if (d->control != 0) {
+ connect(d->control, SIGNAL(stateChanged(QRadioTuner::State)), SIGNAL(stateChanged(QRadioTuner::State)));
+ connect(d->control, SIGNAL(bandChanged(QRadioTuner::Band)), SIGNAL(bandChanged(QRadioTuner::Band)));
+ connect(d->control, SIGNAL(frequencyChanged(int)), SIGNAL(frequencyChanged(int)));
+ connect(d->control, SIGNAL(stereoStatusChanged(bool)), SIGNAL(stereoStatusChanged(bool)));
+ connect(d->control, SIGNAL(searchingChanged(bool)), SIGNAL(searchingChanged(bool)));
+ connect(d->control, SIGNAL(signalStrengthChanged(int)), SIGNAL(signalStrengthChanged(int)));
+ connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
+ connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
+ connect(d->control, SIGNAL(error(QRadioTuner::Error)), SIGNAL(error(QRadioTuner::Error)));
+ }
+ }
+}
+
+/*!
+ Destroys a radio tuner.
+*/
+
+QRadioTuner::~QRadioTuner()
+{
+ Q_D(QRadioTuner);
+
+ if (d->service && d->control)
+ d->service->releaseControl(d->control);
+
+ d->provider->releaseService(d->service);
+}
+
+/*!
+ Returns true if the radio tuner service is ready to use.
+ \since 1.0
+*/
+bool QRadioTuner::isAvailable() const
+{
+ if (d_func()->control != NULL)
+ return d_func()->control->isAvailable();
+ else
+ return false;
+}
+
+/*!
+ Returns the availability error state.
+ \since 1.0
+*/
+QtMultimedia::AvailabilityError QRadioTuner::availabilityError() const
+{
+ if (d_func()->control != NULL)
+ return d_func()->control->availabilityError();
+ else
+ return QtMultimedia::ServiceMissingError;
+}
+
+/*!
+ \property QRadioTuner::state
+ Return the current radio tuner state.
+
+ \since 1.0
+ \sa QRadioTuner::State
+*/
+
+QRadioTuner::State QRadioTuner::state() const
+{
+ return d_func()->control ?
+ d_func()->control->state() : QRadioTuner::StoppedState;
+}
+
+/*!
+ \property QRadioTuner::band
+ \brief the frequency band a radio tuner is tuned to.
+
+ \since 1.0
+ \sa QRadioTuner::Band
+*/
+
+QRadioTuner::Band QRadioTuner::band() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->band();
+
+ return QRadioTuner::FM;
+}
+
+/*!
+ \property QRadioTuner::frequency
+ \brief the frequency in Hertz a radio tuner is tuned to.
+ \since 1.0
+*/
+
+int QRadioTuner::frequency() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->frequency();
+
+ return 0;
+}
+
+/*!
+ Returns the number of Hertz to increment the frequency by when stepping through frequencies
+ within a given \a band.
+ \since 1.0
+*/
+
+int QRadioTuner::frequencyStep(QRadioTuner::Band band) const
+{
+ Q_D(const QRadioTuner);
+
+ if(d->control != 0)
+ return d->control->frequencyStep(band);
+
+ return 0;
+}
+
+/*!
+ Returns a frequency \a band's minimum and maximum frequency.
+ \since 1.0
+*/
+
+QPair<int,int> QRadioTuner::frequencyRange(QRadioTuner::Band band) const
+{
+ Q_D(const QRadioTuner);
+
+ if(d->control != 0)
+ return d->control->frequencyRange(band);
+
+ return qMakePair<int,int>(0,0);
+}
+
+/*!
+ \property QRadioTuner::stereo
+ \brief whether a radio tuner is receiving a stereo signal.
+ \since 1.0
+*/
+
+bool QRadioTuner::isStereo() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->isStereo();
+
+ return false;
+}
+
+
+/*!
+ \property QRadioTuner::stereoMode
+ \brief the stereo mode of a radio tuner.
+ \since 1.0
+*/
+
+QRadioTuner::StereoMode QRadioTuner::stereoMode() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->stereoMode();
+
+ return QRadioTuner::Auto;
+}
+
+void QRadioTuner::setStereoMode(QRadioTuner::StereoMode mode)
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->setStereoMode(mode);
+}
+
+/*!
+ Identifies if a frequency \a band is supported by a radio tuner.
+
+ Returns true if the band is supported, and false if it is not.
+ \since 1.0
+*/
+
+bool QRadioTuner::isBandSupported(QRadioTuner::Band band) const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->isBandSupported(band);
+
+ return false;
+}
+
+/*!
+ Activate the radio device.
+ \since 1.0
+*/
+
+void QRadioTuner::start()
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ d->control->start();
+}
+
+/*!
+ Deactivate the radio device.
+ \since 1.0
+*/
+
+void QRadioTuner::stop()
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ d->control->stop();
+}
+
+/*!
+ \property QRadioTuner::signalStrength
+ \brief the strength of the current radio signal as a percentage.
+ \since 1.0
+*/
+
+int QRadioTuner::signalStrength() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->signalStrength();
+
+ return 0;
+}
+
+/*!
+ \property QRadioTuner::volume
+ \brief the volume of a radio tuner's audio output as a percentage.
+ \since 1.0
+*/
+
+
+int QRadioTuner::volume() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->volume();
+
+ return 0;
+}
+
+/*!
+ \property QRadioTuner::muted
+ \brief whether a radio tuner's audio output is muted.
+ \since 1.0
+*/
+
+bool QRadioTuner::isMuted() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->isMuted();
+
+ return false;
+}
+
+/*!
+ Sets a radio tuner's frequency \a band.
+
+ Changing the band will reset the \l frequency to the new band's minimum frequency.
+ \since 1.0
+*/
+
+void QRadioTuner::setBand(QRadioTuner::Band band)
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->setBand(band);
+}
+
+/*!
+ Sets a radio tuner's \a frequency.
+
+ If the tuner is set to a frequency outside the current \l band, the band will be changed to
+ one occupied by the new frequency.
+ \since 1.0
+*/
+
+void QRadioTuner::setFrequency(int frequency)
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->setFrequency(frequency);
+}
+
+void QRadioTuner::setVolume(int volume)
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->setVolume(volume);
+}
+
+void QRadioTuner::setMuted(bool muted)
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->setMuted(muted);
+}
+
+/*!
+ \property QRadioTuner::searching
+ \brief whether a radio tuner is currently scanning for a signal.
+
+ \sa searchForward(), searchBackward(), cancelSearch()
+ \since 1.0
+*/
+
+bool QRadioTuner::isSearching() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->isSearching();
+
+ return false;
+}
+
+/*!
+ Starts a forward scan for a signal, starting from the current \l frequency.
+
+ \since 1.0
+ \sa searchBackward(), cancelSearch(), searching
+*/
+
+void QRadioTuner::searchForward()
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->searchForward();
+}
+
+/*!
+ Starts a backwards scan for a signal, starting from the current \l frequency.
+
+ \since 1.0
+ \sa searchForward(), cancelSearch(), searching
+*/
+
+void QRadioTuner::searchBackward()
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->searchBackward();
+}
+
+/*!
+ Stops scanning for a signal.
+
+ \since 1.0
+ \sa searchForward(), searchBackward(), searching
+*/
+
+void QRadioTuner::cancelSearch()
+{
+ Q_D(QRadioTuner);
+
+ if (d->control != 0)
+ d->control->cancelSearch();
+}
+
+/*!
+ Returns the error state of a radio tuner.
+
+ \since 1.0
+ \sa errorString()
+*/
+
+QRadioTuner::Error QRadioTuner::error() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->error();
+
+ return QRadioTuner::ResourceError;
+}
+
+/*!
+ Returns a description of a radio tuner's error state.
+
+ \since 1.0
+ \sa error()
+*/
+
+QString QRadioTuner::errorString() const
+{
+ Q_D(const QRadioTuner);
+
+ if (d->control != 0)
+ return d->control->errorString();
+
+ return QString();
+}
+
+/*!
+ \fn void QRadioTuner::bandChanged(QRadioTuner::Band band)
+
+ Signals a radio tuner's \a band has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::frequencyChanged(int frequency)
+
+ Signals that the \a frequency a radio tuner is tuned to has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::mutedChanged(bool muted)
+
+ Signals that the \a muted state of a radio tuner's audio output has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::volumeChanged(int volume)
+
+ Signals that the \a volume of a radio tuner's audio output has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::searchingChanged(bool searching)
+
+ Signals that the \a searching state of a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::stereoStatusChanged(bool stereo)
+
+ Signals that the \a stereo state of a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::signalStrengthChanged(int strength)
+
+ Signals that the \a strength of the signal received by a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTuner::error(QRadioTuner::Error error)
+
+ Signals that an \a error occurred.
+ \since 1.0
+*/
+
+/*!
+ \enum QRadioTuner::State
+
+ Enumerates radio tuner states.
+
+ \value ActiveState The tuner is started and active.
+ \value StoppedState The tuner device is stopped.
+*/
+
+
+/*!
+ \enum QRadioTuner::Band
+
+ Enumerates radio frequency bands.
+
+ \value AM 520 to 1610 kHz, 9 or 10kHz channel spacing, extended 1610 to 1710 kHz
+ \value FM 87.5 to 108.0 MHz, except Japan 76-90 MHz
+ \value SW 1.711 to 30.0 MHz, divided into 15 bands. 5kHz channel spacing
+ \value LW 148.5 to 283.5 kHz, 9kHz channel spacing (Europe, Africa, Asia)
+ \value FM2 range not defined, used when area supports more than one FM range.
+*/
+
+/*!
+ \enum QRadioTuner::Error
+
+ Enumerates radio tuner error conditions.
+
+ \value NoError No errors have occurred.
+ \value ResourceError There is no radio service available.
+ \value OpenError Unable to open radio device.
+ \value OutOfRangeError An attempt to set a frequency or band that is not supported by radio device.
+*/
+
+/*!
+ \enum QRadioTuner::StereoMode
+
+ Enumerates radio tuner policy for receiving stereo signals.
+
+ \value Auto Uses the stereo mode matching the station.
+ \value ForceStereo Provide stereo mode, converting if required.
+ \value ForceMono Provide mono mode, converting if required.
+*/
+
+/*! \fn void QRadioTuner::stateChanged(QRadioTuner::State state)
+ This signal is emitted when the state changes to \a state.
+ \since 1.0
+ */
+
+#include "moc_qradiotuner.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qradiotuner.h b/src/multimedia/qradiotuner.h
new file mode 100644
index 000000000..78852638c
--- /dev/null
+++ b/src/multimedia/qradiotuner.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRADIOTUNER_H
+#define QRADIOTUNER_H
+
+#include <QtCore/qobject.h>
+
+#include "qmediaobject.h"
+#include "qmediaserviceprovider.h"
+#include <qmediaenumdebug.h>
+
+#include <QPair>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QRadioTunerPrivate;
+class Q_MULTIMEDIA_EXPORT QRadioTuner : public QMediaObject
+{
+ Q_OBJECT
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(Band band READ band WRITE setBand NOTIFY bandChanged)
+ Q_PROPERTY(int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged)
+ Q_PROPERTY(bool stereo READ isStereo NOTIFY stereoStatusChanged)
+ Q_PROPERTY(StereoMode stereoMode READ stereoMode WRITE setStereoMode)
+ Q_PROPERTY(int signalStrength READ signalStrength NOTIFY signalStrengthChanged)
+ Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(bool searching READ isSearching NOTIFY searchingChanged)
+ Q_ENUMS(State)
+ Q_ENUMS(Band)
+ Q_ENUMS(Error)
+ Q_ENUMS(StereoMode)
+
+public:
+ enum State { ActiveState, StoppedState };
+ enum Band { AM, FM, SW, LW, FM2 };
+ enum Error { NoError, ResourceError, OpenError, OutOfRangeError };
+ enum StereoMode { ForceStereo, ForceMono, Auto };
+
+ QRadioTuner(QObject *parent = 0, QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider());
+ ~QRadioTuner();
+
+ bool isAvailable() const;
+ QtMultimedia::AvailabilityError availabilityError() const;
+
+ State state() const;
+
+ Band band() const;
+
+ bool isBandSupported(Band b) const;
+
+ int frequency() const;
+ int frequencyStep(Band band) const;
+ QPair<int,int> frequencyRange(Band band) const;
+
+ bool isStereo() const;
+ void setStereoMode(QRadioTuner::StereoMode mode);
+ StereoMode stereoMode() const;
+
+ int signalStrength() const;
+
+ int volume() const;
+ bool isMuted() const;
+
+ bool isSearching() const;
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void searchForward();
+ void searchBackward();
+ void cancelSearch();
+
+ void setBand(Band band);
+ void setFrequency(int frequency);
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void start();
+ void stop();
+
+Q_SIGNALS:
+ void stateChanged(QRadioTuner::State state);
+ void bandChanged(QRadioTuner::Band band);
+ void frequencyChanged(int frequency);
+ void stereoStatusChanged(bool stereo);
+ void searchingChanged(bool searching);
+ void signalStrengthChanged(int signalStrength);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(QRadioTuner::Error error);
+
+private:
+ Q_DISABLE_COPY(QRadioTuner)
+ Q_DECLARE_PRIVATE(QRadioTuner)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QRadioTuner::State)
+Q_DECLARE_METATYPE(QRadioTuner::Band)
+Q_DECLARE_METATYPE(QRadioTuner::Error)
+Q_DECLARE_METATYPE(QRadioTuner::StereoMode)
+
+Q_MEDIA_ENUM_DEBUG(QRadioTuner, State)
+Q_MEDIA_ENUM_DEBUG(QRadioTuner, Band)
+Q_MEDIA_ENUM_DEBUG(QRadioTuner, Error)
+Q_MEDIA_ENUM_DEBUG(QRadioTuner, StereoMode)
+
+QT_END_HEADER
+
+#endif // QRADIOPLAYER_H
diff --git a/src/multimedia/qradiotunercontrol.cpp b/src/multimedia/qradiotunercontrol.cpp
new file mode 100644
index 000000000..97ffd2396
--- /dev/null
+++ b/src/multimedia/qradiotunercontrol.cpp
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtmultimediadefs.h>
+#include "qradiotunercontrol.h"
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QRadioTunerControl
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+
+ \brief The QRadioTunerControl class provides access to the radio tuning
+ functionality of a QMediaService.
+
+ If a QMediaService can tune an analog radio device it will implement
+ QRadioTunerControl. This control provides a means to tune a radio device
+ to a specific \l {setFrequency()}{frequency} as well as search \l
+ {searchForward()}{forwards} and \l {searchBackward()}{backwards} for a
+ signal.
+
+ The functionality provided by this control is exposed to application code
+ through the QRadioTuner class.
+
+ The interface name of QRadioTunerControl is \c com.nokia.Qt.QRadioTunerControl/1.0 as
+ defined in QRadioTunerControl_iid.
+
+ \sa QMediaService::requestControl(), QRadioTuner
+*/
+
+/*!
+ \macro QRadioTunerControl_iid
+
+ \c com.nokia.Qt.QRadioTunerControl/1.0
+
+ Defines the interface name of the QRadioTunerControl class.
+
+ \relates QRadioTunerControl
+*/
+
+/*!
+ Constructs a radio tuner control with the given \a parent.
+*/
+
+QRadioTunerControl::QRadioTunerControl(QObject *parent):
+ QMediaControl(*new QMediaControlPrivate, parent)
+{
+}
+
+/*!
+ Destroys a radio tuner control.
+*/
+
+QRadioTunerControl::~QRadioTunerControl()
+{
+}
+
+/*!
+ \fn bool QRadioTunerControl::isAvailable() const
+
+ Returns true if the radio service is ready to use.
+ \since 1.0
+*/
+
+/*!
+ \fn QtMultimedia::AvailabilityError QRadioTunerControl::availabilityError() const
+
+ Returns the error state of the radio service.
+ \since 1.0
+*/
+
+/*!
+ \fn QRadioTuner::State QRadioTunerControl::state() const
+
+ Returns the current radio tuner state.
+ \since 1.0
+*/
+
+/*!
+ \fn QRadioTuner::Band QRadioTunerControl::band() const
+
+ Returns the frequency band a radio tuner is tuned to.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::bandChanged(QRadioTuner::Band band)
+
+ Signals that the frequency \a band a radio tuner is tuned to has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::setBand(QRadioTuner::Band band)
+
+ Sets the frequecy \a band a radio tuner is tuned to.
+
+ Changing the frequency band will reset the frequency to the minimum frequency of the new band.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QRadioTunerControl::isBandSupported(QRadioTuner::Band band) const
+
+ Identifies if a frequency \a band is supported.
+
+ Returns true if the band is supported, and false if it is not.
+ \since 1.0
+*/
+
+/*!
+ \fn int QRadioTunerControl::frequency() const
+
+ Returns the frequency a radio tuner is tuned to.
+ \since 1.0
+*/
+
+/*!
+ \fn int QRadioTunerControl::frequencyStep(QRadioTuner::Band band) const
+
+ Returns the number of Hertz to increment the frequency by when stepping through frequencies
+ within a given \a band.
+ \since 1.0
+*/
+
+/*!
+ \fn QPair<int,int> QRadioTunerControl::frequencyRange(QRadioTuner::Band band) const
+
+ Returns a frequency \a band's minimum and maximum frequency.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::setFrequency(int frequency)
+
+ Sets the \a frequency a radio tuner is tuned to.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QRadioTunerControl::isStereo() const
+
+ Identifies if a radio tuner is receiving a stereo signal.
+
+ Returns true if the tuner is receiving a stereo signal, and false if it is not.
+ \since 1.0
+*/
+
+/*!
+ \fn QRadioTuner::StereoMode QRadioTunerControl::stereoMode() const
+
+ Returns a radio tuner's stereo mode.
+
+ \since 1.0
+ \sa QRadioTuner::StereoMode
+*/
+
+/*!
+ \fn void QRadioTunerControl::setStereoMode(QRadioTuner::StereoMode mode)
+
+ Sets a radio tuner's stereo \a mode.
+
+ \since 1.0
+ \sa QRadioTuner::StereoMode
+*/
+
+/*!
+ \fn int QRadioTunerControl::signalStrength() const
+
+ Return a radio tuner's current signal strength as a percentage.
+ \since 1.0
+*/
+
+/*!
+ \fn int QRadioTunerControl::volume() const
+
+ Returns the volume of a radio tuner's audio output as a percentage.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::setVolume(int volume)
+
+ Sets the percentage \a volume of a radio tuner's audio output.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QRadioTunerControl::isMuted() const
+
+ Identifies if a radio tuner's audio output is muted.
+
+ Returns true if the audio is muted, and false if it is not.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::setMuted(bool muted)
+
+ Sets the \a muted state of a radio tuner's audio output.
+ \since 1.0
+*/
+
+/*!
+ \fn bool QRadioTunerControl::isSearching() const
+
+ Identifies if a radio tuner is currently scanning for signal.
+
+ Returns true if the tuner is scanning, and false if it is not.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::searchForward()
+
+ Starts a forward scan for a signal, starting from the current \l frequency().
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::searchBackward()
+
+ Starts a backwards scan for a signal, starting from the current \l frequency().
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::cancelSearch()
+
+ Stops scanning for a signal.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::start()
+
+ Activate the radio device.
+ \since 1.0
+*/
+
+/*!
+ \fn QRadioTunerControl::stop()
+
+ Deactivate the radio device.
+ \since 1.0
+*/
+
+/*!
+ \fn QRadioTuner::Error QRadioTunerControl::error() const
+
+ Returns the error state of a radio tuner.
+ \since 1.0
+*/
+
+/*!
+ \fn QString QRadioTunerControl::errorString() const
+
+ Returns a string describing a radio tuner's error state.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::stateChanged(QRadioTuner::State state)
+
+ Signals that the \a state of a radio tuner has changed.
+ \since 1.0
+*/
+
+
+/*!
+ \fn void QRadioTunerControl::frequencyChanged(int frequency)
+
+ Signals that the \a frequency a radio tuner is tuned to has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::stereoStatusChanged(bool stereo)
+
+ Signals that the \a stereo state of a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::searchingChanged(bool searching)
+
+ Signals that the \a searching state of a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::signalStrengthChanged(int strength)
+
+ Signals that the percentage \a strength of the signal received by a radio tuner has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::volumeChanged(int volume)
+
+ Signals that the percentage \a volume of radio tuner's audio output has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::mutedChanged(bool muted)
+
+ Signals that the \a muted state of a radio tuner's audio output has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn void QRadioTunerControl::error(QRadioTuner::Error error)
+
+ Signals that an \a error has occurred.
+ \since 1.0
+*/
+
+#include "moc_qradiotunercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qradiotunercontrol.h b/src/multimedia/qradiotunercontrol.h
new file mode 100644
index 000000000..04812be48
--- /dev/null
+++ b/src/multimedia/qradiotunercontrol.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRADIOTUNERCONTROL_H
+#define QRADIOTUNERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qradiotuner.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class Q_MULTIMEDIA_EXPORT QRadioTunerControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QRadioTunerControl();
+
+ virtual bool isAvailable() const = 0;
+ virtual QtMultimedia::AvailabilityError availabilityError() const = 0;
+
+ virtual QRadioTuner::State state() const = 0;
+
+ virtual QRadioTuner::Band band() const = 0;
+ virtual void setBand(QRadioTuner::Band b) = 0;
+ virtual bool isBandSupported(QRadioTuner::Band b) const = 0;
+
+ virtual int frequency() const = 0;
+ virtual int frequencyStep(QRadioTuner::Band b) const = 0;
+ virtual QPair<int,int> frequencyRange(QRadioTuner::Band b) const = 0;
+ virtual void setFrequency(int frequency) = 0;
+
+ virtual bool isStereo() const = 0;
+ virtual QRadioTuner::StereoMode stereoMode() const = 0;
+ virtual void setStereoMode(QRadioTuner::StereoMode mode) = 0;
+
+ virtual int signalStrength() const = 0;
+
+ virtual int volume() const = 0;
+ virtual void setVolume(int volume) = 0;
+
+ virtual bool isMuted() const = 0;
+ virtual void setMuted(bool muted) = 0;
+
+ virtual bool isSearching() const = 0;
+
+ virtual void searchForward() = 0;
+ virtual void searchBackward() = 0;
+ virtual void cancelSearch() = 0;
+
+ virtual void start() = 0;
+ virtual void stop() = 0;
+
+ virtual QRadioTuner::Error error() const = 0;
+ virtual QString errorString() const = 0;
+
+Q_SIGNALS:
+ void stateChanged(QRadioTuner::State state);
+ void bandChanged(QRadioTuner::Band band);
+ void frequencyChanged(int frequency);
+ void stereoStatusChanged(bool stereo);
+ void searchingChanged(bool searching);
+ void signalStrengthChanged(int signalStrength);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(QRadioTuner::Error err);
+
+protected:
+ QRadioTunerControl(QObject *parent = 0);
+};
+
+#define QRadioTunerControl_iid "com.nokia.Qt.QRadioTunerControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QRadioTunerControl, QRadioTunerControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QRADIOTUNERCONTROL_H
diff --git a/src/multimedia/qtmedianamespace.h b/src/multimedia/qtmedianamespace.h
new file mode 100644
index 000000000..4296b188d
--- /dev/null
+++ b/src/multimedia/qtmedianamespace.h
@@ -0,0 +1,339 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTMEDIANAMESPACE_H
+#define QTMEDIANAMESPACE_H
+
+#include <QtCore/qpair.h>
+#include <QtCore/qmetatype.h>
+
+#include <qtmultimediadefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+// For now, for backwards source compatibility
+// we have a copy of these enums
+// But if you add a new enum value, you won't need
+// to copy it to the QtMMK enums since it can't have
+// been used before.
+namespace QtMultimedia
+{
+ enum MetaData
+ {
+ // Common
+ Title,
+ SubTitle,
+ Author,
+ Comment,
+ Description,
+ Category,
+ Genre,
+ Year,
+ Date,
+ UserRating,
+ Keywords,
+ Language,
+ Publisher,
+ Copyright,
+ ParentalRating,
+ RatingOrganisation,
+
+ // Media
+ Size,
+ MediaType,
+ Duration,
+
+ // Audio
+ AudioBitRate,
+ AudioCodec,
+ AverageLevel,
+ ChannelCount,
+ PeakValue,
+ SampleRate,
+
+ // Music
+ AlbumTitle,
+ AlbumArtist,
+ ContributingArtist,
+ Composer,
+ Conductor,
+ Lyrics,
+ Mood,
+ TrackNumber,
+ TrackCount,
+
+ CoverArtUrlSmall,
+ CoverArtUrlLarge,
+
+ // Image/Video
+ Resolution,
+ PixelAspectRatio,
+
+ // Video
+ VideoFrameRate,
+ VideoBitRate,
+ VideoCodec,
+
+ PosterUrl,
+
+ // Movie
+ ChapterNumber,
+ Director,
+ LeadPerformer,
+ Writer,
+
+ // Photos
+ CameraManufacturer,
+ CameraModel,
+ Event,
+ Subject,
+ Orientation,
+ ExposureTime,
+ FNumber,
+ ExposureProgram,
+ ISOSpeedRatings,
+ ExposureBiasValue,
+ DateTimeOriginal,
+ DateTimeDigitized,
+ SubjectDistance,
+ MeteringMode,
+ LightSource,
+ Flash,
+ FocalLength,
+ ExposureMode,
+ WhiteBalance,
+ DigitalZoomRatio,
+ FocalLengthIn35mmFilm,
+ SceneCaptureType,
+ GainControl,
+ Contrast,
+ Saturation,
+ Sharpness,
+ DeviceSettingDescription,
+
+ PosterImage,
+ CoverArtImage,
+ ThumbnailImage
+
+ };
+
+ enum SupportEstimate
+ {
+ NotSupported,
+ MaybeSupported,
+ ProbablySupported,
+ PreferredService
+ };
+
+ enum EncodingQuality
+ {
+ VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+
+ enum EncodingMode
+ {
+ ConstantQualityEncoding,
+ ConstantBitRateEncoding,
+ AverageBitRateEncoding,
+ TwoPassEncoding
+ };
+
+ enum AvailabilityError
+ {
+ NoError,
+ ServiceMissingError,
+ BusyError,
+ ResourceError
+ };
+
+}
+
+// For legacy support
+namespace QtMultimediaKit
+{
+ enum MetaData
+ {
+ // Common
+ Title = QtMultimedia::Title,
+ SubTitle,
+ Author,
+ Comment,
+ Description,
+ Category,
+ Genre,
+ Year,
+ Date,
+ UserRating,
+ Keywords,
+ Language,
+ Publisher,
+ Copyright,
+ ParentalRating,
+ RatingOrganisation,
+
+ // Media
+ Size,
+ MediaType,
+ Duration,
+
+ // Audio
+ AudioBitRate,
+ AudioCodec,
+ AverageLevel,
+ ChannelCount,
+ PeakValue,
+ SampleRate,
+
+ // Music
+ AlbumTitle,
+ AlbumArtist,
+ ContributingArtist,
+ Composer,
+ Conductor,
+ Lyrics,
+ Mood,
+ TrackNumber,
+ TrackCount,
+
+ CoverArtUrlSmall,
+ CoverArtUrlLarge,
+
+ // Image/Video
+ Resolution,
+ PixelAspectRatio,
+
+ // Video
+ VideoFrameRate,
+ VideoBitRate,
+ VideoCodec,
+
+ PosterUrl,
+
+ // Movie
+ ChapterNumber,
+ Director,
+ LeadPerformer,
+ Writer,
+
+ // Photos
+ CameraManufacturer,
+ CameraModel,
+ Event,
+ Subject,
+ Orientation,
+ ExposureTime,
+ FNumber,
+ ExposureProgram,
+ ISOSpeedRatings,
+ ExposureBiasValue,
+ DateTimeOriginal,
+ DateTimeDigitized,
+ SubjectDistance,
+ MeteringMode,
+ LightSource,
+ Flash,
+ FocalLength,
+ ExposureMode,
+ WhiteBalance,
+ DigitalZoomRatio,
+ FocalLengthIn35mmFilm,
+ SceneCaptureType,
+ GainControl,
+ Contrast,
+ Saturation,
+ Sharpness,
+ DeviceSettingDescription,
+
+ PosterImage,
+ CoverArtImage,
+ ThumbnailImage
+
+ };
+
+ enum SupportEstimate
+ {
+ NotSupported = QtMultimedia::NotSupported,
+ MaybeSupported,
+ ProbablySupported,
+ PreferredService
+ };
+
+ enum EncodingQuality
+ {
+ VeryLowQuality = QtMultimedia::VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+
+ enum EncodingMode
+ {
+ ConstantQualityEncoding = QtMultimedia::ConstantQualityEncoding,
+ ConstantBitRateEncoding,
+ AverageBitRateEncoding,
+ TwoPassEncoding
+ };
+
+ enum AvailabilityError
+ {
+ NoError = QtMultimedia::NoError,
+ ServiceMissingError,
+ BusyError,
+ ResourceError
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qtmedianamespace.qdoc b/src/multimedia/qtmedianamespace.qdoc
new file mode 100644
index 000000000..bc998e930
--- /dev/null
+++ b/src/multimedia/qtmedianamespace.qdoc
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \namespace QtMultimedia
+ \ingroup multimedia
+ \inmodule QtMultimedia
+
+ \brief The QtMultimedia namespace contains miscellaneous identifiers used throughout the Qt Media services library.
+
+ QtMultimedia is a module containing the low level, low latency,
+ Multimedia APIs which were introduced in Qt 4.6 and also includes the
+ high level QtMultimedia APIs which were introduced in QtMobility 1.0.
+
+*/
+
+/*!
+ \enum QtMultimedia::MetaData
+
+ This enum provides identifiers for meta-data attributes.
+
+ \note Not all identifiers are supported on all platforms. Please consult vendor documentation for specific support
+ on different platforms.
+
+ Common attributes
+ \value Title The title of the media. QString.
+ \value SubTitle The sub-title of the media. QString.
+ \value Author The authors of the media. QStringList.
+ \value Comment A user comment about the media. QString.
+ \value Description A description of the media. QString
+ \value Category The category of the media. QStringList.
+ \value Genre The genre of the media. QStringList.
+ \value Year The year of release of the media. int.
+ \value Date The date of the media. QDate.
+ \value UserRating A user rating of the media. int [0..100].
+ \value Keywords A list of keywords describing the media. QStringList.
+ \value Language The language of media, as an ISO 639-2 code.
+
+ \value Publisher The publisher of the media. QString.
+ \value Copyright The media's copyright notice. QString.
+ \value ParentalRating The parental rating of the media. QString.
+ \value RatingOrganisation The organisation responsible for the parental rating of the media.
+ QString.
+
+ Media attributes
+ \value Size The size in bytes of the media. qint64
+ \value MediaType The type of the media (audio, video, etc). QString.
+ \value Duration The duration in millseconds of the media. qint64.
+
+ Audio attributes
+ \value AudioBitRate The bit rate of the media's audio stream in bits per second. int.
+ \value AudioCodec The codec of the media's audio stream. QString.
+ \value AverageLevel The average volume level of the media. int.
+ \value ChannelCount The number of channels in the media's audio stream. int.
+ \value PeakValue The peak volume of the media's audio stream. int
+ \value SampleRate The sample rate of the media's audio stream in hertz. int
+
+ Music attributes
+ \value AlbumTitle The title of the album the media belongs to. QString.
+ \value AlbumArtist The principal artist of the album the media belongs to. QString.
+ \value ContributingArtist The artists contributing to the media. QStringList.
+ \value Composer The composer of the media. QStringList.
+ \value Conductor The conductor of the media. QString.
+ \value Lyrics The lyrics to the media. QString.
+ \value Mood The mood of the media. QString.
+ \value TrackNumber The track number of the media. int.
+ \value TrackCount The number of tracks on the album containing the media. int.
+
+ \value CoverArtUrlSmall The URL of a small cover art image. QUrl.
+ \value CoverArtUrlLarge The URL of a large cover art image. QUrl.
+ \value CoverArtImage An embedded cover art image. QImage.
+
+ Image and video attributes
+ \value Resolution The dimensions of an image or video. QSize.
+ \value PixelAspectRatio The pixel aspect ratio of an image or video. QSize.
+
+ Video attributes
+ \value VideoFrameRate The frame rate of the media's video stream. qreal.
+ \value VideoBitRate The bit rate of the media's video stream in bits per second. int.
+ \value VideoCodec The codec of the media's video stream. QString.
+
+ \value PosterUrl The URL of a poster image. QUrl.
+ \value PosterImage An embedded poster image. QImage.
+
+ Movie attributes
+ \value ChapterNumber The chapter number of the media. int.
+ \value Director The director of the media. QString.
+ \value LeadPerformer The lead performer in the media. QStringList.
+ \value Writer The writer of the media. QStringList.
+
+ Photo attributes.
+ \value CameraManufacturer The manufacturer of the camera used to capture the media. QString.
+ \value CameraModel The model of the camera used to capture the media. QString.
+ \value Event The event during which the media was captured. QString.
+ \value Subject The subject of the media. QString.
+ \value Orientation Orientation of image.
+ \value ExposureTime Exposure time, given in seconds.
+ \value FNumber The F Number.
+ \value ExposureProgram
+ The class of the program used by the camera to set exposure when the picture is taken.
+ \value ISOSpeedRatings
+ Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232.
+ \value ExposureBiasValue
+ The exposure bias.
+ The unit is the APEX (Additive System of Photographic Exposure) setting.
+ \value DateTimeOriginal The date and time when the original image data was generated.
+ \value DateTimeDigitized The date and time when the image was stored as digital data.
+ \value SubjectDistance The distance to the subject, given in meters.
+ \value MeteringMode The metering mode.
+ \value LightSource
+ The kind of light source.
+ \value Flash
+ Status of flash when the image was shot.
+ \value FocalLength
+ The actual focal length of the lens, in mm.
+ \value ExposureMode
+ Indicates the exposure mode set when the image was shot.
+ \value WhiteBalance
+ Indicates the white balance mode set when the image was shot.
+ \value DigitalZoomRatio
+ Indicates the digital zoom ratio when the image was shot.
+ \value FocalLengthIn35mmFilm
+ Indicates the equivalent focal length assuming a 35mm film camera, in mm.
+ \value SceneCaptureType
+ Indicates the type of scene that was shot.
+ It can also be used to record the mode in which the image was shot.
+ \value GainControl
+ Indicates the degree of overall image gain adjustment.
+ \value Contrast
+ Indicates the direction of contrast processing applied by the camera when the image was shot.
+ \value Saturation
+ Indicates the direction of saturation processing applied by the camera when the image was shot.
+ \value Sharpness
+ Indicates the direction of sharpness processing applied by the camera when the image was shot.
+ \value DeviceSettingDescription
+ Exif tag, indicates information on the picture-taking conditions of a particular camera model. QString
+
+ \value ThumbnailImage An embedded thumbnail image. QImage.
+*/
+
+/*!
+ \enum QtMultimedia::SupportEstimate
+
+ Enumerates the levels of support a media service provider may have for a feature.
+
+ \value NotSupported The feature is not supported.
+ \value MaybeSupported The feature may be supported.
+ \value ProbablySupported The feature is probably supported.
+ \value PreferredService The service is the preferred provider of a service.
+*/
+
+/*!
+ \enum QtMultimedia::EncodingQuality
+
+ Enumerates quality encoding levels.
+
+ \value VeryLowQuality
+ \value LowQuality
+ \value NormalQuality
+ \value HighQuality
+ \value VeryHighQuality
+*/
+
+/*!
+ \enum QtMultimedia::EncodingMode
+
+ Enumerates encoding modes.
+
+ \value ConstantQualityEncoding
+ \value ConstantBitRateEncoding
+ \value AverageBitRateEncoding
+ \value TwoPassEncoding
+*/
+
+/*!
+ \enum QtMultimedia::AvailabilityError
+
+ Enumerates Service status errors.
+
+ \value NoError The service is operating correctly.
+ \value ServiceMissingError There is no service available to provide the requested functionality.
+ \value ResourceError The service could not allocate resources required to function correctly.
+ \value BusyError The service must wait for access to necessary resources.
+*/
diff --git a/src/multimedia/qtmultimediadefs.h b/src/multimedia/qtmultimediadefs.h
new file mode 100644
index 000000000..313503929
--- /dev/null
+++ b/src/multimedia/qtmultimediadefs.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+
+#ifndef QTMULTIMEDIA_P_H
+#define QTMULTIMEDIA_P_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+#if defined(Q_OS_WIN)
+# if defined(QT_NODLL)
+# undef QT_MAKEDLL
+# undef QT_DLL
+# elif defined(QT_MAKEDLL)
+# if defined(QT_DLL)
+# undef QT_DLL
+# endif
+# if defined(QT_BUILD_MULTIMEDIA_LIB)
+# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
+# else
+# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT
+# endif
+# elif defined(QT_DLL) /* use a Qt DLL library */
+# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT
+# endif
+#endif
+
+#if !defined(Q_MULTIMEDIA_EXPORT)
+# if defined(QT_SHARED)
+# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
+# else
+# define Q_MULTIMEDIA_EXPORT
+# endif
+#endif
+
+QT_END_HEADER
+
+
+#endif // QMULTIMEDIA_P_H
+
diff --git a/src/multimedia/qvideodevicecontrol.cpp b/src/multimedia/qvideodevicecontrol.cpp
new file mode 100644
index 000000000..a864fd580
--- /dev/null
+++ b/src/multimedia/qvideodevicecontrol.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideodevicecontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoDeviceControl
+
+ \brief The QVideoDeviceControl class provides an video device selector media control.
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ The QVideoDeviceControl class provides descriptions of the video devices
+ available on a system and allows one to be selected as the endpoint of a
+ media service.
+
+ The interface name of QVideoDeviceControl is \c com.nokia.Qt.VideoDeviceControl as
+ defined in QVideoDeviceControl_iid.
+*/
+
+/*!
+ \macro QVideoDeviceControl_iid
+
+ \c com.nokia.Qt.VideoDeviceControl
+
+ Defines the interface name of the QVideoDeviceControl class.
+
+ \relates QVideoDeviceControl
+*/
+
+/*!
+ Constructs a video device control with the given \a parent.
+*/
+QVideoDeviceControl::QVideoDeviceControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video device control.
+*/
+QVideoDeviceControl::~QVideoDeviceControl()
+{
+}
+
+/*!
+ \fn QVideoDeviceControl::deviceCount() const
+
+ Returns the number of available video devices;
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceName(int index) const
+
+ Returns the name of the video device at \a index.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceDescription(int index) const
+
+ Returns a description of the video device at \a index.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::deviceIcon(int index) const
+
+ Returns an icon for the video device at \a index.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::defaultDevice() const
+
+ Returns the index of the default video device.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDevice() const
+
+ Returns the index of the selected video device.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::setSelectedDevice(int index)
+
+ Sets the selected video device \a index.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::devicesChanged()
+
+ Signals that the list of available video devices has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDeviceChanged(int index)
+
+ Signals that the selected video device \a index has changed.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoDeviceControl::selectedDeviceChanged(const QString &name)
+
+ Signals that the selected video device \a name has changed.
+ \since 1.0
+*/
+
+#include "moc_qvideodevicecontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qvideodevicecontrol.h b/src/multimedia/qvideodevicecontrol.h
new file mode 100644
index 000000000..6f44c4671
--- /dev/null
+++ b/src/multimedia/qvideodevicecontrol.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEODEVICECONTROL_H
+#define QVIDEODEVICECONTROL_H
+
+#include "qmediacontrol.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class Q_MULTIMEDIA_EXPORT QVideoDeviceControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QVideoDeviceControl();
+
+ virtual int deviceCount() const = 0;
+
+ virtual QString deviceName(int index) const = 0;
+ virtual QString deviceDescription(int index) const = 0;
+ virtual QIcon deviceIcon(int index) const = 0;
+
+ virtual int defaultDevice() const = 0;
+ virtual int selectedDevice() const = 0;
+
+public Q_SLOTS:
+ virtual void setSelectedDevice(int index) = 0;
+
+Q_SIGNALS:
+ void selectedDeviceChanged(int index);
+ void selectedDeviceChanged(const QString &deviceName);
+ void devicesChanged();
+
+protected:
+ QVideoDeviceControl(QObject *parent = 0);
+};
+
+#define QVideoDeviceControl_iid "com.nokia.Qt.QVideoDeviceControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoDeviceControl, QVideoDeviceControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVIDEODEVICECONTROL_H
diff --git a/src/multimedia/qvideoencodercontrol.cpp b/src/multimedia/qvideoencodercontrol.cpp
new file mode 100644
index 000000000..1551f2cf7
--- /dev/null
+++ b/src/multimedia/qvideoencodercontrol.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideoencodercontrol.h"
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoEncoderControl
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ \brief The QVideoEncoderControl class provides access to the settings
+ of a media service that performs video encoding.
+
+ If a QMediaService supports encoding video data it will implement
+ QVideoEncoderControl. This control provides information about the limits
+ of restricted video encoder options and allows the selection of a set of
+ video encoder settings as specified in a QVideoEncoderSettings object.
+
+ The functionality provided by this control is exposed to application code
+ through the QMediaRecorder class.
+
+ The interface name of QVideoEncoderControl is \c com.nokia.Qt.QVideoEncoderControl/1.0 as
+ defined in QVideoEncoderControl_iid.
+
+ \sa QMediaRecorder, QVideoEncoderSettings, QMediaService::requestControl()
+*/
+
+/*!
+ \macro QVideoEncoderControl_iid
+
+ \c com.nokia.Qt.QVideoEncoderControl/1.0
+
+ Defines the interface name of the QVideoEncoderControl class.
+
+ \relates QVideoEncoderControl
+*/
+
+/*!
+ Create a new video encoder control object with the given \a parent.
+*/
+QVideoEncoderControl::QVideoEncoderControl(QObject *parent)
+ :QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video encoder control.
+*/
+QVideoEncoderControl::~QVideoEncoderControl()
+{
+}
+
+/*!
+ \fn QVideoEncoderControl::supportedVideoCodecs() const
+
+ Returns the list of supported video codecs.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::videoCodecDescription(const QString &codec) const
+
+ Returns a description of a video \a codec.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::supportedEncodingOptions(const QString &codec) const
+
+ Returns a list of supported encoding options for a video \a codec.
+
+ The names and types of the options in the list is system dependent.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::encodingOption(const QString &codec, const QString &option) const
+
+ Returns the value of a video \a codec \a option.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::setEncodingOption(const QString &codec, const QString &option, const QVariant &value)
+
+ Sets the \a value of a \a codec specific \a option.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
+ bool *continuous = 0) const
+
+ Returns a list of supported resolutions.
+
+ If non null video \a settings parameter is passed,
+ the returned list is reduced to resolution supported with partial settings like
+ \l {QVideoEncoderSettings::setCodec()}{video codec} or
+ \l {QVideoEncoderSettings::setFrameRate()}{frame rate} applied.
+
+ If the encoder supports arbitrary resolutions within the supported resolutions range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+
+ \since 1.0
+ \sa QVideoEncoderSettings::resolution()
+*/
+
+/*!
+ \fn QVideoEncoderControl::supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
+ bool *continuous = 0) const
+
+ Returns a list of supported frame rates.
+
+ If non null video \a settings parameter is passed,
+ the returned list is reduced to frame rates supported with partial settings like
+ \l {QVideoEncoderSettings::setCodec()}{video codec} or
+ \l {QVideoEncoderSettings::setResolution()}{video resolution} applied.
+
+ If the encoder supports arbitrary frame rates within the supported range,
+ *\a continuous is set to true, otherwise *\a continuous is set to false.
+
+ \since 1.0
+ \sa QVideoEncoderSettings::frameRate()
+*/
+
+/*!
+ \fn QVideoEncoderControl::videoSettings() const
+
+ Returns the video encoder settings.
+
+ The returned value may be different tha passed to QVideoEncoderControl::setVideoSettings()
+ if the settings contains the default or undefined parameters.
+ In this case if the undefined parameters are already resolved, they should be returned.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoEncoderControl::setVideoSettings(const QVideoEncoderSettings &settings)
+
+ Sets the selected video encoder \a settings.
+ \since 1.0
+*/
+
+#include "moc_qvideoencodercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qvideoencodercontrol.h b/src/multimedia/qvideoencodercontrol.h
new file mode 100644
index 000000000..343af8039
--- /dev/null
+++ b/src/multimedia/qvideoencodercontrol.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEOENCODERCONTROL_H
+#define QVIDEOENCODERCONTROL_H
+
+#include "qmediacontrol.h"
+#include "qmediarecorder.h"
+
+#include <QtCore/qpair.h>
+#include <QtCore/qsize.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QByteArray;
+class QStringList;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QVideoEncoderControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ virtual ~QVideoEncoderControl();
+
+ virtual QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings,
+ bool *continuous = 0) const = 0;
+
+ virtual QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings,
+ bool *continuous = 0) const = 0;
+
+ virtual QStringList supportedVideoCodecs() const = 0;
+ virtual QString videoCodecDescription(const QString &codecName) const = 0;
+
+ virtual QVideoEncoderSettings videoSettings() const = 0;
+ virtual void setVideoSettings(const QVideoEncoderSettings &settings) = 0;
+
+ virtual QStringList supportedEncodingOptions(const QString &codec) const = 0;
+ virtual QVariant encodingOption(const QString &codec, const QString &name) const = 0;
+ virtual void setEncodingOption(const QString &codec, const QString &name, const QVariant &value) = 0;
+
+protected:
+ QVideoEncoderControl(QObject *parent = 0);
+};
+
+#define QVideoEncoderControl_iid "com.nokia.Qt.QVideoEncoderControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoEncoderControl, QVideoEncoderControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/qvideorenderercontrol.cpp b/src/multimedia/qvideorenderercontrol.cpp
new file mode 100644
index 000000000..99142261a
--- /dev/null
+++ b/src/multimedia/qvideorenderercontrol.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideorenderercontrol.h"
+
+#include "qmediacontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVideoRendererControl
+
+
+ \brief The QVideoRendererControl class provides a control for rendering
+ to a video surface.
+
+ \inmodule QtMultimedia
+ \ingroup multimedia-serv
+ \since 1.0
+
+ Using the surface() property of QVideoRendererControl a
+ QAbstractVideoSurface may be set as the video render target of a
+ QMediaService.
+
+ \snippet doc/src/snippets/multimedia-snippets/video.cpp Video renderer control
+
+ QVideoRendererControl is one of a number of possible video output controls.
+
+ The interface name of QVideoRendererControl is \c com.nokia.Qt.QVideoRendererControl/1.0 as
+ defined in QVideoRendererControl_iid.
+
+ \sa QMediaService::requestControl(), QVideoWidget
+*/
+
+/*!
+ \macro QVideoRendererControl_iid
+
+ \c com.nokia.Qt.QVideoRendererControl/1.0
+
+ Defines the interface name of the QVideoRendererControl class.
+
+ \relates QVideoRendererControl
+*/
+
+/*!
+ Constructs a new video renderer media end point with the given \a parent.
+*/
+QVideoRendererControl::QVideoRendererControl(QObject *parent)
+ : QMediaControl(parent)
+{
+}
+
+/*!
+ Destroys a video renderer media end point.
+*/
+QVideoRendererControl::~QVideoRendererControl()
+{
+}
+
+/*!
+ \fn QVideoRendererControl::surface() const
+
+ Returns the surface a video producer renders to.
+ \since 1.0
+*/
+
+/*!
+ \fn QVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+
+ Sets the \a surface a video producer renders to.
+ \since 1.0
+*/
+
+#include "moc_qvideorenderercontrol.cpp"
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qvideorenderercontrol.h b/src/multimedia/qvideorenderercontrol.h
new file mode 100644
index 000000000..b3a70837c
--- /dev/null
+++ b/src/multimedia/qvideorenderercontrol.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEORENDERERCONTROL_H
+#define QVIDEORENDERERCONTROL_H
+
+#include "qmediacontrol.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QAbstractVideoSurface;
+QT_END_NAMESPACE
+
+QT_BEGIN_NAMESPACE
+
+
+class Q_MULTIMEDIA_EXPORT QVideoRendererControl : public QMediaControl
+{
+ Q_OBJECT
+
+public:
+ ~QVideoRendererControl();
+
+ virtual QAbstractVideoSurface *surface() const = 0;
+ virtual void setSurface(QAbstractVideoSurface *surface) = 0;
+
+protected:
+ QVideoRendererControl(QObject *parent = 0);
+};
+
+#define QVideoRendererControl_iid "com.nokia.Qt.QVideoRendererControl/1.0"
+Q_MEDIA_DECLARE_CONTROL(QVideoRendererControl, QVideoRendererControl_iid)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QVIDEORENDERERCONTROL_H
diff --git a/src/multimedia/qvideosurfaceoutput.cpp b/src/multimedia/qvideosurfaceoutput.cpp
new file mode 100644
index 000000000..cdbec5596
--- /dev/null
+++ b/src/multimedia/qvideosurfaceoutput.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideosurfaceoutput_p.h"
+
+#include <qabstractvideosurface.h>
+#include <qmediaservice.h>
+#include <qvideorenderercontrol.h>
+
+
+QVideoSurfaceOutput::QVideoSurfaceOutput(QObject*parent)
+ : QObject(parent)
+{
+}
+
+QVideoSurfaceOutput::~QVideoSurfaceOutput()
+{
+ if (m_control) {
+ m_control.data()->setSurface(0);
+ m_service.data()->releaseControl(m_control.data());
+ }
+}
+
+QMediaObject *QVideoSurfaceOutput::mediaObject() const
+{
+ return m_object.data();
+}
+
+void QVideoSurfaceOutput::setVideoSurface(QAbstractVideoSurface *surface)
+{
+ m_surface = surface;
+
+ if (m_control)
+ m_control.data()->setSurface(surface);
+}
+
+bool QVideoSurfaceOutput::setMediaObject(QMediaObject *object)
+{
+ if (m_control) {
+ m_control.data()->setSurface(0);
+ m_service.data()->releaseControl(m_control.data());
+ }
+ m_control.clear();
+ m_service.clear();
+ m_object.clear();
+
+ if (object) {
+ if (QMediaService *service = object->service()) {
+ if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) {
+ if ((m_control = qobject_cast<QVideoRendererControl *>(control))) {
+ m_service = service;
+ m_object = object;
+ m_control.data()->setSurface(m_surface.data());
+
+ return true;
+ }
+ service->releaseControl(control);
+ }
+ }
+ }
+ return false;
+}
diff --git a/src/multimedia/qvideosurfaceoutput_p.h b/src/multimedia/qvideosurfaceoutput_p.h
new file mode 100644
index 000000000..76ec5e84d
--- /dev/null
+++ b/src/multimedia/qvideosurfaceoutput_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEOSURFACEOUTPUT_P_H
+#define QVIDEOSURFACEOUTPUT_P_H
+
+#include <qmediabindableinterface.h>
+
+#include <QtCore/qsharedpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoSurface;
+class QVideoRendererControl;
+
+class QVideoSurfaceOutput : public QObject, public QMediaBindableInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaBindableInterface)
+public:
+ QVideoSurfaceOutput(QObject*parent = 0);
+ ~QVideoSurfaceOutput();
+
+ QMediaObject *mediaObject() const;
+
+ void setVideoSurface(QAbstractVideoSurface *surface);
+
+protected:
+ bool setMediaObject(QMediaObject *object);
+
+private:
+ QWeakPointer<QAbstractVideoSurface> m_surface;
+ QWeakPointer<QVideoRendererControl> m_control;
+ QWeakPointer<QMediaService> m_service;
+ QWeakPointer<QMediaObject> m_object;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp
new file mode 100644
index 000000000..6480bc850
--- /dev/null
+++ b/src/multimedia/video/qabstractvideobuffer.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractvideobuffer_p.h"
+
+#include <qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractVideoBuffer
+ \brief The QAbstractVideoBuffer class is an abstraction for video data.
+ \since 1.0
+ \inmodule QtMultimedia
+
+ The QVideoFrame class makes use of a QAbstractVideoBuffer internally to reference a buffer of
+ video data. Creating a subclass of QAbstractVideoBuffer will allow you to construct video
+ frames from preallocated or static buffers.
+
+ The contents of a buffer can be accessed by mapping the buffer to memory using the map()
+ function which returns a pointer to memory containing the contents of the the video buffer.
+ The memory returned by map() is released by calling the unmap() function.
+
+ The handle() of a buffer may also be used to manipulate its contents using type specific APIs.
+ The type of a buffer's handle is given by the handleType() function.
+
+ \sa QVideoFrame
+*/
+
+/*!
+ \enum QAbstractVideoBuffer::HandleType
+
+ Identifies the type of a video buffers handle.
+
+ \value NoHandle The buffer has no handle, its data can only be accessed by mapping the buffer.
+ \value GLTextureHandle The handle of the buffer is an OpenGL texture ID.
+ \value XvShmImageHandle The handle contains pointer to shared memory XVideo image.
+ \value CoreImageHandle The handle contains pointer to Mac OS X CIImage.
+ \value QPixmapHandle The handle of the buffer is a QPixmap.
+ \value UserHandle Start value for user defined handle types.
+
+ \sa handleType()
+*/
+
+/*!
+ \enum QAbstractVideoBuffer::MapMode
+
+ Enumerates how a video buffer's data is mapped to memory.
+
+ \value NotMapped The video buffer has is not mapped to memory.
+ \value ReadOnly The mapped memory is populated with data from the video buffer when mapped, but
+ the content of the mapped memory may be discarded when unmapped.
+ \value WriteOnly The mapped memory is uninitialized when mapped, and the content will be used to
+ populate the video buffer when unmapped.
+ \value ReadWrite The mapped memory is populated with data from the video buffer, and the
+ video buffer is repopulated with the content of the mapped memory.
+
+ \sa mapMode(), map()
+*/
+
+/*!
+ Constructs an abstract video buffer of the given \a type.
+*/
+QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type)
+ : d_ptr(new QAbstractVideoBufferPrivate)
+{
+ Q_D(QAbstractVideoBuffer);
+
+ d->handleType = type;
+}
+
+/*!
+ \internal
+*/
+QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type)
+ : d_ptr(&dd)
+{
+ Q_D(QAbstractVideoBuffer);
+
+ d->handleType = type;
+}
+
+/*!
+ Destroys an abstract video buffer.
+*/
+QAbstractVideoBuffer::~QAbstractVideoBuffer()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns the type of a video buffer's handle.
+
+ \since 1.0
+ \sa handle()
+*/
+QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
+{
+ return d_func()->handleType;
+}
+
+/*!
+ \fn QAbstractVideoBuffer::mapMode() const
+
+ Returns the mode a video buffer is mapped in.
+
+ \since 1.0
+ \sa map()
+*/
+
+/*!
+ \fn QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+
+ Maps the contents of a video buffer to memory.
+
+ The map \a mode indicates whether the contents of the mapped memory should be read from and/or
+ written to the buffer. If the map mode includes the QAbstractVideoBuffer::ReadOnly flag the
+ mapped memory will be populated with the content of the video buffer when mapped. If the map
+ mode includes the QAbstractVideoBuffer::WriteOnly flag the content of the mapped memory will be
+ persisted in the buffer when unmapped.
+
+ When access to the data is no longer needed be sure to call the unmap() function to release the
+ mapped memory.
+
+ Returns a pointer to the mapped memory region, or a null pointer if the mapping failed. The
+ size in bytes of the mapped memory region is returned in \a numBytes, and the line stride in \a
+ bytesPerLine.
+
+ When access to the data is no longer needed be sure to unmap() the buffer.
+
+ \note Writing to memory that is mapped as read-only is undefined, and may result in changes
+ to shared data.
+
+ \since 1.0
+ \sa unmap(), mapMode()
+*/
+
+/*!
+ \fn QAbstractVideoBuffer::unmap()
+
+ Releases the memory mapped by the map() function
+
+ If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the QAbstractVideoBuffer::WriteOnly
+ flag this will persist the current content of the mapped memory to the video frame.
+
+ \since 1.0
+ \sa map()
+*/
+
+/*!
+ Returns a type specific handle to the data buffer.
+
+ The type of the handle is given by handleType() function.
+
+ \since 1.0
+ \sa handleType()
+*/
+QVariant QAbstractVideoBuffer::handle() const
+{
+ return QVariant();
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h
new file mode 100644
index 000000000..2c66dfd65
--- /dev/null
+++ b/src/multimedia/video/qabstractvideobuffer.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTVIDEOBUFFER_H
+#define QABSTRACTVIDEOBUFFER_H
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QVariant;
+
+class QAbstractVideoBufferPrivate;
+
+class Q_MULTIMEDIA_EXPORT QAbstractVideoBuffer
+{
+public:
+ enum HandleType
+ {
+ NoHandle,
+ GLTextureHandle,
+ XvShmImageHandle,
+ CoreImageHandle,
+ QPixmapHandle,
+ UserHandle = 1000
+ };
+
+ enum MapMode
+ {
+ NotMapped = 0x00,
+ ReadOnly = 0x01,
+ WriteOnly = 0x02,
+ ReadWrite = ReadOnly | WriteOnly
+ };
+
+ QAbstractVideoBuffer(HandleType type);
+ virtual ~QAbstractVideoBuffer();
+
+ HandleType handleType() const;
+
+ virtual MapMode mapMode() const = 0;
+
+ virtual uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) = 0;
+ virtual void unmap() = 0;
+
+ virtual QVariant handle() const;
+
+protected:
+ QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type);
+
+ QAbstractVideoBufferPrivate *d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractVideoBuffer)
+ Q_DISABLE_COPY(QAbstractVideoBuffer)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QAbstractVideoBuffer::HandleType)
+Q_DECLARE_METATYPE(QAbstractVideoBuffer::MapMode)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/video/qabstractvideobuffer_p.h b/src/multimedia/video/qabstractvideobuffer_p.h
new file mode 100644
index 000000000..b808e5d91
--- /dev/null
+++ b/src/multimedia/video/qabstractvideobuffer_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTVIDEOBUFFER_P_H
+#define QABSTRACTVIDEOBUFFER_P_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.
+//
+
+#include <QtCore/qshareddata.h>
+#include "qabstractvideobuffer.h"
+
+#include <qtmultimediadefs.h>
+#include <qtmedianamespace.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QAbstractVideoBufferPrivate
+{
+public:
+ QAbstractVideoBufferPrivate()
+ : handleType(QAbstractVideoBuffer::NoHandle)
+ {}
+
+ virtual ~QAbstractVideoBufferPrivate()
+ {}
+
+ QAbstractVideoBuffer::HandleType handleType;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/video/qabstractvideosurface.cpp b/src/multimedia/video/qabstractvideosurface.cpp
new file mode 100644
index 000000000..4d65d7eaa
--- /dev/null
+++ b/src/multimedia/video/qabstractvideosurface.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//TESTED_COMPONENT=src/multimedia
+
+#include "qabstractvideosurface.h"
+
+#include "qvideosurfaceformat.h"
+
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_METATYPE(QVideoSurfaceFormat)
+Q_DECLARE_METATYPE(QAbstractVideoSurface::Error)
+
+/*!
+ \class QAbstractVideoSurface
+ \brief The QAbstractVideoSurface class is a base class for video presentation surfaces.
+ \since 1.0
+ \inmodule QtMultimedia
+
+ A video surface presents a continuous stream of identically formatted frames, where the format
+ of each frame is compatible with a stream format supplied when starting a presentation.
+
+ The QAbstractVideoSurface class defines the standard interface that video producers use to
+ inter-operate with video presentation surfaces. It is not supposed to be instantiated directly.
+ Instead, you should subclass it to create new video surfaces.
+
+ A list of pixel formats a surface can present is given by the supportedPixelFormats() function,
+ and the isFormatSupported() function will test if a video surface format is supported. If a
+ format is not supported the nearestFormat() function may be able to suggest a similar format.
+ For example, if a surface supports fixed set of resolutions it may suggest the smallest
+ supported resolution that contains the proposed resolution.
+
+ The start() function takes a supported format and enables a video surface. Once started a
+ surface will begin displaying the frames it receives in the present() function. Surfaces may
+ hold a reference to the buffer of a presented video frame until a new frame is presented or
+ streaming is stopped. The stop() function will disable a surface and a release any video
+ buffers it holds references to.
+*/
+
+/*!
+ \enum QAbstractVideoSurface::Error
+ This enum describes the errors that may be returned by the error() function.
+
+ \value NoError No error occurred.
+ \value UnsupportedFormatError A video format was not supported.
+ \value IncorrectFormatError A video frame was not compatible with the format of the surface.
+ \value StoppedError The surface has not been started.
+ \value ResourceError The surface could not allocate some resource.
+*/
+
+/*!
+ Constructs a video surface with the given \a parent.
+*/
+QAbstractVideoSurface::QAbstractVideoSurface(QObject *parent)
+ : QObject(parent)
+{
+ setProperty("_q_surfaceFormat", QVariant::fromValue(QVideoSurfaceFormat()));
+ setProperty("_q_active", false);
+ setProperty("_q_error", QVariant::fromValue(QAbstractVideoSurface::NoError));
+ setProperty("_q_nativeResolution", QSize());
+}
+
+// XXX Qt5
+/*!
+ \internal
+
+ This is deprecated.
+
+ Since we need to build without access to Qt's private headers we can't reliably inherit
+ from QObjectPrivate. Binary compatibility means we can't remove this constructor or
+ add a d pointer to QAbstractVideoSurface.
+*/
+QAbstractVideoSurface::QAbstractVideoSurface(QAbstractVideoSurfacePrivate &, QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Destroys a video surface.
+*/
+QAbstractVideoSurface::~QAbstractVideoSurface()
+{
+}
+
+/*!
+ \fn QAbstractVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
+
+ Returns a list of pixel formats a video surface can present for a given handle \a type.
+
+ The pixel formats returned for the QAbstractVideoBuffer::NoHandle type are valid for any buffer
+ that can be mapped in read-only mode.
+
+ Types that are first in the list can be assumed to be faster to render.
+ \since 1.0
+*/
+
+/*!
+ Tests a video surface \a format to determine if a surface can accept it.
+
+ Returns true if the format is supported by the surface, and false otherwise.
+ \since 1.0
+*/
+bool QAbstractVideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const
+{
+ return supportedPixelFormats(format.handleType()).contains(format.pixelFormat());
+}
+
+/*!
+ Returns a supported video surface format that is similar to \a format.
+
+ A similar surface format is one that has the same \l {QVideoSurfaceFormat::pixelFormat()}{pixel
+ format} and \l {QVideoSurfaceFormat::handleType()}{handle type} but may differ in some of the other
+ properties. For example, if there are restrictions on the \l {QVideoSurfaceFormat::frameSize()}
+ {frame sizes} a video surface can accept it may suggest a format with a larger frame size and
+ a \l {QVideoSurfaceFormat::viewport()}{viewport} the size of the original frame size.
+
+ If the format is already supported it will be returned unchanged, or if there is no similar
+ supported format an invalid format will be returned.
+ \since 1.0
+*/
+QVideoSurfaceFormat QAbstractVideoSurface::nearestFormat(const QVideoSurfaceFormat &format) const
+{
+ return isFormatSupported(format)
+ ? format
+ : QVideoSurfaceFormat();
+}
+
+/*!
+ \fn QAbstractVideoSurface::supportedFormatsChanged()
+
+ Signals that the set of formats supported by a video surface has changed.
+
+ \since 1.0
+ \sa supportedPixelFormats(), isFormatSupported()
+*/
+
+/*!
+ Returns the format of a video surface.
+ \since 1.0
+*/
+QVideoSurfaceFormat QAbstractVideoSurface::surfaceFormat() const
+{
+ return property("_q_format").value<QVideoSurfaceFormat>();
+}
+
+/*!
+ \fn QAbstractVideoSurface::surfaceFormatChanged(const QVideoSurfaceFormat &format)
+
+ Signals that the configured \a format of a video surface has changed.
+
+ \since 1.0
+ \sa surfaceFormat(), start()
+*/
+
+/*!
+ Starts a video surface presenting \a format frames.
+
+ Returns true if the surface was started, and false if an error occurred.
+
+ \since 1.0
+ \sa isActive(), stop()
+*/
+bool QAbstractVideoSurface::start(const QVideoSurfaceFormat &format)
+{
+ bool wasActive = property("_q_active").toBool();
+
+ setProperty("_q_active", true);
+ setProperty("_q_format", QVariant::fromValue(format));
+ setProperty("_q_error", QVariant::fromValue(NoError));
+
+ emit surfaceFormatChanged(format);
+
+ if (!wasActive)
+ emit activeChanged(true);
+
+ return true;
+}
+
+/*!
+ Stops a video surface presenting frames and releases any resources acquired in start().
+
+ \since 1.0
+ \sa isActive(), start()
+*/
+void QAbstractVideoSurface::stop()
+{
+ if (property("_q_active").toBool()) {
+ setProperty("_q_format", QVariant::fromValue(QVideoSurfaceFormat()));
+ setProperty("_q_active", false);
+
+ emit activeChanged(false);
+ emit surfaceFormatChanged(surfaceFormat());
+ }
+}
+
+/*!
+ Indicates whether a video surface has been started.
+
+ Returns true if the surface has been started, and false otherwise.
+ \since 1.0
+*/
+bool QAbstractVideoSurface::isActive() const
+{
+ return property("_q_active").toBool();
+}
+
+/*!
+ \fn QAbstractVideoSurface::activeChanged(bool active)
+
+ Signals that the \a active state of a video surface has changed.
+
+ \since 1.0
+ \sa isActive(), start(), stop()
+*/
+
+/*!
+ \fn QAbstractVideoSurface::present(const QVideoFrame &frame)
+
+ Presents a video \a frame.
+
+ Returns true if the frame was presented, and false if an error occurred.
+
+ Not all surfaces will block until the presentation of a frame has completed. Calling present()
+ on a non-blocking surface may fail if called before the presentation of a previous frame has
+ completed. In such cases the surface may not return to a ready state until it has had an
+ opportunity to process events.
+
+ If present() fails for any other reason the surface will immediately enter the stopped state
+ and an error() value will be set.
+
+ A video surface must be in the started state for present() to succeed, and the format of the
+ video frame must be compatible with the current video surface format.
+
+ \since 1.0
+ \sa error()
+*/
+
+/*!
+ Returns the last error that occurred.
+
+ If a surface fails to start(), or stops unexpectedly this function can be called to discover
+ what error occurred.
+ \since 1.0
+*/
+
+QAbstractVideoSurface::Error QAbstractVideoSurface::error() const
+{
+ return property("_q_error").value<QAbstractVideoSurface::Error>();
+}
+
+/*!
+ Sets the value of error() to \a error.
+ \since 1.0
+*/
+void QAbstractVideoSurface::setError(Error error)
+{
+ setProperty("_q_error", QVariant::fromValue(error));
+}
+
+/*!
+ \property QAbstractVideoSurface::nativeResolution
+
+ The native resolution of video surface.
+ This is the resolution of video frames the surface
+ can render with optimal quality and/or performance.
+
+ The native resolution is not always known and can be changed during playback.
+ \since 1.1
+ */
+QSize QAbstractVideoSurface::nativeResolution() const
+{
+ return property("_q_nativeResolution").toSize();
+}
+
+/*!
+ Set the video surface native \a resolution.
+ \since 1.1
+ */
+void QAbstractVideoSurface::setNativeResolution(const QSize &resolution)
+{
+ const QSize nativeResolution = property("_q_nativeResolution").toSize();
+
+ if (nativeResolution != resolution) {
+ setProperty("_q_nativeResolution", resolution);
+
+ emit nativeResolutionChanged(resolution);
+ }
+}
+/*!
+ \fn QAbstractVideoSurface::nativeResolutionChanged(const QSize &resolution);
+
+ Signals the native \a resolution of video surface has changed.
+ \since 1.1
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qabstractvideosurface.cpp"
+
diff --git a/src/multimedia/video/qabstractvideosurface.h b/src/multimedia/video/qabstractvideosurface.h
new file mode 100644
index 000000000..37c4d385f
--- /dev/null
+++ b/src/multimedia/video/qabstractvideosurface.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTVIDEOSURFACE_H
+#define QABSTRACTVIDEOSURFACE_H
+
+#include <QtCore/qobject.h>
+#include <qvideoframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QRectF;
+class QVideoSurfaceFormat;
+
+class QAbstractVideoSurfacePrivate;
+
+class Q_MULTIMEDIA_EXPORT QAbstractVideoSurface : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QSize nativeResolution READ nativeResolution NOTIFY nativeResolutionChanged)
+public:
+ enum Error
+ {
+ NoError,
+ UnsupportedFormatError,
+ IncorrectFormatError,
+ StoppedError,
+ ResourceError
+ };
+
+ explicit QAbstractVideoSurface(QObject *parent = 0);
+ ~QAbstractVideoSurface();
+
+ virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const = 0;
+ virtual bool isFormatSupported(const QVideoSurfaceFormat &format) const;
+ virtual QVideoSurfaceFormat nearestFormat(const QVideoSurfaceFormat &format) const;
+
+ QVideoSurfaceFormat surfaceFormat() const;
+
+ QSize nativeResolution() const;
+
+ virtual bool start(const QVideoSurfaceFormat &format);
+ virtual void stop();
+
+ bool isActive() const;
+
+ virtual bool present(const QVideoFrame &frame) = 0;
+
+ Error error() const;
+
+Q_SIGNALS:
+ void activeChanged(bool active);
+ void surfaceFormatChanged(const QVideoSurfaceFormat &format);
+ void supportedFormatsChanged();
+ void nativeResolutionChanged(const QSize &);
+
+protected:
+ QAbstractVideoSurface(QAbstractVideoSurfacePrivate &dd, QObject *parent);
+
+ void setError(Error error);
+ void setNativeResolution(const QSize &resolution);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractVideoSurface)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/video/qimagevideobuffer.cpp b/src/multimedia/video/qimagevideobuffer.cpp
new file mode 100644
index 000000000..e16abc30b
--- /dev/null
+++ b/src/multimedia/video/qimagevideobuffer.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qimagevideobuffer_p.h"
+
+#include "qabstractvideobuffer_p.h"
+
+#include <qimage.h>
+#include <qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+class QImageVideoBufferPrivate : public QAbstractVideoBufferPrivate
+{
+public:
+ QImageVideoBufferPrivate()
+ : mapMode(QAbstractVideoBuffer::NotMapped)
+ {
+ }
+
+ QAbstractVideoBuffer::MapMode mapMode;
+ QImage image;
+};
+
+QImageVideoBuffer::QImageVideoBuffer(const QImage &image)
+ : QAbstractVideoBuffer(*new QImageVideoBufferPrivate, NoHandle)
+{
+ Q_D(QImageVideoBuffer);
+
+ d->image = image;
+}
+
+QImageVideoBuffer::~QImageVideoBuffer()
+{
+}
+
+QAbstractVideoBuffer::MapMode QImageVideoBuffer::mapMode() const
+{
+ return d_func()->mapMode;
+}
+
+uchar *QImageVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+{
+ Q_D(QImageVideoBuffer);
+
+ if (d->mapMode == NotMapped && d->image.bits() && mode != NotMapped) {
+ d->mapMode = mode;
+
+ if (numBytes)
+ *numBytes = d->image.byteCount();
+
+ if (bytesPerLine)
+ *bytesPerLine = d->image.bytesPerLine();
+
+ return d->image.bits();
+ } else {
+ return 0;
+ }
+}
+
+void QImageVideoBuffer::unmap()
+{
+ Q_D(QImageVideoBuffer);
+
+ d->mapMode = NotMapped;
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/video/qimagevideobuffer_p.h b/src/multimedia/video/qimagevideobuffer_p.h
new file mode 100644
index 000000000..dae952ed4
--- /dev/null
+++ b/src/multimedia/video/qimagevideobuffer_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QIMAGEVIDEOBUFFER_P_H
+#define QIMAGEVIDEOBUFFER_P_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.
+//
+
+#include <qabstractvideobuffer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QImage;
+
+class QImageVideoBufferPrivate;
+
+class Q_MULTIMEDIA_EXPORT QImageVideoBuffer : public QAbstractVideoBuffer
+{
+ Q_DECLARE_PRIVATE(QImageVideoBuffer)
+public:
+ QImageVideoBuffer(const QImage &image);
+ ~QImageVideoBuffer();
+
+ MapMode mapMode() const;
+
+ uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
+ void unmap();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/multimedia/video/qmemoryvideobuffer.cpp b/src/multimedia/video/qmemoryvideobuffer.cpp
new file mode 100644
index 000000000..d3516182a
--- /dev/null
+++ b/src/multimedia/video/qmemoryvideobuffer.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmemoryvideobuffer_p.h"
+
+#include "qabstractvideobuffer_p.h"
+#include <qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMemoryVideoBufferPrivate : public QAbstractVideoBufferPrivate
+{
+public:
+ QMemoryVideoBufferPrivate()
+ : bytesPerLine(0)
+ , mapMode(QAbstractVideoBuffer::NotMapped)
+ {
+ }
+
+ int bytesPerLine;
+ QAbstractVideoBuffer::MapMode mapMode;
+ QByteArray data;
+};
+
+/*!
+ \class QMemoryVideoBuffer
+ \brief The QMemoryVideoBuffer class provides a system memory allocated video data buffer.
+ \internal
+
+ QMemoryVideoBuffer is the default video buffer for allocating system memory. It may be used to
+ allocate memory for a QVideoFrame without implementing your own QAbstractVideoBuffer.
+*/
+
+/*!
+ Constructs a video buffer with an image stride of \a bytesPerLine from a byte \a array.
+*/
+QMemoryVideoBuffer::QMemoryVideoBuffer(const QByteArray &array, int bytesPerLine)
+ : QAbstractVideoBuffer(*new QMemoryVideoBufferPrivate, NoHandle)
+{
+ Q_D(QMemoryVideoBuffer);
+
+ d->data = array;
+ d->bytesPerLine = bytesPerLine;
+}
+
+/*!
+ Destroys a system memory allocated video buffer.
+*/
+QMemoryVideoBuffer::~QMemoryVideoBuffer()
+{
+}
+
+/*!
+ \reimp
+ \since 1.1
+*/
+QAbstractVideoBuffer::MapMode QMemoryVideoBuffer::mapMode() const
+{
+ return d_func()->mapMode;
+}
+
+/*!
+ \reimp
+ \since 1.1
+*/
+uchar *QMemoryVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+{
+ Q_D(QMemoryVideoBuffer);
+
+ if (d->mapMode == NotMapped && d->data.data() && mode != NotMapped) {
+ d->mapMode = mode;
+
+ if (numBytes)
+ *numBytes = d->data.size();
+
+ if (bytesPerLine)
+ *bytesPerLine = d->bytesPerLine;
+
+ return reinterpret_cast<uchar *>(d->data.data());
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ \reimp
+ \since 1.1
+*/
+void QMemoryVideoBuffer::unmap()
+{
+ d_func()->mapMode = NotMapped;
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/video/qmemoryvideobuffer_p.h b/src/multimedia/video/qmemoryvideobuffer_p.h
new file mode 100644
index 000000000..d5bc4e3c8
--- /dev/null
+++ b/src/multimedia/video/qmemoryvideobuffer_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEMORYVIDEOBUFFER_P_H
+#define QMEMORYVIDEOBUFFER_P_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_HEADER
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QMemoryVideoBufferPrivate;
+
+class Q_MULTIMEDIA_EXPORT QMemoryVideoBuffer : public QAbstractVideoBuffer
+{
+ Q_DECLARE_PRIVATE(QMemoryVideoBuffer)
+public:
+ QMemoryVideoBuffer(const QByteArray &data, int bytesPerLine);
+ ~QMemoryVideoBuffer();
+
+ MapMode mapMode() const;
+
+ uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
+ void unmap();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp
new file mode 100644
index 000000000..eaef644e9
--- /dev/null
+++ b/src/multimedia/video/qvideoframe.cpp
@@ -0,0 +1,776 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideoframe.h"
+
+#include "qimagevideobuffer_p.h"
+#include "qmemoryvideobuffer_p.h"
+
+#include <qimage.h>
+#include <qpair.h>
+#include <qsize.h>
+#include <qvariant.h>
+#include <qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace
+{
+class QVideoFramePrivateRegisterMetaTypes
+{
+public:
+ QVideoFramePrivateRegisterMetaTypes()
+ {
+ qRegisterMetaType<QVideoFrame::PixelFormat>("QVideoFrame::PixelFormat");
+ }
+} _registerMetaTypes;
+}
+
+
+class QVideoFramePrivate : public QSharedData
+{
+public:
+ QVideoFramePrivate()
+ : startTime(-1)
+ , endTime(-1)
+ , data(0)
+ , mappedBytes(0)
+ , bytesPerLine(0)
+ , pixelFormat(QVideoFrame::Format_Invalid)
+ , fieldType(QVideoFrame::ProgressiveFrame)
+ , buffer(0)
+ {
+ }
+
+ QVideoFramePrivate(const QSize &size, QVideoFrame::PixelFormat format)
+ : size(size)
+ , startTime(-1)
+ , endTime(-1)
+ , data(0)
+ , mappedBytes(0)
+ , bytesPerLine(0)
+ , pixelFormat(format)
+ , fieldType(QVideoFrame::ProgressiveFrame)
+ , buffer(0)
+ {
+ }
+
+ ~QVideoFramePrivate()
+ {
+ delete buffer;
+ }
+
+ QSize size;
+ qint64 startTime;
+ qint64 endTime;
+ uchar *data;
+ int mappedBytes;
+ int bytesPerLine;
+ QVideoFrame::PixelFormat pixelFormat;
+ QVideoFrame::FieldType fieldType;
+ QAbstractVideoBuffer *buffer;
+
+private:
+ Q_DISABLE_COPY(QVideoFramePrivate)
+};
+
+/*!
+ \class QVideoFrame
+ \brief The QVideoFrame class provides a representation of a frame of video data.
+ \since 1.0
+ \inmodule QtMultimedia
+
+ A QVideoFrame encapsulates the data of a video frame, and information about the frame.
+
+ The contents of a video frame can be mapped to memory using the map() function. While
+ mapped, the video data can accessed using the bits() function, which returns a pointer to a
+ buffer. The total size of this buffer is given by the mappedBytes() function, and the size of each line is given
+ by bytesPerLine(). The return value of the handle() function may be used to access frame data
+ using the internal buffer's native APIs.
+
+ The video data in a QVideoFrame is encapsulated in a QAbstractVideoBuffer. A QVideoFrame
+ may be constructed from any buffer type by subclassing the QAbstractVideoBuffer class.
+
+ \note QVideoFrame is explicitly shared, any change made to video frame will also apply to any
+ copies.
+*/
+
+/*!
+ \enum QVideoFrame::PixelFormat
+
+ Enumerates video data types.
+
+ \value Format_Invalid
+ The frame is invalid.
+
+ \value Format_ARGB32
+ The frame is stored using a 32-bit ARGB format (0xAARRGGBB). This is equivalent to
+ QImage::Format_ARGB32.
+
+ \value Format_ARGB32_Premultiplied
+ The frame stored using a premultiplied 32-bit ARGB format (0xAARRGGBB). This is equivalent
+ to QImage::Format_ARGB32_Premultiplied.
+
+ \value Format_RGB32
+ The frame stored using a 32-bit RGB format (0xffRRGGBB). This is equivalent to
+ QImage::Format_RGB32
+
+ \value Format_RGB24
+ The frame is stored using a 24-bit RGB format (8-8-8). This is equivalent to
+ QImage::Format_RGB888
+
+ \value Format_RGB565
+ The frame is stored using a 16-bit RGB format (5-6-5). This is equivalent to
+ QImage::Format_RGB16.
+
+ \value Format_RGB555
+ The frame is stored using a 16-bit RGB format (5-5-5). This is equivalent to
+ QImage::Format_RGB555.
+
+ \value Format_ARGB8565_Premultiplied
+ The frame is stored using a 24-bit premultiplied ARGB format (8-6-6-5).
+
+ \value Format_BGRA32
+ The frame is stored using a 32-bit ARGB format (0xBBGGRRAA).
+
+ \value Format_BGRA32_Premultiplied
+ The frame is stored using a premultiplied 32bit BGRA format.
+
+ \value Format_BGR32
+ The frame is stored using a 32-bit BGR format (0xBBGGRRff).
+
+ \value Format_BGR24
+ The frame is stored using a 24-bit BGR format (0xBBGGRR).
+
+ \value Format_BGR565
+ The frame is stored using a 16-bit BGR format (5-6-5).
+
+ \value Format_BGR555
+ The frame is stored using a 16-bit BGR format (5-5-5).
+
+ \value Format_BGRA5658_Premultiplied
+ The frame is stored using a 24-bit premultiplied BGRA format (5-6-5-8).
+
+ \value Format_AYUV444
+ The frame is stored using a packed 32-bit AYUV format (0xAAYYUUVV).
+
+ \value Format_AYUV444_Premultiplied
+ The frame is stored using a packed premultiplied 32-bit AYUV format (0xAAYYUUVV).
+
+ \value Format_YUV444
+ The frame is stored using a 24-bit packed YUV format (8-8-8).
+
+ \value Format_YUV420P
+ The frame is stored using an 8-bit per component planar YUV format with the U and V planes
+ horizontally and vertically sub-sampled, i.e. the height and width of the U and V planes are
+ half that of the Y plane.
+
+ \value Format_YV12
+ The frame is stored using an 8-bit per component planar YVU format with the V and U planes
+ horizontally and vertically sub-sampled, i.e. the height and width of the V and U planes are
+ half that of the Y plane.
+
+ \value Format_UYVY
+ The frame is stored using an 8-bit per component packed YUV format with the U and V planes
+ horizontally sub-sampled (U-Y-V-Y), i.e. two horizontally adjacent pixels are stored as a 32-bit
+ macropixel which has a Y value for each pixel and common U and V values.
+
+ \value Format_YUYV
+ The frame is stored using an 8-bit per component packed YUV format with the U and V planes
+ horizontally sub-sampled (Y-U-Y-V), i.e. two horizontally adjacent pixels are stored as a 32-bit
+ macropixel which has a Y value for each pixel and common U and V values.
+
+ \value Format_NV12
+ The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y)
+ followed by a horizontally and vertically sub-sampled, packed UV plane (U-V).
+
+ \value Format_NV21
+ The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y)
+ followed by a horizontally and vertically sub-sampled, packed VU plane (V-U).
+
+ \value Format_IMC1
+ The frame is stored using an 8-bit per component planar YUV format with the U and V planes
+ horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except
+ that the bytes per line of the U and V planes are padded out to the same stride as the Y plane.
+
+ \value Format_IMC2
+ The frame is stored using an 8-bit per component planar YUV format with the U and V planes
+ horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except
+ that the lines of the U and V planes are interleaved, i.e. each line of U data is followed by a
+ line of V data creating a single line of the same stride as the Y data.
+
+ \value Format_IMC3
+ The frame is stored using an 8-bit per component planar YVU format with the V and U planes
+ horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that
+ the bytes per line of the V and U planes are padded out to the same stride as the Y plane.
+
+ \value Format_IMC4
+ The frame is stored using an 8-bit per component planar YVU format with the V and U planes
+ horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that
+ the lines of the V and U planes are interleaved, i.e. each line of V data is followed by a line
+ of U data creating a single line of the same stride as the Y data.
+
+ \value Format_Y8
+ The frame is stored using an 8-bit greyscale format.
+
+ \value Format_Y16
+ The frame is stored using a 16-bit linear greyscale format. Little endian.
+
+ \value Format_Jpeg
+ The frame is stored in compressed Jpeg format.
+
+ \value Format_CameraRaw
+ The frame is stored using a device specific camera raw format.
+
+ \value Format_AdobeDng
+ The frame is stored using raw Adobe Digital Negative (DNG) format.
+
+ \value Format_User
+ Start value for user defined pixel formats.
+*/
+
+/*!
+ \enum QVideoFrame::FieldType
+
+ Specifies the field an interlaced video frame belongs to.
+
+ \value ProgressiveFrame The frame is not interlaced.
+ \value TopField The frame contains a top field.
+ \value BottomField The frame contains a bottom field.
+ \value InterlacedFrame The frame contains a merged top and bottom field.
+*/
+
+/*!
+ Constructs a null video frame.
+*/
+QVideoFrame::QVideoFrame()
+ : d(new QVideoFramePrivate)
+{
+}
+
+/*!
+ Constructs a video frame from a \a buffer with the given pixel \a format and \a size in pixels.
+
+ \note This doesn't increment the reference count of the video buffer.
+ \since 1.0
+*/
+QVideoFrame::QVideoFrame(
+ QAbstractVideoBuffer *buffer, const QSize &size, PixelFormat format)
+ : d(new QVideoFramePrivate(size, format))
+{
+ d->buffer = buffer;
+}
+
+/*!
+ Constructs a video frame of the given pixel \a format and \a size in pixels.
+
+ The \a bytesPerLine (stride) is the length of each scan line in bytes, and \a bytes is the total
+ number of bytes that must be allocated for the frame.
+ \since 1.0
+*/
+QVideoFrame::QVideoFrame(int bytes, const QSize &size, int bytesPerLine, PixelFormat format)
+ : d(new QVideoFramePrivate(size, format))
+{
+ if (bytes > 0) {
+ QByteArray data;
+ data.resize(bytes);
+
+ // Check the memory was successfully allocated.
+ if (!data.isEmpty())
+ d->buffer = new QMemoryVideoBuffer(data, bytesPerLine);
+ }
+}
+
+/*!
+ Constructs a video frame from an \a image.
+
+ \note This will construct an invalid video frame if there is no frame type equivalent to the
+ image format.
+
+ \since 1.0
+ \sa pixelFormatFromImageFormat()
+*/
+QVideoFrame::QVideoFrame(const QImage &image)
+ : d(new QVideoFramePrivate(
+ image.size(), pixelFormatFromImageFormat(image.format())))
+{
+ if (d->pixelFormat != Format_Invalid)
+ d->buffer = new QImageVideoBuffer(image);
+}
+
+/*!
+ Constructs a copy of \a other.
+
+ \since 1.0
+*/
+QVideoFrame::QVideoFrame(const QVideoFrame &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Assigns the contents of \a other to a video frame.
+ \since 1.0
+*/
+QVideoFrame &QVideoFrame::operator =(const QVideoFrame &other)
+{
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ Destroys a video frame.
+*/
+QVideoFrame::~QVideoFrame()
+{
+}
+
+/*!
+ Identifies whether a video frame is valid.
+
+ An invalid frame has no video buffer associated with it.
+
+ Returns true if the frame is valid, and false if it is not.
+ \since 1.0
+*/
+bool QVideoFrame::isValid() const
+{
+ return d->buffer != 0;
+}
+
+/*!
+ Returns the color format of a video frame.
+ \since 1.0
+*/
+QVideoFrame::PixelFormat QVideoFrame::pixelFormat() const
+{
+ return d->pixelFormat;
+}
+
+/*!
+ Returns the type of a video frame's handle.
+
+ \since 1.0
+*/
+QAbstractVideoBuffer::HandleType QVideoFrame::handleType() const
+{
+ return d->buffer ? d->buffer->handleType() : QAbstractVideoBuffer::NoHandle;
+}
+
+/*!
+ Returns the dimensions of a video frame.
+ \since 1.0
+*/
+QSize QVideoFrame::size() const
+{
+ return d->size;
+}
+
+/*!
+ Returns the width of a video frame.
+ \since 1.0
+*/
+int QVideoFrame::width() const
+{
+ return d->size.width();
+}
+
+/*!
+ Returns the height of a video frame.
+ \since 1.0
+*/
+int QVideoFrame::height() const
+{
+ return d->size.height();
+}
+
+/*!
+ Returns the field an interlaced video frame belongs to.
+
+ If the video is not interlaced this will return WholeFrame.
+ \since 1.0
+*/
+QVideoFrame::FieldType QVideoFrame::fieldType() const
+{
+ return d->fieldType;
+}
+
+/*!
+ Sets the \a field an interlaced video frame belongs to.
+ \since 1.0
+*/
+void QVideoFrame::setFieldType(QVideoFrame::FieldType field)
+{
+ d->fieldType = field;
+}
+
+/*!
+ Identifies if a video frame's contents are currently mapped to system memory.
+
+ This is a convenience function which checks that the \l {QAbstractVideoBuffer::MapMode}{MapMode}
+ of the frame is not equal to QAbstractVideoBuffer::NotMapped.
+
+ Returns true if the contents of the video frame are mapped to system memory, and false
+ otherwise.
+
+ \since 1.0
+ \sa mapMode(), QAbstractVideoBuffer::MapMode
+*/
+
+bool QVideoFrame::isMapped() const
+{
+ return d->buffer != 0 && d->buffer->mapMode() != QAbstractVideoBuffer::NotMapped;
+}
+
+/*!
+ Identifies if the mapped contents of a video frame will be persisted when the frame is unmapped.
+
+ This is a convenience function which checks if the \l {QAbstractVideoBuffer::MapMode}{MapMode}
+ contains the QAbstractVideoBuffer::WriteOnly flag.
+
+ Returns true if the video frame will be updated when unmapped, and false otherwise.
+
+ \note The result of altering the data of a frame that is mapped in read-only mode is undefined.
+ Depending on the buffer implementation the changes may be persisted, or worse alter a shared
+ buffer.
+
+ \since 1.0
+ \sa mapMode(), QAbstractVideoBuffer::MapMode
+*/
+bool QVideoFrame::isWritable() const
+{
+ return d->buffer != 0 && (d->buffer->mapMode() & QAbstractVideoBuffer::WriteOnly);
+}
+
+/*!
+ Identifies if the mapped contents of a video frame were read from the frame when it was mapped.
+
+ This is a convenience function which checks if the \l {QAbstractVideoBuffer::MapMode}{MapMode}
+ contains the QAbstractVideoBuffer::WriteOnly flag.
+
+ Returns true if the contents of the mapped memory were read from the video frame, and false
+ otherwise.
+
+ \since 1.0
+ \sa mapMode(), QAbstractVideoBuffer::MapMode
+*/
+bool QVideoFrame::isReadable() const
+{
+ return d->buffer != 0 && (d->buffer->mapMode() & QAbstractVideoBuffer::ReadOnly);
+}
+
+/*!
+ Returns the mode a video frame was mapped to system memory in.
+
+ \since 1.0
+ \sa map(), QAbstractVideoBuffer::MapMode
+*/
+QAbstractVideoBuffer::MapMode QVideoFrame::mapMode() const
+{
+ return d->buffer != 0 ? d->buffer->mapMode() : QAbstractVideoBuffer::NotMapped;
+}
+
+/*!
+ Maps the contents of a video frame to memory.
+
+ The map \a mode indicates whether the contents of the mapped memory should be read from and/or
+ written to the frame. If the map mode includes the QAbstractVideoBuffer::ReadOnly flag the
+ mapped memory will be populated with the content of the video frame when mapped. If the map
+ mode inclues the QAbstractVideoBuffer::WriteOnly flag the content of the mapped memory will be
+ persisted in the frame when unmapped.
+
+ While mapped the contents of a video frame can be accessed directly through the pointer returned
+ by the bits() function.
+
+ When access to the data is no longer needed be sure to call the unmap() function to release the
+ mapped memory and possibly update the video frame contents.
+
+ Returns true if the buffer was mapped to memory in the given \a mode and false otherwise.
+
+ \since 1.0
+ \sa unmap(), mapMode(), bits()
+*/
+bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
+{
+ if (d->buffer != 0 && d->data == 0) {
+ Q_ASSERT(d->bytesPerLine == 0);
+ Q_ASSERT(d->mappedBytes == 0);
+
+ d->data = d->buffer->map(mode, &d->mappedBytes, &d->bytesPerLine);
+
+ return d->data != 0;
+ }
+
+ return false;
+}
+
+/*!
+ Releases the memory mapped by the map() function.
+
+ If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the QAbstractVideoBuffer::WriteOnly
+ flag this will persist the current content of the mapped memory to the video frame.
+
+ \since 1.0
+ \sa map()
+*/
+void QVideoFrame::unmap()
+{
+ if (d->data != 0) {
+ d->mappedBytes = 0;
+ d->bytesPerLine = 0;
+ d->data = 0;
+
+ d->buffer->unmap();
+ }
+}
+
+/*!
+ Returns the number of bytes in a scan line.
+
+ \note This is the bytes per line of the first plane only. The bytes per line of subsequent
+ planes should be calculated as per the frame type.
+
+ This value is only valid while the frame data is \l {map()}{mapped}.
+
+ \since 1.0
+ \sa bits(), map(), mappedBytes()
+*/
+int QVideoFrame::bytesPerLine() const
+{
+ return d->bytesPerLine;
+}
+
+/*!
+ Returns a pointer to the start of the frame data buffer.
+
+ This value is only valid while the frame data is \l {map()}{mapped}.
+
+ Changes made to data accessed via this pointer (when mapped with write access)
+ are only guaranteed to have been persisted when unmap() is called.
+
+ \since 1.0
+ \sa map(), mappedBytes(), bytesPerLine()
+*/
+uchar *QVideoFrame::bits()
+{
+ return d->data;
+}
+
+/*!
+ Returns a pointer to the start of the frame data buffer.
+
+ This value is only valid while the frame data is \l {map()}{mapped}.
+
+ If the buffer was not mapped with read access, the contents of this
+ buffer will initially be uninitialized.
+
+ \since 1.0
+ \sa map(), mappedBytes(), bytesPerLine()
+*/
+const uchar *QVideoFrame::bits() const
+{
+ return d->data;
+}
+
+/*!
+ Returns the number of bytes occupied by the mapped frame data.
+
+ This value is only valid while the frame data is \l {map()}{mapped}.
+
+ \since 1.0
+ \sa map()
+*/
+int QVideoFrame::mappedBytes() const
+{
+ return d->mappedBytes;
+}
+
+/*!
+ Returns a type specific handle to a video frame's buffer.
+
+ For an OpenGL texture this would be the texture ID.
+
+ \since 1.0
+ \sa QAbstractVideoBuffer::handle()
+*/
+QVariant QVideoFrame::handle() const
+{
+ return d->buffer != 0 ? d->buffer->handle() : QVariant();
+}
+
+/*!
+ Returns the presentation time when the frame should be displayed.
+ \since 1.0
+*/
+qint64 QVideoFrame::startTime() const
+{
+ return d->startTime;
+}
+
+/*!
+ Sets the presentation \a time when the frame should be displayed.
+ \since 1.0
+*/
+void QVideoFrame::setStartTime(qint64 time)
+{
+ d->startTime = time;
+}
+
+/*!
+ Returns the presentation time when a frame should stop being displayed.
+
+ \since 1.0
+*/
+qint64 QVideoFrame::endTime() const
+{
+ return d->endTime;
+}
+
+/*!
+ Sets the presentation \a time when a frame should stop being displayed.
+ \since 1.0
+*/
+void QVideoFrame::setEndTime(qint64 time)
+{
+ d->endTime = time;
+}
+
+/*!
+ Returns a video pixel format equivalent to an image \a format. If there is no equivalent
+ format QVideoFrame::InvalidType is returned instead.
+ \since 1.0
+*/
+QVideoFrame::PixelFormat QVideoFrame::pixelFormatFromImageFormat(QImage::Format format)
+{
+ switch (format) {
+ case QImage::Format_Invalid:
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ case QImage::Format_Indexed8:
+ return Format_Invalid;
+ case QImage::Format_RGB32:
+ return Format_RGB32;
+ case QImage::Format_ARGB32:
+ return Format_ARGB32;
+ case QImage::Format_ARGB32_Premultiplied:
+ return Format_ARGB32_Premultiplied;
+ case QImage::Format_RGB16:
+ return Format_RGB565;
+ case QImage::Format_ARGB8565_Premultiplied:
+ return Format_ARGB8565_Premultiplied;
+ case QImage::Format_RGB666:
+ case QImage::Format_ARGB6666_Premultiplied:
+ return Format_Invalid;
+ case QImage::Format_RGB555:
+ return Format_RGB555;
+ case QImage::Format_ARGB8555_Premultiplied:
+ return Format_Invalid;
+ case QImage::Format_RGB888:
+ return Format_RGB24;
+ case QImage::Format_RGB444:
+ case QImage::Format_ARGB4444_Premultiplied:
+ return Format_Invalid;
+ case QImage::NImageFormats:
+ return Format_Invalid;
+ }
+ return Format_Invalid;
+}
+
+/*!
+ Returns an image format equivalent to a video frame pixel \a format. If there is no equivalent
+ format QImage::Format_Invalid is returned instead.
+ \since 1.0
+*/
+QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format)
+{
+ switch (format) {
+ case Format_Invalid:
+ return QImage::Format_Invalid;
+ case Format_ARGB32:
+ return QImage::Format_ARGB32;
+ case Format_ARGB32_Premultiplied:
+ return QImage::Format_ARGB32_Premultiplied;
+ case Format_RGB32:
+ return QImage::Format_RGB32;
+ case Format_RGB24:
+ return QImage::Format_RGB888;
+ case Format_RGB565:
+ return QImage::Format_RGB16;
+ case Format_RGB555:
+ return QImage::Format_RGB555;
+ case Format_ARGB8565_Premultiplied:
+ return QImage::Format_ARGB8565_Premultiplied;
+ case Format_BGRA32:
+ case Format_BGRA32_Premultiplied:
+ case Format_BGR32:
+ case Format_BGR24:
+ return QImage::Format_Invalid;
+ case Format_BGR565:
+ case Format_BGR555:
+ case Format_BGRA5658_Premultiplied:
+ case Format_AYUV444:
+ case Format_AYUV444_Premultiplied:
+ case Format_YUV444:
+ case Format_YUV420P:
+ case Format_YV12:
+ case Format_UYVY:
+ case Format_YUYV:
+ case Format_NV12:
+ case Format_NV21:
+ case Format_IMC1:
+ case Format_IMC2:
+ case Format_IMC3:
+ case Format_IMC4:
+ case Format_Y8:
+ case Format_Y16:
+ case Format_Jpeg:
+ case Format_CameraRaw:
+ case Format_AdobeDng:
+ return QImage::Format_Invalid;
+ case Format_User:
+ return QImage::Format_Invalid;
+ }
+ return QImage::Format_Invalid;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h
new file mode 100644
index 000000000..6dffaf59d
--- /dev/null
+++ b/src/multimedia/video/qvideoframe.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEOFRAME_H
+#define QVIDEOFRAME_H
+
+#include <QtCore/qmetatype.h>
+#include <QtCore/qshareddata.h>
+#include <QtGui/qimage.h>
+#include <qabstractvideobuffer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+class QSize;
+class QVariant;
+
+class QVideoFramePrivate;
+
+class Q_MULTIMEDIA_EXPORT QVideoFrame
+{
+public:
+ enum FieldType
+ {
+ ProgressiveFrame,
+ TopField,
+ BottomField,
+ InterlacedFrame
+ };
+
+ enum PixelFormat
+ {
+ Format_Invalid,
+ Format_ARGB32,
+ Format_ARGB32_Premultiplied,
+ Format_RGB32,
+ Format_RGB24,
+ Format_RGB565,
+ Format_RGB555,
+ Format_ARGB8565_Premultiplied,
+ Format_BGRA32,
+ Format_BGRA32_Premultiplied,
+ Format_BGR32,
+ Format_BGR24,
+ Format_BGR565,
+ Format_BGR555,
+ Format_BGRA5658_Premultiplied,
+
+ Format_AYUV444,
+ Format_AYUV444_Premultiplied,
+ Format_YUV444,
+ Format_YUV420P,
+ Format_YV12,
+ Format_UYVY,
+ Format_YUYV,
+ Format_NV12,
+ Format_NV21,
+ Format_IMC1,
+ Format_IMC2,
+ Format_IMC3,
+ Format_IMC4,
+ Format_Y8,
+ Format_Y16,
+
+ Format_Jpeg,
+
+ Format_CameraRaw,
+ Format_AdobeDng,
+
+ Format_User = 1000
+ };
+
+ QVideoFrame();
+ QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, PixelFormat format);
+ QVideoFrame(int bytes, const QSize &size, int bytesPerLine, PixelFormat format);
+ QVideoFrame(const QImage &image);
+ QVideoFrame(const QVideoFrame &other);
+ ~QVideoFrame();
+
+ QVideoFrame &operator =(const QVideoFrame &other);
+
+ bool isValid() const;
+
+ PixelFormat pixelFormat() const;
+
+ QAbstractVideoBuffer::HandleType handleType() const;
+
+ QSize size() const;
+ int width() const;
+ int height() const;
+
+ FieldType fieldType() const;
+ void setFieldType(FieldType);
+
+ bool isMapped() const;
+ bool isReadable() const;
+ bool isWritable() const;
+
+ QAbstractVideoBuffer::MapMode mapMode() const;
+
+ bool map(QAbstractVideoBuffer::MapMode mode);
+ void unmap();
+
+ int bytesPerLine() const;
+
+ uchar *bits();
+ const uchar *bits() const;
+ int mappedBytes() const;
+
+ QVariant handle() const;
+
+ qint64 startTime() const;
+ void setStartTime(qint64 time);
+
+ qint64 endTime() const;
+ void setEndTime(qint64 time);
+
+ static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
+ static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
+
+private:
+ QExplicitlySharedDataPointer<QVideoFramePrivate> d;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QVideoFrame::FieldType)
+Q_DECLARE_METATYPE(QVideoFrame::PixelFormat)
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp
new file mode 100644
index 000000000..8286d18e1
--- /dev/null
+++ b/src/multimedia/video/qvideosurfaceformat.cpp
@@ -0,0 +1,707 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideosurfaceformat.h"
+
+#include <qdebug.h>
+#include <qmetatype.h>
+#include <qpair.h>
+#include <qvariant.h>
+#include <qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVideoSurfaceFormatPrivate : public QSharedData
+{
+public:
+ QVideoSurfaceFormatPrivate()
+ : pixelFormat(QVideoFrame::Format_Invalid)
+ , handleType(QAbstractVideoBuffer::NoHandle)
+ , scanLineDirection(QVideoSurfaceFormat::TopToBottom)
+ , pixelAspectRatio(1, 1)
+ , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined)
+ , frameRate(0.0)
+ {
+ }
+
+ QVideoSurfaceFormatPrivate(
+ const QSize &size,
+ QVideoFrame::PixelFormat format,
+ QAbstractVideoBuffer::HandleType type)
+ : pixelFormat(format)
+ , handleType(type)
+ , scanLineDirection(QVideoSurfaceFormat::TopToBottom)
+ , frameSize(size)
+ , pixelAspectRatio(1, 1)
+ , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined)
+ , viewport(QPoint(0, 0), size)
+ , frameRate(0.0)
+ {
+ }
+
+ QVideoSurfaceFormatPrivate(const QVideoSurfaceFormatPrivate &other)
+ : QSharedData(other)
+ , pixelFormat(other.pixelFormat)
+ , handleType(other.handleType)
+ , scanLineDirection(other.scanLineDirection)
+ , frameSize(other.frameSize)
+ , pixelAspectRatio(other.pixelAspectRatio)
+ , ycbcrColorSpace(other.ycbcrColorSpace)
+ , viewport(other.viewport)
+ , frameRate(other.frameRate)
+ , propertyNames(other.propertyNames)
+ , propertyValues(other.propertyValues)
+ {
+ }
+
+ bool operator ==(const QVideoSurfaceFormatPrivate &other) const
+ {
+ if (pixelFormat == other.pixelFormat
+ && handleType == other.handleType
+ && scanLineDirection == other.scanLineDirection
+ && frameSize == other.frameSize
+ && pixelAspectRatio == other.pixelAspectRatio
+ && viewport == other.viewport
+ && frameRatesEqual(frameRate, other.frameRate)
+ && ycbcrColorSpace == other.ycbcrColorSpace
+ && propertyNames.count() == other.propertyNames.count()) {
+ for (int i = 0; i < propertyNames.count(); ++i) {
+ int j = other.propertyNames.indexOf(propertyNames.at(i));
+
+ if (j == -1 || propertyValues.at(i) != other.propertyValues.at(j))
+ return false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline static bool frameRatesEqual(qreal r1, qreal r2)
+ {
+ return qAbs(r1 - r2) <= 0.00001 * qMin(qAbs(r1), qAbs(r2));
+ }
+
+ QVideoFrame::PixelFormat pixelFormat;
+ QAbstractVideoBuffer::HandleType handleType;
+ QVideoSurfaceFormat::Direction scanLineDirection;
+ QSize frameSize;
+ QSize pixelAspectRatio;
+ QVideoSurfaceFormat::YCbCrColorSpace ycbcrColorSpace;
+ QRect viewport;
+ qreal frameRate;
+ QList<QByteArray> propertyNames;
+ QList<QVariant> propertyValues;
+};
+
+/*!
+ \class QVideoSurfaceFormat
+ \brief The QVideoSurfaceFormat class specifies the stream format of a video presentation
+ surface.
+ \since 1.0
+ \inmodule QtMultimedia
+
+ A video surface presents a stream of video frames. The surface's format describes the type of
+ the frames and determines how they should be presented.
+
+ The core properties of a video stream required to setup a video surface are the pixel format
+ given by pixelFormat(), and the frame dimensions given by frameSize().
+
+ If the surface is to present frames using a frame's handle a surface format will also include
+ a handle type which is given by the handleType() function.
+
+ The region of a frame that is actually displayed on a video surface is given by the viewport().
+ A stream may have a viewport less than the entire region of a frame to allow for videos smaller
+ than the nearest optimal size of a video frame. For example the width of a frame may be
+ extended so that the start of each scan line is eight byte aligned.
+
+ Other common properties are the pixelAspectRatio(), scanLineDirection(), and frameRate().
+ Additionally a stream may have some additional type specific properties which are listed by the
+ dynamicPropertyNames() function and can be accessed using the property(), and setProperty()
+ functions.
+*/
+
+/*!
+ \enum QVideoSurfaceFormat::Direction
+
+ Enumerates the layout direction of video scan lines.
+
+ \value TopToBottom Scan lines are arranged from the top of the frame to the bottom.
+ \value BottomToTop Scan lines are arranged from the bottom of the frame to the top.
+*/
+
+/*!
+ \enum QVideoSurfaceFormat::YCbCrColorSpace
+
+ Enumerates the Y'CbCr color space of video frames.
+
+ \value YCbCr_Undefined
+ No color space is specified.
+
+ \value YCbCr_BT601
+ A Y'CbCr color space defined by ITU-R recommendation BT.601
+ with Y value range from 16 to 235, and Cb/Cr range from 16 to 240.
+ Used in standard definition video.
+
+ \value YCbCr_BT709
+ A Y'CbCr color space defined by ITU-R BT.709 with the same values range as YCbCr_BT601. Used
+ for HDTV.
+
+ \value YCbCr_xvYCC601
+ The BT.601 color space with the value range extended to 0 to 255.
+ It is backward compatibile with BT.601 and uses values outside BT.601 range to represent a
+ wider range of colors.
+
+ \value YCbCr_xvYCC709
+ The BT.709 color space with the value range extended to 0 to 255.
+
+ \value YCbCr_JPEG
+ The full range Y'CbCr color space used in JPEG files.
+*/
+
+/*!
+ Constructs a null video stream format.
+*/
+QVideoSurfaceFormat::QVideoSurfaceFormat()
+ : d(new QVideoSurfaceFormatPrivate)
+{
+}
+
+/*!
+ Contructs a description of stream which receives stream of \a type buffers with given frame
+ \a size and pixel \a format.
+ \since 1.0
+*/
+QVideoSurfaceFormat::QVideoSurfaceFormat(
+ const QSize& size, QVideoFrame::PixelFormat format, QAbstractVideoBuffer::HandleType type)
+ : d(new QVideoSurfaceFormatPrivate(size, format, type))
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+ \since 1.0
+*/
+QVideoSurfaceFormat::QVideoSurfaceFormat(const QVideoSurfaceFormat &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Assigns the values of \a other to this object.
+ \since 1.0
+*/
+QVideoSurfaceFormat &QVideoSurfaceFormat::operator =(const QVideoSurfaceFormat &other)
+{
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ Destroys a video stream description.
+*/
+QVideoSurfaceFormat::~QVideoSurfaceFormat()
+{
+}
+
+/*!
+ Identifies if a video surface format has a valid pixel format and frame size.
+
+ Returns true if the format is valid, and false otherwise.
+ \since 1.0
+*/
+bool QVideoSurfaceFormat::isValid() const
+{
+ return d->pixelFormat != QVideoFrame::Format_Invalid && d->frameSize.isValid();
+}
+
+/*!
+ Returns true if \a other is the same as this video format, and false if they are different.
+ \since 1.0
+*/
+bool QVideoSurfaceFormat::operator ==(const QVideoSurfaceFormat &other) const
+{
+ return d == other.d || *d == *other.d;
+}
+
+/*!
+ Returns true if \a other is different to a video format, and false if they are the same.
+ \since 1.0
+*/
+bool QVideoSurfaceFormat::operator !=(const QVideoSurfaceFormat &other) const
+{
+ return d != other.d && !(*d == *other.d);
+}
+
+/*!
+ Returns the pixel format of frames in a video stream.
+ \since 1.0
+*/
+QVideoFrame::PixelFormat QVideoSurfaceFormat::pixelFormat() const
+{
+ return d->pixelFormat;
+}
+
+/*!
+ Returns the type of handle the surface uses to present the frame data.
+
+ If the handle type is QAbstractVideoBuffer::NoHandle buffers with any handle type are valid
+ provided they can be \l {QAbstractVideoBuffer::map()}{mapped} with the
+ QAbstractVideoBuffer::ReadOnly flag. If the handleType() is not QAbstractVideoBuffer::NoHandle
+ then the handle type of the buffer must be the same as that of the surface format.
+ \since 1.0
+*/
+QAbstractVideoBuffer::HandleType QVideoSurfaceFormat::handleType() const
+{
+ return d->handleType;
+}
+
+/*!
+ Returns the dimensions of frames in a video stream.
+
+ \sa frameWidth(), frameHeight()
+ \since 1.0
+*/
+QSize QVideoSurfaceFormat::frameSize() const
+{
+ return d->frameSize;
+}
+
+/*!
+ Returns the width of frames in a video stream.
+
+ \sa frameSize(), frameHeight()
+ \since 1.0
+*/
+int QVideoSurfaceFormat::frameWidth() const
+{
+ return d->frameSize.width();
+}
+
+/*!
+ Returns the height of frame in a video stream.
+ \since 1.0
+*/
+int QVideoSurfaceFormat::frameHeight() const
+{
+ return d->frameSize.height();
+}
+
+/*!
+ Sets the size of frames in a video stream to \a size.
+
+ This will reset the viewport() to fill the entire frame.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setFrameSize(const QSize &size)
+{
+ d->frameSize = size;
+ d->viewport = QRect(QPoint(0, 0), size);
+}
+
+/*!
+ \overload
+
+ Sets the \a width and \a height of frames in a video stream.
+
+ This will reset the viewport() to fill the entire frame.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setFrameSize(int width, int height)
+{
+ d->frameSize = QSize(width, height);
+ d->viewport = QRect(0, 0, width, height);
+}
+
+/*!
+ Returns the viewport of a video stream.
+
+ The viewport is the region of a video frame that is actually displayed.
+
+ By default the viewport covers an entire frame.
+ \since 1.0
+*/
+QRect QVideoSurfaceFormat::viewport() const
+{
+ return d->viewport;
+}
+
+/*!
+ Sets the viewport of a video stream to \a viewport.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setViewport(const QRect &viewport)
+{
+ d->viewport = viewport;
+}
+
+/*!
+ Returns the direction of scan lines.
+ \since 1.0
+*/
+QVideoSurfaceFormat::Direction QVideoSurfaceFormat::scanLineDirection() const
+{
+ return d->scanLineDirection;
+}
+
+/*!
+ Sets the \a direction of scan lines.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setScanLineDirection(Direction direction)
+{
+ d->scanLineDirection = direction;
+}
+
+/*!
+ Returns the frame rate of a video stream in frames per second.
+ \since 1.0
+*/
+qreal QVideoSurfaceFormat::frameRate() const
+{
+ return d->frameRate;
+}
+
+/*!
+ Sets the frame \a rate of a video stream in frames per second.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setFrameRate(qreal rate)
+{
+ d->frameRate = rate;
+}
+
+/*!
+ Returns a video stream's pixel aspect ratio.
+ \since 1.0
+*/
+QSize QVideoSurfaceFormat::pixelAspectRatio() const
+{
+ return d->pixelAspectRatio;
+}
+
+/*!
+ Sets a video stream's pixel aspect \a ratio.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setPixelAspectRatio(const QSize &ratio)
+{
+ d->pixelAspectRatio = ratio;
+}
+
+/*!
+ \overload
+
+ Sets the \a horizontal and \a vertical elements of a video stream's pixel aspect ratio.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setPixelAspectRatio(int horizontal, int vertical)
+{
+ d->pixelAspectRatio = QSize(horizontal, vertical);
+}
+
+/*!
+ Returns the Y'CbCr color space of a video stream.
+ \since 1.0
+*/
+QVideoSurfaceFormat::YCbCrColorSpace QVideoSurfaceFormat::yCbCrColorSpace() const
+{
+ return d->ycbcrColorSpace;
+}
+
+/*!
+ Sets the Y'CbCr color \a space of a video stream.
+ It is only used with raw YUV frame types.
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setYCbCrColorSpace(QVideoSurfaceFormat::YCbCrColorSpace space)
+{
+ d->ycbcrColorSpace = space;
+}
+
+/*!
+ Returns a suggested size in pixels for the video stream.
+
+ This is the size of the viewport scaled according to the pixel aspect ratio.
+ \since 1.0
+*/
+QSize QVideoSurfaceFormat::sizeHint() const
+{
+ QSize size = d->viewport.size();
+
+ if (d->pixelAspectRatio.height() != 0)
+ size.setWidth(size.width() * d->pixelAspectRatio.width() / d->pixelAspectRatio.height());
+
+ return size;
+}
+
+/*!
+ Returns a list of video format dynamic property names.
+ \since 1.0
+*/
+QList<QByteArray> QVideoSurfaceFormat::propertyNames() const
+{
+ return (QList<QByteArray>()
+ << "handleType"
+ << "pixelFormat"
+ << "frameSize"
+ << "frameWidth"
+ << "viewport"
+ << "scanLineDirection"
+ << "frameRate"
+ << "pixelAspectRatio"
+ << "sizeHint"
+ << "yCbCrColorSpace")
+ + d->propertyNames;
+}
+
+/*!
+ Returns the value of the video format's \a name property.
+ \since 1.0
+*/
+QVariant QVideoSurfaceFormat::property(const char *name) const
+{
+ if (qstrcmp(name, "handleType") == 0) {
+ return qVariantFromValue(d->handleType);
+ } else if (qstrcmp(name, "pixelFormat") == 0) {
+ return qVariantFromValue(d->pixelFormat);
+ } else if (qstrcmp(name, "handleType") == 0) {
+ return qVariantFromValue(d->handleType);
+ } else if (qstrcmp(name, "frameSize") == 0) {
+ return d->frameSize;
+ } else if (qstrcmp(name, "frameWidth") == 0) {
+ return d->frameSize.width();
+ } else if (qstrcmp(name, "frameHeight") == 0) {
+ return d->frameSize.height();
+ } else if (qstrcmp(name, "viewport") == 0) {
+ return d->viewport;
+ } else if (qstrcmp(name, "scanLineDirection") == 0) {
+ return qVariantFromValue(d->scanLineDirection);
+ } else if (qstrcmp(name, "frameRate") == 0) {
+ return qVariantFromValue(d->frameRate);
+ } else if (qstrcmp(name, "pixelAspectRatio") == 0) {
+ return qVariantFromValue(d->pixelAspectRatio);
+ } else if (qstrcmp(name, "sizeHint") == 0) {
+ return sizeHint();
+ } else if (qstrcmp(name, "yCbCrColorSpace") == 0) {
+ return qVariantFromValue(d->ycbcrColorSpace);
+ } else {
+ int id = 0;
+ for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {}
+
+ return id < d->propertyValues.count()
+ ? d->propertyValues.at(id)
+ : QVariant();
+ }
+}
+
+/*!
+ Sets the video format's \a name property to \a value.
+
+ Trying to set a read only property will be ignored.
+
+ \since 1.0
+*/
+void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value)
+{
+ if (qstrcmp(name, "handleType") == 0) {
+ // read only.
+ } else if (qstrcmp(name, "pixelFormat") == 0) {
+ // read only.
+ } else if (qstrcmp(name, "frameSize") == 0) {
+ if (qVariantCanConvert<QSize>(value)) {
+ d->frameSize = qvariant_cast<QSize>(value);
+ d->viewport = QRect(QPoint(0, 0), d->frameSize);
+ }
+ } else if (qstrcmp(name, "frameWidth") == 0) {
+ // read only.
+ } else if (qstrcmp(name, "frameHeight") == 0) {
+ // read only.
+ } else if (qstrcmp(name, "viewport") == 0) {
+ if (qVariantCanConvert<QRect>(value))
+ d->viewport = qvariant_cast<QRect>(value);
+ } else if (qstrcmp(name, "scanLineDirection") == 0) {
+ if (qVariantCanConvert<Direction>(value))
+ d->scanLineDirection = qvariant_cast<Direction>(value);
+ } else if (qstrcmp(name, "frameRate") == 0) {
+ if (qVariantCanConvert<qreal>(value))
+ d->frameRate = qvariant_cast<qreal>(value);
+ } else if (qstrcmp(name, "pixelAspectRatio") == 0) {
+ if (qVariantCanConvert<QSize>(value))
+ d->pixelAspectRatio = qvariant_cast<QSize>(value);
+ } else if (qstrcmp(name, "sizeHint") == 0) {
+ // read only.
+ } else if (qstrcmp(name, "yCbCrColorSpace") == 0) {
+ if (qVariantCanConvert<YCbCrColorSpace>(value))
+ d->ycbcrColorSpace = qvariant_cast<YCbCrColorSpace>(value);
+ } else {
+ int id = 0;
+ for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {}
+
+ if (id < d->propertyValues.count()) {
+ if (value.isNull()) {
+ d->propertyNames.removeAt(id);
+ d->propertyValues.removeAt(id);
+ } else {
+ d->propertyValues[id] = value;
+ }
+ } else if (!value.isNull()) {
+ d->propertyNames.append(QByteArray(name));
+ d->propertyValues.append(value);
+ }
+ }
+}
+
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QVideoSurfaceFormat &f)
+{
+ QString typeName;
+ switch (f.pixelFormat()) {
+ case QVideoFrame::Format_Invalid:
+ typeName = QLatin1String("Format_Invalid");
+ break;
+ case QVideoFrame::Format_ARGB32:
+ typeName = QLatin1String("Format_ARGB32");
+ break;
+ case QVideoFrame::Format_ARGB32_Premultiplied:
+ typeName = QLatin1String("Format_ARGB32_Premultiplied");
+ break;
+ case QVideoFrame::Format_RGB32:
+ typeName = QLatin1String("Format_RGB32");
+ break;
+ case QVideoFrame::Format_RGB24:
+ typeName = QLatin1String("Format_RGB24");
+ break;
+ case QVideoFrame::Format_RGB565:
+ typeName = QLatin1String("Format_RGB565");
+ break;
+ case QVideoFrame::Format_RGB555:
+ typeName = QLatin1String("Format_RGB555");
+ break;
+ case QVideoFrame::Format_ARGB8565_Premultiplied:
+ typeName = QLatin1String("Format_ARGB8565_Premultiplied");
+ break;
+ case QVideoFrame::Format_BGRA32:
+ typeName = QLatin1String("Format_BGRA32");
+ break;
+ case QVideoFrame::Format_BGRA32_Premultiplied:
+ typeName = QLatin1String("Format_BGRA32_Premultiplied");
+ break;
+ case QVideoFrame::Format_BGR32:
+ typeName = QLatin1String("Format_BGR32");
+ break;
+ case QVideoFrame::Format_BGR24:
+ typeName = QLatin1String("Format_BGR24");
+ break;
+ case QVideoFrame::Format_BGR565:
+ typeName = QLatin1String("Format_BGR565");
+ break;
+ case QVideoFrame::Format_BGR555:
+ typeName = QLatin1String("Format_BGR555");
+ break;
+ case QVideoFrame::Format_BGRA5658_Premultiplied:
+ typeName = QLatin1String("Format_BGRA5658_Premultiplied");
+ break;
+ case QVideoFrame::Format_AYUV444:
+ typeName = QLatin1String("Format_AYUV444");
+ break;
+ case QVideoFrame::Format_AYUV444_Premultiplied:
+ typeName = QLatin1String("Format_AYUV444_Premultiplied");
+ break;
+ case QVideoFrame::Format_YUV444:
+ typeName = QLatin1String("Format_YUV444");
+ break;
+ case QVideoFrame::Format_YUV420P:
+ typeName = QLatin1String("Format_YUV420P");
+ break;
+ case QVideoFrame::Format_YV12:
+ typeName = QLatin1String("Format_YV12");
+ break;
+ case QVideoFrame::Format_UYVY:
+ typeName = QLatin1String("Format_UYVY");
+ break;
+ case QVideoFrame::Format_YUYV:
+ typeName = QLatin1String("Format_YUYV");
+ break;
+ case QVideoFrame::Format_NV12:
+ typeName = QLatin1String("Format_NV12");
+ break;
+ case QVideoFrame::Format_NV21:
+ typeName = QLatin1String("Format_NV21");
+ break;
+ case QVideoFrame::Format_IMC1:
+ typeName = QLatin1String("Format_IMC1");
+ break;
+ case QVideoFrame::Format_IMC2:
+ typeName = QLatin1String("Format_IMC2");
+ break;
+ case QVideoFrame::Format_IMC3:
+ typeName = QLatin1String("Format_IMC3");
+ break;
+ case QVideoFrame::Format_IMC4:
+ typeName = QLatin1String("Format_IMC4");
+ break;
+ case QVideoFrame::Format_Y8:
+ typeName = QLatin1String("Format_Y8");
+ break;
+ case QVideoFrame::Format_Y16:
+ typeName = QLatin1String("Format_Y16");
+ break;
+ default:
+ typeName = QString(QLatin1String("UserType(%1)" )).arg(int(f.pixelFormat()));
+ }
+
+ dbg.nospace() << "QVideoSurfaceFormat(" << typeName;
+ dbg.nospace() << ", " << f.frameSize();
+ dbg.nospace() << ", viewport=" << f.viewport();
+ dbg.nospace() << ", pixelAspectRatio=" << f.pixelAspectRatio();
+ dbg.nospace() << ")";
+
+ foreach(const QByteArray& propertyName, f.propertyNames())
+ dbg << "\n " << propertyName.data() << " = " << f.property(propertyName.data());
+
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/video/qvideosurfaceformat.h b/src/multimedia/video/qvideosurfaceformat.h
new file mode 100644
index 000000000..f830b80a6
--- /dev/null
+++ b/src/multimedia/video/qvideosurfaceformat.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEOSURFACEFORMAT_H
+#define QVIDEOSURFACEFORMAT_H
+
+#include <QtCore/qlist.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qsize.h>
+#include <QtGui/qimage.h>
+#include <qvideoframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+
+class QDebug;
+
+class QVideoSurfaceFormatPrivate;
+
+class Q_MULTIMEDIA_EXPORT QVideoSurfaceFormat
+{
+public:
+ enum Direction
+ {
+ TopToBottom,
+ BottomToTop
+ };
+
+ enum YCbCrColorSpace
+ {
+ YCbCr_Undefined,
+ YCbCr_BT601,
+ YCbCr_BT709,
+ YCbCr_xvYCC601,
+ YCbCr_xvYCC709,
+ YCbCr_JPEG,
+#ifndef qdoc
+ YCbCr_CustomMatrix
+#endif
+ };
+
+ QVideoSurfaceFormat();
+ QVideoSurfaceFormat(
+ const QSize &size,
+ QVideoFrame::PixelFormat pixelFormat,
+ QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
+ QVideoSurfaceFormat(const QVideoSurfaceFormat &format);
+ ~QVideoSurfaceFormat();
+
+ QVideoSurfaceFormat &operator =(const QVideoSurfaceFormat &format);
+
+ bool operator ==(const QVideoSurfaceFormat &format) const;
+ bool operator !=(const QVideoSurfaceFormat &format) const;
+
+ bool isValid() const;
+
+ QVideoFrame::PixelFormat pixelFormat() const;
+ QAbstractVideoBuffer::HandleType handleType() const;
+
+ QSize frameSize() const;
+ void setFrameSize(const QSize &size);
+ void setFrameSize(int width, int height);
+
+ int frameWidth() const;
+ int frameHeight() const;
+
+ QRect viewport() const;
+ void setViewport(const QRect &viewport);
+
+ Direction scanLineDirection() const;
+ void setScanLineDirection(Direction direction);
+
+ qreal frameRate() const;
+ void setFrameRate(qreal rate);
+
+ QSize pixelAspectRatio() const;
+ void setPixelAspectRatio(const QSize &ratio);
+ void setPixelAspectRatio(int width, int height);
+
+ YCbCrColorSpace yCbCrColorSpace() const;
+ void setYCbCrColorSpace(YCbCrColorSpace colorSpace);
+
+ QSize sizeHint() const;
+
+ QList<QByteArray> propertyNames() const;
+ QVariant property(const char *name) const;
+ void setProperty(const char *name, const QVariant &value);
+
+private:
+ QSharedDataPointer<QVideoSurfaceFormatPrivate> d;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QVideoSurfaceFormat &);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QVideoSurfaceFormat::Direction)
+Q_DECLARE_METATYPE(QVideoSurfaceFormat::YCbCrColorSpace)
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/multimedia/video/video.pri b/src/multimedia/video/video.pri
new file mode 100644
index 000000000..accaa3371
--- /dev/null
+++ b/src/multimedia/video/video.pri
@@ -0,0 +1,22 @@
+
+INCLUDEPATH += video
+
+PUBLIC_HEADERS += \
+ video/qabstractvideobuffer.h \
+ video/qabstractvideosurface.h \
+ video/qvideoframe.h \
+ video/qvideosurfaceformat.h
+
+PRIVATE_HEADERS += \
+ video/qabstractvideobuffer_p.h \
+ video/qimagevideobuffer_p.h \
+ video/qmemoryvideobuffer_p.h
+
+SOURCES += \
+ video/qabstractvideobuffer.cpp \
+ video/qabstractvideosurface.cpp \
+ video/qimagevideobuffer.cpp \
+ video/qmemoryvideobuffer.cpp \
+ video/qvideoframe.cpp \
+ video/qvideosurfaceformat.cpp
+