summaryrefslogtreecommitdiffstats
path: root/src/multimedia/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/qml')
-rw-r--r--src/multimedia/qml/qmetadatacontrolmetaobject.cpp362
-rw-r--r--src/multimedia/qml/qmetadatacontrolmetaobject_p.h81
-rw-r--r--src/multimedia/qml/qml.cpp68
-rw-r--r--src/multimedia/qml/qml.h60
-rw-r--r--src/multimedia/qml/qml.pri37
-rw-r--r--src/multimedia/qml/qmlaudio.cpp326
-rw-r--r--src/multimedia/qml/qmlaudio_p.h162
-rw-r--r--src/multimedia/qml/qmlgraphicsvideo.cpp944
-rw-r--r--src/multimedia/qml/qmlgraphicsvideo_p.h193
-rw-r--r--src/multimedia/qml/qmlmediabase.cpp413
-rw-r--r--src/multimedia/qml/qmlmediabase_p.h158
-rw-r--r--src/multimedia/qml/qsoundeffect.cpp254
-rw-r--r--src/multimedia/qml/qsoundeffect_p.h126
-rw-r--r--src/multimedia/qml/qsoundeffect_pulse_p.cpp502
-rw-r--r--src/multimedia/qml/qsoundeffect_pulse_p.h138
-rw-r--r--src/multimedia/qml/qsoundeffect_qmedia_p.cpp163
-rw-r--r--src/multimedia/qml/qsoundeffect_qmedia_p.h109
-rw-r--r--src/multimedia/qml/qsoundeffect_qsound_p.cpp225
-rw-r--r--src/multimedia/qml/qsoundeffect_qsound_p.h129
-rw-r--r--src/multimedia/qml/wavedecoder_p.cpp140
-rw-r--r--src/multimedia/qml/wavedecoder_p.h123
21 files changed, 4713 insertions, 0 deletions
diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject.cpp b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp
new file mode 100644
index 0000000..47b6382
--- /dev/null
+++ b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtMultimedia/private/qmetadatacontrolmetaobject_p.h>
+#include <QtMultimedia/qmetadatacontrol.h>
+
+
+QT_BEGIN_NAMESPACE
+
+// copied from qmetaobject.cpp
+// do not touch without touching the moc as well
+enum PropertyFlags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ EnumOrFlag = 0x00000008,
+ StdCppSet = 0x00000100,
+// Override = 0x00000200,
+ Designable = 0x00001000,
+ ResolveDesignable = 0x00002000,
+ Scriptable = 0x00004000,
+ ResolveScriptable = 0x00008000,
+ Stored = 0x00010000,
+ ResolveStored = 0x00020000,
+ Editable = 0x00040000,
+ ResolveEditable = 0x00080000,
+ User = 0x00100000,
+ ResolveUser = 0x00200000,
+ Notify = 0x00400000,
+ Dynamic = 0x00800000
+};
+
+enum MethodFlags {
+ AccessPrivate = 0x00,
+ AccessProtected = 0x01,
+ AccessPublic = 0x02,
+ AccessMask = 0x03, //mask
+
+ MethodMethod = 0x00,
+ MethodSignal = 0x04,
+ MethodSlot = 0x08,
+ MethodConstructor = 0x0c,
+ MethodTypeMask = 0x0c,
+
+ MethodCompatibility = 0x10,
+ MethodCloned = 0x20,
+ MethodScriptable = 0x40
+};
+
+struct QMetaObjectPrivate
+{
+ int revision;
+ int className;
+ int classInfoCount, classInfoData;
+ int methodCount, methodData;
+ int propertyCount, propertyData;
+ int enumeratorCount, enumeratorData;
+ int constructorCount, constructorData;
+ int flags;
+};
+
+static inline const QMetaObjectPrivate *priv(const uint* m_data)
+{ return reinterpret_cast<const QMetaObjectPrivate*>(m_data); }
+// end of copied lines from qmetaobject.cpp
+
+namespace
+{
+ struct MetaDataKey
+ {
+ QtMultimedia::MetaData key;
+ const char *name;
+ };
+
+ const MetaDataKey qt_metaDataKeys[] =
+ {
+ { QtMultimedia::Title, "title" },
+ { QtMultimedia::SubTitle, "subTitle" },
+ { QtMultimedia::Author, "author" },
+ { QtMultimedia::Comment, "comment" },
+ { QtMultimedia::Description, "description" },
+ { QtMultimedia::Category, "category" },
+ { QtMultimedia::Genre, "genre" },
+ { QtMultimedia::Year, "year" },
+ { QtMultimedia::Date, "date" },
+ { QtMultimedia::UserRating, "userRating" },
+ { QtMultimedia::Keywords, "keywords" },
+ { QtMultimedia::Language, "language" },
+ { QtMultimedia::Publisher, "publisher" },
+ { QtMultimedia::Copyright, "copyright" },
+ { QtMultimedia::ParentalRating, "parentalRating" },
+ { QtMultimedia::RatingOrganisation, "ratingOrganisation" },
+
+ // Media
+ { QtMultimedia::Size, "size" },
+ { QtMultimedia::MediaType, "mediaType" },
+// { QtMultimedia::Duration, "duration" },
+
+ // Audio
+ { QtMultimedia::AudioBitRate, "audioBitRate" },
+ { QtMultimedia::AudioCodec, "audioCodec" },
+ { QtMultimedia::AverageLevel, "averageLevel" },
+ { QtMultimedia::ChannelCount, "channelCount" },
+ { QtMultimedia::PeakValue, "peakValue" },
+ { QtMultimedia::SampleRate, "sampleRate" },
+
+ // Music
+ { QtMultimedia::AlbumTitle, "albumTitle" },
+ { QtMultimedia::AlbumArtist, "albumArtist" },
+ { QtMultimedia::ContributingArtist, "contributingArtist" },
+ { QtMultimedia::Composer, "composer" },
+ { QtMultimedia::Conductor, "conductor" },
+ { QtMultimedia::Lyrics, "lyrics" },
+ { QtMultimedia::Mood, "mood" },
+ { QtMultimedia::TrackNumber, "trackNumber" },
+ { QtMultimedia::TrackCount, "trackCount" },
+
+ { QtMultimedia::CoverArtUrlSmall, "coverArtUrlSmall" },
+ { QtMultimedia::CoverArtUrlLarge, "coverArtUrlLarge" },
+
+ // Image/Video
+ { QtMultimedia::Resolution, "resolution" },
+ { QtMultimedia::PixelAspectRatio, "pixelAspectRatio" },
+
+ // Video
+ { QtMultimedia::VideoFrameRate, "videoFrameRate" },
+ { QtMultimedia::VideoBitRate, "videoBitRate" },
+ { QtMultimedia::VideoCodec, "videoCodec" },
+
+ { QtMultimedia::PosterUrl, "posterUrl" },
+
+ // Movie
+ { QtMultimedia::ChapterNumber, "chapterNumber" },
+ { QtMultimedia::Director, "director" },
+ { QtMultimedia::LeadPerformer, "leadPerformer" },
+ { QtMultimedia::Writer, "writer" },
+
+ // Photos
+ { QtMultimedia::CameraManufacturer, "cameraManufacturer" },
+ { QtMultimedia::CameraModel, "cameraModel" },
+ { QtMultimedia::Event, "event" },
+ { QtMultimedia::Subject, "subject" },
+ { QtMultimedia::Orientation, "orientation" },
+ { QtMultimedia::ExposureTime, "exposureTime" },
+ { QtMultimedia::FNumber, "fNumber" },
+ { QtMultimedia::ExposureProgram, "exposureProgram" },
+ { QtMultimedia::ISOSpeedRatings, "isoSpeedRatings" },
+ { QtMultimedia::ExposureBiasValue, "exposureBiasValue" },
+ { QtMultimedia::DateTimeOriginal, "dateTimeOriginal" },
+ { QtMultimedia::DateTimeDigitized, "dateTimeDigitized" },
+ { QtMultimedia::SubjectDistance, "subjectDistance" },
+ { QtMultimedia::MeteringMode, "meteringMode" },
+ { QtMultimedia::LightSource, "lightSource" },
+ { QtMultimedia::Flash, "flash" },
+ { QtMultimedia::FocalLength, "focalLength" },
+ { QtMultimedia::ExposureMode, "exposureMode" },
+ { QtMultimedia::WhiteBalance, "whiteBalance" },
+ { QtMultimedia::DigitalZoomRatio, "digitalZoomRatio" },
+ { QtMultimedia::FocalLengthIn35mmFilm, "focalLengthIn35mmFilm" },
+ { QtMultimedia::SceneCaptureType, "sceneCaptureType" },
+ { QtMultimedia::GainControl, "gainControl" },
+ { QtMultimedia::Contrast, "contrast" },
+ { QtMultimedia::Saturation, "saturation" },
+ { QtMultimedia::Sharpness, "sharpness" },
+ { QtMultimedia::DeviceSettingDescription, "deviceSettingDescription" }
+ };
+
+ class QMetaDataControlObject : public QObject
+ {
+ public:
+ inline QObjectData *data() { return d_ptr.data(); }
+ };
+}
+
+QMetaDataControlMetaObject::QMetaDataControlMetaObject(QMetaDataControl *control, QObject *object)
+ : m_control(control)
+ , m_object(object)
+ , m_string(0)
+ , m_data(0)
+ , m_propertyOffset(0)
+ , m_signalOffset(0)
+{
+ const QMetaObject *superClass = m_object->metaObject();
+
+ const int propertyCount = sizeof(qt_metaDataKeys) / sizeof(MetaDataKey);
+ const int dataSize = sizeof(uint)
+ * (13 // QMetaObjectPrivate members.
+ + 5 // 5 members per signal.
+ + 4 * propertyCount // 3 members per property + 1 notify signal per property.
+ + 1); // Terminating value.
+
+ m_data = reinterpret_cast<uint *>(qMalloc(dataSize));
+
+ QMetaObjectPrivate *pMeta = reinterpret_cast<QMetaObjectPrivate *>(m_data);
+
+ pMeta->revision = 3;
+ pMeta->className = 0;
+ pMeta->classInfoCount = 0;
+ pMeta->classInfoData = 0;
+ pMeta->methodCount = 1;
+ pMeta->methodData = 13;
+ pMeta->propertyCount = propertyCount;
+ pMeta->propertyData = 18;
+ pMeta->enumeratorCount = 0;
+ pMeta->enumeratorData = 0;
+ pMeta->constructorCount = 0;
+ pMeta->constructorData = 0;
+ pMeta->flags = 0x01; // Dynamic meta object flag.
+
+ const int classNameSize = qstrlen(superClass->className()) + 1;
+
+ int stringIndex = classNameSize + 1;
+
+ // __metaDataChanged() signal.
+ static const char *changeSignal = "__metaDataChanged()";
+ const int changeSignalSize = qstrlen(changeSignal) + 1;
+
+ m_data[13] = stringIndex; // Signature.
+ m_data[14] = classNameSize; // Parameters.
+ m_data[15] = classNameSize; // Type.
+ m_data[16] = classNameSize; // Tag.
+ m_data[17] = MethodSignal | AccessProtected; // Flags.
+
+ stringIndex += changeSignalSize;
+
+ const char *qvariantName = "QVariant";
+ const int qvariantSize = qstrlen(qvariantName) + 1;
+ const int qvariantIndex = stringIndex;
+
+ stringIndex += qvariantSize;
+
+ // Properties.
+ for (int i = 0; i < propertyCount; ++i) {
+ m_data[18 + 3 * i] = stringIndex; // Name.
+ m_data[19 + 3 * i] = qvariantIndex; // Type.
+ m_data[20 + 3 * i]
+ = Readable | Writable | Notify | Dynamic | (0xffffffff << 24); // Flags.
+ m_data[18 + propertyCount * 3 + i] = 0; // Notify signal.
+
+ stringIndex += qstrlen(qt_metaDataKeys[i].name) + 1;
+ }
+
+ // Terminating value.
+ m_data[18 + propertyCount * 4] = 0;
+
+ // Build string.
+ m_string = reinterpret_cast<char *>(qMalloc(stringIndex + 1));
+
+ // Class name.
+ qMemCopy(m_string, superClass->className(), classNameSize);
+
+ stringIndex = classNameSize;
+
+ // Null m_string.
+ m_string[stringIndex] = '\0';
+ stringIndex += 1;
+
+ // __metaDataChanged() signal.
+ qMemCopy(m_string + stringIndex, changeSignal, changeSignalSize);
+ stringIndex += changeSignalSize;
+
+ qMemCopy(m_string + stringIndex, qvariantName, qvariantSize);
+ stringIndex += qvariantSize;
+
+ // Properties.
+ for (int i = 0; i < propertyCount; ++i) {
+ const int propertyNameSize = qstrlen(qt_metaDataKeys[i].name) + 1;
+
+ qMemCopy(m_string + stringIndex, qt_metaDataKeys[i].name, propertyNameSize);
+ stringIndex += propertyNameSize;
+ }
+
+ // Terminating character.
+ m_string[stringIndex] = '\0';
+
+ d.superdata = superClass;
+ d.stringdata = m_string;
+ d.data = m_data;
+ d.extradata = 0;
+
+ static_cast<QMetaDataControlObject *>(m_object)->data()->metaObject = this;
+
+ m_propertyOffset = propertyOffset();
+ m_signalOffset = methodOffset();
+}
+
+QMetaDataControlMetaObject::~QMetaDataControlMetaObject()
+{
+ static_cast<QMetaDataControlObject *>(m_object)->data()->metaObject = 0;
+
+ qFree(m_data);
+ qFree(m_string);
+}
+
+int QMetaDataControlMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
+{
+ if (c == QMetaObject::ReadProperty && id >= m_propertyOffset) {
+ int propId = id - m_propertyOffset;
+
+ *reinterpret_cast<QVariant *>(a[0]) = m_control->metaData(qt_metaDataKeys[propId].key);
+
+ return -1;
+ } else if (c == QMetaObject::WriteProperty && id >= m_propertyOffset) {
+ int propId = id - m_propertyOffset;
+
+ m_control->setMetaData(qt_metaDataKeys[propId].key, *reinterpret_cast<QVariant *>(a[0]));
+
+ return -1;
+ } else {
+ return m_object->qt_metacall(c, id, a);
+ }
+}
+
+int QMetaDataControlMetaObject::createProperty(const char *, const char *)
+{
+ return -1;
+}
+
+void QMetaDataControlMetaObject::metaDataChanged()
+{
+ activate(m_object, m_signalOffset, 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject_p.h b/src/multimedia/qml/qmetadatacontrolmetaobject_p.h
new file mode 100644
index 0000000..c0fd4e8
--- /dev/null
+++ b/src/multimedia/qml/qmetadatacontrolmetaobject_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMETADATACONTROLMETAOBJECT_P_H
+#define QMETADATACONTROLMETAOJBECT_P_H
+
+#include <QtCore/qmetaobject.h>
+#include <QtMultimedia/qtmedianamespace.h>
+
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMetaDataControl;
+
+class QMetaDataControlMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+ QMetaDataControlMetaObject(QMetaDataControl *control, QObject *object);
+ ~QMetaDataControlMetaObject();
+
+ int metaCall(QMetaObject::Call call, int _id, void **arguments);
+ int createProperty(const char *, const char *);
+
+ void metaDataChanged();
+
+private:
+ QMetaDataControl *m_control;
+ QObject *m_object;
+ char *m_string;
+ uint *m_data;
+
+ int m_propertyOffset;
+ int m_signalOffset;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qml/qml.cpp b/src/multimedia/qml/qml.cpp
new file mode 100644
index 0000000..b9ee212
--- /dev/null
+++ b/src/multimedia/qml/qml.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtMultimedia/qml.h>
+#include <QtMultimedia/private/qsoundeffect_p.h>
+#include <QtMultimedia/private/qmlaudio_p.h>
+#include <QtMultimedia/private/qmlgraphicsvideo_p.h>
+
+
+QT_BEGIN_NAMESPACE
+
+namespace QtMultimedia
+{
+
+/*!
+ Register the Multimedia QML elements.
+ \internal
+*/
+
+void qRegisterQmlElements()
+{
+ qmlRegisterType<QSoundEffect>("Qt.multimedia", 4, 7, "SoundEffect", "SoundEffect");
+ qmlRegisterType<QmlAudio>("Qt.multimedia", 4, 7, "Audio", "Audio");
+ qmlRegisterType<QmlGraphicsVideo>("Qt.multimedia", 4, 7, "Video", "Video");
+}
+
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qml/qml.h b/src/multimedia/qml/qml.h
new file mode 100644
index 0000000..41274c8
--- /dev/null
+++ b/src/multimedia/qml/qml.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTMULTIMEDIA_QML_H
+#define QTMULTIMEDIA_QML_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Multimedia)
+
+namespace QtMultimedia
+{
+extern void Q_MULTIMEDIA_EXPORT qRegisterQmlElements();
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // ifndef QTMULTIMEDIA_QML_H
diff --git a/src/multimedia/qml/qml.pri b/src/multimedia/qml/qml.pri
new file mode 100644
index 0000000..e506632
--- /dev/null
+++ b/src/multimedia/qml/qml.pri
@@ -0,0 +1,37 @@
+
+contains(QT_CONFIG, declarative) {
+ QT += declarative
+
+ system(pkg-config --exists \'libpulse >= 0.9.10\') {
+ DEFINES += QT_MULTIMEDIA_PULSEAUDIO
+ HEADERS += $$PWD/qsoundeffect_pulse_p.h
+ SOURCES += $$PWD/qsoundeffect_pulse_p.cpp
+ LIBS += -lpulse
+ } else:x11 {
+ DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER
+ HEADERS += $$PWD/qsoundeffect_qmedia_p.h
+ SOURCES += $$PWD/qsoundeffect_qmedia_p.cpp
+ } else {
+ HEADERS += $$PWD/qsoundeffect_qsound_p.h
+ SOURCES += $$PWD/qsoundeffect_qsound_p.cpp
+ }
+
+ HEADERS += \
+ $$PWD/qml.h \
+ $$PWD/qmetadatacontrolmetaobject_p.h \
+ $$PWD/qmlaudio_p.h \
+ $$PWD/qmlgraphicsvideo_p.h \
+ $$PWD/qmlmediabase_p.h \
+ $$PWD/qsoundeffect_p.h \
+ $$PWD/wavedecoder_p.h
+
+ SOURCES += \
+ $$PWD/qml.cpp \
+ $$PWD/qmetadatacontrolmetaobject.cpp \
+ $$PWD/qmlaudio.cpp \
+ $$PWD/qmlgraphicsvideo.cpp \
+ $$PWD/qmlmediabase.cpp \
+ $$PWD/qsoundeffect.cpp \
+ $$PWD/wavedecoder_p.cpp
+}
+
diff --git a/src/multimedia/qml/qmlaudio.cpp b/src/multimedia/qml/qmlaudio.cpp
new file mode 100644
index 0000000..b54d644
--- /dev/null
+++ b/src/multimedia/qml/qmlaudio.cpp
@@ -0,0 +1,326 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlaudio_p.h"
+
+#include <QtMultimedia/qmediaplayercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \qmlclass Audio QmlAudio
+ \brief The Audio element allows you to add audio playback to a scene.
+
+ \qml
+ Audio { source: "audio/song.mp3" }
+ \endqml
+
+ \sa Video
+*/
+
+/*!
+ \internal
+ \class QmlAudio
+ \brief The QmlAudio class provides an audio item that you can add to a QmlView.
+*/
+
+void QmlAudio::_q_error(int errorCode, const QString &errorString)
+{
+ m_error = QMediaPlayer::Error(errorCode);
+ m_errorString = errorString;
+
+ emit error(Error(errorCode), errorString);
+ emit errorChanged();
+}
+
+
+QmlAudio::QmlAudio(QObject *parent)
+ : QObject(parent)
+{
+ setObject(this);
+}
+
+QmlAudio::~QmlAudio()
+{
+ shutdown();
+}
+
+/*!
+ \qmlmethod Audio::play()
+
+ Starts playback of the media.
+
+ Sets the \l playing property to true, and the \l paused property to false.
+*/
+
+void QmlAudio::play()
+{
+ m_playerControl->play();
+
+ if (m_paused) {
+ m_paused = false;
+ emit pausedChanged();
+ }
+}
+
+/*!
+ \qmlmethod Audio::pause()
+
+ Pauses playback of the media.
+
+ Sets the \l playing and \l paused properties to true.
+*/
+
+void QmlAudio::pause()
+{
+ m_playerControl->pause();
+
+ if (!m_paused && m_state == QMediaPlayer::PausedState) {
+ m_paused = true;
+ emit pausedChanged();
+ }
+}
+
+/*!
+ \qmlmethod Audio::stop()
+
+ Stops playback of the media.
+
+ Sets the \l playing and \l paused properties to false.
+*/
+
+void QmlAudio::stop()
+{
+ m_playerControl->stop();
+
+ if (m_paused) {
+ m_paused = false;
+ emit pausedChanged();
+ }
+}
+
+/*!
+ \qmlproperty url Audio::source
+
+ This property holds the source URL of the media.
+*/
+
+/*!
+ \qmlproperty bool Audio::playing
+
+ This property holds whether the media is playing.
+
+ Defaults to false, and can be set to true to start playback.
+*/
+
+/*!
+ \qmlproperty bool Audio::paused
+
+ This property holds whether the media is paused.
+
+ Defaults to false, and can be set to true to pause playback.
+*/
+
+/*!
+ \qmlsignal Audio::onStarted()
+
+ This handler is called when playback is started.
+*/
+
+/*!
+ \qmlsignal Audio::onResumed()
+
+ This handler is called when playback is resumed from the paused state.
+*/
+
+/*!
+ \qmlsignal Audio::onPaused()
+
+ This handler is called when playback is paused.
+*/
+
+/*!
+ \qmlsignal Audio::onStopped()
+
+ This handler is called when playback is stopped.
+*/
+
+/*!
+ \qmlproperty enum Audio::status
+
+ This property holds the status of media loading. It can be one of:
+
+ \list
+ \o NoMedia - no media has been set.
+ \o Loading - the media is currently being loaded.
+ \o Loaded - the media has been loaded.
+ \o Buffering - the media is buffering data.
+ \o Stalled - playback has been interrupted while the media is buffering data.
+ \o Buffered - the media has buffered data.
+ \o EndOfMedia - the media has played to the end.
+ \o InvalidMedia - the media cannot be played.
+ \o UnknownStatus - the status of the media is unknown.
+ \endlist
+*/
+
+QmlAudio::Status QmlAudio::status() const
+{
+ return Status(m_status);
+}
+
+/*!
+ \qmlsignal Audio::onLoaded()
+
+ This handler is called when the media source has been loaded.
+*/
+
+/*!
+ \qmlsignal Audio::onBuffering()
+
+ This handler is called when the media starts buffering.
+*/
+
+/*!
+ \qmlsignal Audio::onStalled()
+
+ This handler is called when playback has stalled while the media buffers.
+*/
+
+/*!
+ \qmlsignal Audio::onBuffered()
+
+ This handler is called when the media has finished buffering.
+*/
+
+/*!
+ \qmlsignal Audio::onEndOfMedia()
+
+ This handler is called when playback stops because end of the media has been reached.
+*/
+/*!
+ \qmlproperty int Audio::duration
+
+ This property holds the duration of the media in milliseconds.
+
+ If the media doesn't have a fixed duration (a live stream for example) this will be 0.
+*/
+
+/*!
+ \qmlproperty int Audio::position
+
+ This property holds the current playback position in milliseconds.
+
+ If the \l seekable property is true, this property can be set to seek to a new position.
+*/
+
+/*!
+ \qmlproperty qreal Audio::volume
+
+ This property holds the volume of the audio output, from 0.0 (silent) to 1.0 (maximum volume).
+*/
+
+/*!
+ \qmlproperty bool Audio::muted
+
+ This property holds whether the audio output is muted.
+*/
+
+/*!
+ \qmlproperty qreal Audio::bufferProgress
+
+ This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0
+ (full).
+*/
+
+/*!
+ \qmlproperty bool Audio::seekable
+
+ This property holds whether position of the audio can be changed.
+
+ If true; setting a \l position value will cause playback to seek to the new position.
+*/
+
+/*!
+ \qmlproperty qreal Audio::playbackRate
+
+ This property holds the rate at which audio is played at as a multiple of the normal rate.
+*/
+
+/*!
+ \qmlproperty enum Audio::error
+
+ This property holds the error state of the audio. It can be one of:
+
+ \list
+ \o NoError - there is no current error.
+ \o ResourceError - the audio cannot be played due to a problem allocating resources.
+ \o FormatError - the audio format is not supported.
+ \o NetworkError - the audio cannot be played due to network issues.
+ \o AccessDenied - the audio cannot be played due to insufficient permissions.
+ \o ServiceMissing - the audio cannot be played because the media service could not be
+ instantiated.
+ \endlist
+*/
+
+QmlAudio::Error QmlAudio::error() const
+{
+ return Error(m_error);
+}
+
+/*!
+ \qmlproperty string Audio::errorString
+
+ This property holds a string describing the current error condition in more detail.
+*/
+
+/*!
+ \qmlsignal Audio::onError(error, errorString)
+
+ This property is called when an \l {Error}{error} has occurred. The errorString parameter
+ may contain more detailed information about the error.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmlaudio_p.cpp"
+
+
diff --git a/src/multimedia/qml/qmlaudio_p.h b/src/multimedia/qml/qmlaudio_p.h
new file mode 100644
index 0000000..f034518
--- /dev/null
+++ b/src/multimedia/qml/qmlaudio_p.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLAUDIO_P_H
+#define QMLAUDIO_P_H
+
+#include <QtMultimedia/private/qmlmediabase_p.h>
+
+#include <QtCore/qbasictimer.h>
+#include <QtDeclarative/qmlgraphicsitem.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QTimerEvent;
+
+class Q_AUTOTEST_EXPORT QmlAudio : public QObject, public QmlMediaBase, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged)
+ Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(int bufferProgress READ bufferProgress NOTIFY bufferProgressChanged)
+ Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged)
+ Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+ Q_ENUMS(Status)
+ Q_ENUMS(Error)
+ Q_INTERFACES(QmlParserStatus)
+public:
+ enum Status
+ {
+ UnknownStatus = QMediaPlayer::UnknownMediaStatus,
+ NoMedia = QMediaPlayer::NoMedia,
+ Loading = QMediaPlayer::LoadingMedia,
+ Loaded = QMediaPlayer::LoadedMedia,
+ Stalled = QMediaPlayer::StalledMedia,
+ Buffering = QMediaPlayer::BufferingMedia,
+ Buffered = QMediaPlayer::BufferedMedia,
+ EndOfMedia = QMediaPlayer::EndOfMedia,
+ InvalidMedia = QMediaPlayer::InvalidMedia
+ };
+
+ enum Error
+ {
+ NoError = QMediaPlayer::NoError,
+ ResourceError = QMediaPlayer::ResourceError,
+ FormatError = QMediaPlayer::FormatError,
+ NetworkError = QMediaPlayer::NetworkError,
+ AccessDenied = QMediaPlayer::AccessDeniedError,
+ ServiceMissing = QMediaPlayer::ServiceMissingError
+ };
+
+ QmlAudio(QObject *parent = 0);
+ ~QmlAudio();
+
+ Status status() const;
+ Error error() const;
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+Q_SIGNALS:
+ void sourceChanged();
+
+ void playingChanged();
+ void pausedChanged();
+
+ void started();
+ void resumed();
+ void paused();
+ void stopped();
+
+ void statusChanged();
+
+ void loaded();
+ void buffering();
+ void stalled();
+ void buffered();
+ void endOfMedia();
+
+ void durationChanged();
+ void positionChanged();
+
+ void volumeChanged();
+ void mutedChanged();
+
+ void bufferProgressChanged();
+
+ void seekableChanged();
+ void playbackRateChanged();
+
+ void errorChanged();
+ void error(QmlAudio::Error error, const QString &errorString);
+
+private Q_SLOTS:
+ void _q_error(int, const QString &);
+
+private:
+ Q_DISABLE_COPY(QmlAudio)
+ Q_PRIVATE_SLOT(mediaBase(), void _q_stateChanged(QMediaPlayer::State))
+ Q_PRIVATE_SLOT(mediaBase(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus))
+ Q_PRIVATE_SLOT(mediaBase(), void _q_metaDataChanged())
+
+ inline QmlMediaBase *mediaBase() { return this; }
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QmlAudio))
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qml/qmlgraphicsvideo.cpp b/src/multimedia/qml/qmlgraphicsvideo.cpp
new file mode 100644
index 0000000..9e30774
--- /dev/null
+++ b/src/multimedia/qml/qmlgraphicsvideo.cpp
@@ -0,0 +1,944 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlgraphicsvideo_p.h"
+
+#include <QtMultimedia/qmediaplayercontrol.h>
+#include <QtMultimedia/qmediaservice.h>
+#include <QtMultimedia/private/qpaintervideosurface_p.h>
+#include <QtMultimedia/qvideooutputcontrol.h>
+#include <QtMultimedia/qvideorenderercontrol.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+void QmlGraphicsVideo::_q_nativeSizeChanged(const QSizeF &size)
+{
+ setImplicitWidth(size.width());
+ setImplicitHeight(size.height());
+}
+
+void QmlGraphicsVideo::_q_error(int errorCode, const QString &errorString)
+{
+ m_error = QMediaPlayer::Error(errorCode);
+ m_errorString = errorString;
+
+ emit error(Error(errorCode), errorString);
+ emit errorChanged();
+}
+
+
+/*!
+ \qmlclass Video QmlGraphicsVideo
+ \brief The Video element allows you to add videos to a scene.
+ \inherits Item
+
+ \qml
+ Video { source: "video/movie.mpg" }
+ \endqml
+
+ The video item supports untransformed, stretched, and uniformly scaled video presentation.
+ For a description of stretched uniformly scaled presentation, see the \l fillMode property
+ description.
+
+ The video item is only visible when the \l hasVideo property is true and the video is playing.
+
+ \sa Audio
+*/
+
+/*!
+ \internal
+ \class QmlGraphicsVideo
+ \brief The QmlGraphicsVideo class provides a video item that you can add to a QmlView.
+*/
+
+QmlGraphicsVideo::QmlGraphicsVideo(QmlGraphicsItem *parent)
+ : QmlGraphicsItem(parent)
+ , m_graphicsItem(0)
+
+{
+ m_graphicsItem = new QGraphicsVideoItem(this);
+ connect(m_graphicsItem, SIGNAL(nativeSizeChanged(QSizeF)),
+ this, SLOT(_q_nativeSizeChanged(QSizeF)));
+
+ setObject(this);
+
+ if (m_mediaService) {
+ connect(m_playerControl, SIGNAL(audioAvailableChanged(bool)),
+ this, SIGNAL(hasAudioChanged()));
+ connect(m_playerControl, SIGNAL(videoAvailableChanged(bool)),
+ this, SIGNAL(hasVideoChanged()));
+
+ m_graphicsItem->setMediaObject(m_mediaObject);
+ }
+}
+
+QmlGraphicsVideo::~QmlGraphicsVideo()
+{
+ shutdown();
+
+ delete m_graphicsItem;
+}
+
+/*!
+ \qmlproperty url Video::source
+
+ This property holds the source URL of the media.
+*/
+
+/*!
+ \qmlproperty bool Video::playing
+
+ This property holds whether the media is playing.
+
+ Defaults to false, and can be set to true to start playback.
+*/
+
+/*!
+ \qmlproperty bool Video::paused
+
+ This property holds whether the media is paused.
+
+ Defaults to false, and can be set to true to pause playback.
+*/
+
+/*!
+ \qmlsignal Video::onStarted()
+
+ This handler is called when playback is started.
+*/
+
+/*!
+ \qmlsignal Video::onResumed()
+
+ This handler is called when playback is resumed from the paused state.
+*/
+
+/*!
+ \qmlsignal Video::onPaused()
+
+ This handler is called when playback is paused.
+*/
+
+/*!
+ \qmlsignal Video::onStopped()
+
+ This handler is called when playback is stopped.
+*/
+
+/*!
+ \qmlproperty enum Video::status
+
+ This property holds the status of media loading. It can be one of:
+
+ \list
+ \o NoMedia - no media has been set.
+ \o Loading - the media is currently being loaded.
+ \o Loaded - the media has been loaded.
+ \o Buffering - the media is buffering data.
+ \o Stalled - playback has been interrupted while the media is buffering data.
+ \o Buffered - the media has buffered data.
+ \o EndOfMedia - the media has played to the end.
+ \o InvalidMedia - the media cannot be played.
+ \o UnknownStatus - the status of the media is cannot be determined.
+ \endlist
+*/
+
+QmlGraphicsVideo::Status QmlGraphicsVideo::status() const
+{
+ return Status(m_status);
+}
+
+/*!
+ \qmlsignal Video::onLoaded()
+
+ This handler is called when the media source has been loaded.
+*/
+
+/*!
+ \qmlsignal Video::onBuffering()
+
+ This handler is called when the media starts buffering.
+*/
+
+/*!
+ \qmlsignal Video::onStalled()
+
+ This handler is called when playback has stalled while the media buffers.
+*/
+
+/*!
+ \qmlsignal Video::onBuffered()
+
+ This handler is called when the media has finished buffering.
+*/
+
+/*!
+ \qmlsignal Video::onEndOfMedia()
+
+ This handler is called when playback stops because end of the media has been reached.
+*/
+
+/*!
+ \qmlproperty int Video::duration
+
+ This property holds the duration of the media in milliseconds.
+
+ If the media doesn't have a fixed duration (a live stream for example) this will be 0.
+*/
+
+/*!
+ \qmlproperty int Video::position
+
+ This property holds the current playback position in milliseconds.
+*/
+
+/*!
+ \qmlproperty qreal Video::volume
+
+ This property holds the volume of the audio output, from 0.0 (silent) to 1.0 (maximum volume).
+*/
+
+/*!
+ \qmlproperty bool Video::muted
+
+ This property holds whether the audio output is muted.
+*/
+
+/*!
+ \qmlproperty bool Video::hasAudio
+
+ This property holds whether the media contains audio.
+*/
+
+bool QmlGraphicsVideo::hasAudio() const
+{
+ return m_playerControl->isAudioAvailable();
+}
+
+/*!
+ \qmlproperty bool Video::hasVideo
+
+ This property holds whether the media contains video.
+*/
+
+bool QmlGraphicsVideo::hasVideo() const
+{
+ return m_playerControl->isVideoAvailable();
+}
+
+/*!
+ \qmlproperty qreal Video::bufferProgress
+
+ This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0
+ (full).
+*/
+
+/*!
+ \qmlproperty bool Video::seekable
+
+ This property holds whether position of the video can be changed.
+*/
+
+/*!
+ \qmlproperty qreal Video::playbackRate
+
+ This property holds the rate at which video is played at as a multiple of the normal rate.
+*/
+
+/*!
+ \qmlproperty enum Video::error
+
+ This property holds the error state of the video. It can be one of:
+
+ \list
+ \o NoError - there is no current error.
+ \o ResourceError - the video cannot be played due to a problem allocating resources.
+ \o FormatError - the video format is not supported.
+ \o NetworkError - the video cannot be played due to network issues.
+ \o AccessDenied - the video cannot be played due to insufficient permissions.
+ \o ServiceMissing - the video cannot be played because the media service could not be
+ instantiated.
+ \endlist
+*/
+
+
+QmlGraphicsVideo::Error QmlGraphicsVideo::error() const
+{
+ return Error(m_error);
+}
+
+/*!
+ \qmlproperty string Video::errorString
+
+ This property holds a string describing the current error condition in more detail.
+*/
+
+/*!
+ \qmlsignal Video::onError(error, errorString)
+
+ This property is called when an \l {Error}{error} has occurred. The errorString parameter
+ may contain more detailed information about the error.
+*/
+
+/*!
+ \qmlproperty enum Video::fillMode
+
+ Set this property to define how the video is scaled to fit the target area.
+
+ \list
+ \o Stretch - the video is scaled to fit.
+ \o PreserveAspectFit - the video is scaled uniformly to fit without cropping
+ \o PreserveAspectCrop - the video is scaled uniformly to fill, cropping if necessary
+ \endlist
+
+ The default fill mode is PreserveAspectFit.
+*/
+
+QmlGraphicsVideo::FillMode QmlGraphicsVideo::fillMode() const
+{
+ return FillMode(m_graphicsItem->aspectRatioMode());
+}
+
+void QmlGraphicsVideo::setFillMode(FillMode mode)
+{
+ m_graphicsItem->setAspectRatioMode(Qt::AspectRatioMode(mode));
+}
+
+/*!
+ \qmlmethod Video::play()
+
+ Starts playback of the media.
+
+ Sets the \l playing property to true, and the \l paused property to false.
+*/
+
+void QmlGraphicsVideo::play()
+{
+ m_playerControl->play();
+
+ if (m_paused) {
+ m_paused = false;
+ emit pausedChanged();
+ }
+}
+
+/*!
+ \qmlmethod Video::pause()
+
+ Pauses playback of the media.
+
+ Sets the \l playing and \l paused properties to true.
+*/
+
+void QmlGraphicsVideo::pause()
+{
+ m_playerControl->pause();
+
+ if (!m_paused && m_state == QMediaPlayer::PausedState) {
+ m_paused = true;
+ emit pausedChanged();
+ }
+}
+
+/*!
+ \qmlmethod Video::stop()
+
+ Stops playback of the media.
+
+ Sets the \l playing and \l paused properties to false.
+*/
+
+void QmlGraphicsVideo::stop()
+{
+ m_playerControl->stop();
+
+ if (m_paused) {
+ m_paused = false;
+ emit pausedChanged();
+ }
+}
+
+void QmlGraphicsVideo::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
+{
+}
+
+void QmlGraphicsVideo::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ m_graphicsItem->setSize(newGeometry.size());
+
+ QmlGraphicsItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QT_END_NAMESPACE
+
+// ***************************************
+// Documentation for meta-data properties.
+// ***************************************
+
+/*!
+ \qmlproperty variant Video::title
+
+ This property holds the tile of the media.
+
+ \sa {QtMultimedia::Title}
+*/
+
+/*!
+ \qmlproperty variant Video::subTitle
+
+ This property holds the sub-title of the media.
+
+ \sa {QtMultimedia::SubTitle}
+*/
+
+/*!
+ \qmlproperty variant Video::author
+
+ This property holds the author of the media.
+
+ \sa {QtMultimedia::Author}
+*/
+
+/*!
+ \qmlproperty variant Video::comment
+
+ This property holds a user comment about the media.
+
+ \sa {QtMultimedia::Comment}
+*/
+
+/*!
+ \qmlproperty variant Video::description
+
+ This property holds a description of the media.
+
+ \sa {QtMultimedia::Description}
+*/
+
+/*!
+ \qmlproperty variant Video::category
+
+ This property holds the category of the media
+
+ \sa {QtMultimedia::Category}
+*/
+
+/*!
+ \qmlproperty variant Video::genre
+
+ This property holds the genre of the media.
+
+ \sa {QtMultimedia::Genre}
+*/
+
+/*!
+ \qmlproperty variant Video::year
+
+ This property holds the year of release of the media.
+
+ \sa {QtMultimedia::Year}
+*/
+
+/*!
+ \qmlproperty variant Video::date
+
+ This property holds the date of the media.
+
+ \sa {QtMultimedia::Date}
+*/
+
+/*!
+ \qmlproperty variant Video::userRating
+
+ This property holds a user rating of the media in the range of 0 to 100.
+
+ \sa {QtMultimedia::UserRating}
+*/
+
+/*!
+ \qmlproperty variant Video::keywords
+
+ This property holds a list of keywords describing the media.
+
+ \sa {QtMultimedia::Keywords}
+*/
+
+/*!
+ \qmlproperty variant Video::language
+
+ This property holds the language of the media, as an ISO 639-2 code.
+
+ \sa {QtMultimedia::Language}
+*/
+
+/*!
+ \qmlproperty variant Video::publisher
+
+ This property holds the publisher of the media.
+
+ \sa {QtMultimedia::Publisher}
+*/
+
+/*!
+ \qmlproperty variant Video::copyright
+
+ This property holds the media's copyright notice.
+
+ \sa {QtMultimedia::Copyright}
+*/
+
+/*!
+ \qmlproperty variant Video::parentalRating
+
+ This property holds the parental rating of the media.
+
+ \sa {QtMultimedia::ParentalRating}
+*/
+
+/*!
+ \qmlproperty variant Video::ratingOrganisation
+
+ This property holds the name of the rating organisation responsible for the
+ parental rating of the media.
+
+ \sa {QtMultimedia::RatingOrganisation}
+*/
+
+/*!
+ \qmlproperty variant Video::size
+
+ This property property holds the size of the media in bytes.
+
+ \sa {QtMultimedia::Size}
+*/
+
+/*!
+ \qmlproperty variant Video::mediaType
+
+ This property holds the type of the media.
+
+ \sa {QtMultimedia::MediaType}
+*/
+
+/*!
+ \qmlproperty variant Video::audioBitRate
+
+ This property holds the bit rate of the media's audio stream ni bits per
+ second.
+
+ \sa {QtMultimedia::AudioBitRate}
+*/
+
+/*!
+ \qmlproperty variant Video::audioCodec
+
+ This property holds the encoding of the media audio stream.
+
+ \sa {QtMultimedia::AudioCodec}
+*/
+
+/*!
+ \qmlproperty variant Video::averageLevel
+
+ This property holds the average volume level of the media.
+
+ \sa {QtMultimedia::AverageLevel}
+*/
+
+/*!
+ \qmlproperty variant Video::channelCount
+
+ This property holds the number of channels in the media's audio stream.
+
+ \sa {QtMultimedia::ChannelCount}
+*/
+
+/*!
+ \qmlproperty variant Video::peakValue
+
+ This property holds the peak volume of media's audio stream.
+
+ \sa {QtMultimedia::PeakValue}
+*/
+
+/*!
+ \qmlproperty variant Video::sampleRate
+
+ This property holds the sample rate of the media's audio stream in hertz.
+
+ \sa {QtMultimedia::SampleRate}
+*/
+
+/*!
+ \qmlproperty variant Video::albumTitle
+
+ This property holds the title of the album the media belongs to.
+
+ \sa {QtMultimedia::AlbumTitle}
+*/
+
+/*!
+ \qmlproperty variant Video::albumArtist
+
+ This property holds the name of the principal artist of the album the media
+ belongs to.
+
+ \sa {QtMultimedia::AlbumArtist}
+*/
+
+/*!
+ \qmlproperty variant Video::contributingArtist
+
+ This property holds the names of artists contributing to the media.
+
+ \sa {QtMultimedia::ContributingArtist}
+*/
+
+/*!
+ \qmlproperty variant Video::composer
+
+ This property holds the composer of the media.
+
+ \sa {QtMultimedia::Composer}
+*/
+
+/*!
+ \qmlproperty variant Video::conductor
+
+ This property holds the conductor of the media.
+
+ \sa {QtMultimedia::Conductor}
+*/
+
+/*!
+ \qmlproperty variant Video::lyrics
+
+ This property holds the lyrics to the media.
+
+ \sa {QtMultimedia::Lyrics}
+*/
+
+/*!
+ \qmlproperty variant Video::mood
+
+ This property holds the mood of the media.
+
+ \sa {QtMultimedia::Mood}
+*/
+
+/*!
+ \qmlproperty variant Video::trackNumber
+
+ This property holds the track number of the media.
+
+ \sa {QtMultimedia::TrackNumber}
+*/
+
+/*!
+ \qmlproperty variant Video::trackCount
+
+ This property holds the number of track on the album containing the media.
+
+ \sa {QtMultimedia::TrackNumber}
+*/
+
+/*!
+ \qmlproperty variant Video::coverArtUrlSmall
+
+ This property holds the URL of a small cover art image.
+
+ \sa {QtMultimedia::CoverArtUrlSmall}
+*/
+
+/*!
+ \qmlproperty variant Video::coverArtUrlLarge
+
+ This property holds the URL of a large cover art image.
+
+ \sa {QtMultimedia::CoverArtUrlLarge}
+*/
+
+/*!
+ \qmlproperty variant Video::resolution
+
+ This property holds the dimension of an image or video.
+
+ \sa {QtMultimedia::Resolution}
+*/
+
+/*!
+ \qmlproperty variant Video::pixelAspectRatio
+
+ This property holds the pixel aspect ratio of an image or video.
+
+ \sa {QtMultimedia::PixelAspectRatio}
+*/
+
+/*!
+ \qmlproperty variant Video::videoFrameRate
+
+ This property holds the frame rate of the media's video stream.
+
+ \sa {QtMultimedia::VideoFrameRate}
+*/
+
+/*!
+ \qmlproperty variant Video::videoBitRate
+
+ This property holds the bit rate of the media's video stream in bits per
+ second.
+
+ \sa {QtMultimedia::VideoBitRate}
+*/
+
+/*!
+ \qmlproperty variant Video::videoCodec
+
+ This property holds the encoding of the media's video stream.
+
+ \sa {QtMultimedia::VideoCodec}
+*/
+
+/*!
+ \qmlproperty variant Video::posterUrl
+
+ This property holds the URL of a poster image.
+
+ \sa {QtMultimedia::PosterUrl}
+*/
+
+/*!
+ \qmlproperty variant Video::chapterNumber
+
+ This property holds the chapter number of the media.
+
+ \sa {QtMultimedia::ChapterNumber}
+*/
+
+/*!
+ \qmlproperty variant Video::director
+
+ This property holds the director of the media.
+
+ \sa {QtMultimedia::Director}
+*/
+
+/*!
+ \qmlproperty variant Video::leadPerformer
+
+ This property holds the lead performer in the media.
+
+ \sa {QtMultimedia::LeadPerformer}
+*/
+
+/*!
+ \qmlproperty variant Video::writer
+
+ This property holds the writer of the media.
+
+ \sa {QtMultimedia::Writer}
+*/
+
+// The remaining properties are related to photos, and are technically
+// available but will certainly never have values.
+#ifndef Q_QDOC
+
+/*!
+ \qmlproperty variant Video::cameraManufacturer
+
+ \sa {QtMultimedia::CameraManufacturer}
+*/
+
+/*!
+ \qmlproperty variant Video::cameraModel
+
+ \sa {QtMultimedia::CameraModel}
+*/
+
+/*!
+ \qmlproperty variant Video::event
+
+ \sa {QtMultimedia::Event}
+*/
+
+/*!
+ \qmlproperty variant Video::subject
+
+ \sa {QtMultimedia::Subject}
+*/
+
+/*!
+ \qmlproperty variant Video::orientation
+
+ \sa {QtMultimedia::Orientation}
+*/
+
+/*!
+ \qmlproperty variant Video::exposureTime
+
+ \sa {QtMultimedia::ExposureTime}
+*/
+
+/*!
+ \qmlproperty variant Video::fNumber
+
+ \sa {QtMultimedia::FNumber}
+*/
+
+/*!
+ \qmlproperty variant Video::exposureProgram
+
+ \sa {QtMultimedia::ExposureProgram}
+*/
+
+/*!
+ \qmlproperty variant Video::isoSpeedRatings
+
+ \sa {QtMultimedia::ISOSpeedRatings}
+*/
+
+/*!
+ \qmlproperty variant Video::exposureBiasValue
+
+ \sa {QtMultimedia::ExposureBiasValue}
+*/
+
+/*!
+ \qmlproperty variant Video::dateTimeDigitized
+
+ \sa {QtMultimedia::DateTimeDigitized}
+*/
+
+/*!
+ \qmlproperty variant Video::subjectDistance
+
+ \sa {QtMultimedia::SubjectDistance}
+*/
+
+/*!
+ \qmlproperty variant Video::meteringMode
+
+ \sa {QtMultimedia::MeteringMode}
+*/
+
+/*!
+ \qmlproperty variant Video::lightSource
+
+ \sa {QtMultimedia::LightSource}
+*/
+
+/*!
+ \qmlproperty variant Video::flash
+
+ \sa {QtMultimedia::Flash}
+*/
+
+/*!
+ \qmlproperty variant Video::focalLength
+
+ \sa {QtMultimedia::FocalLength}
+*/
+
+/*!
+ \qmlproperty variant Video::exposureMode
+
+ \sa {QtMultimedia::ExposureMode}
+*/
+
+/*!
+ \qmlproperty variant Video::whiteBalance
+
+ \sa {QtMultimedia::WhiteBalance}
+*/
+
+/*!
+ \qmlproperty variant Video::DigitalZoomRatio
+
+ \sa {QtMultimedia::DigitalZoomRatio}
+*/
+
+/*!
+ \qmlproperty variant Video::focalLengthIn35mmFilm
+
+ \sa {QtMultimedia::FocalLengthIn35mmFile}
+*/
+
+/*!
+ \qmlproperty variant Video::sceneCaptureType
+
+ \sa {QtMultimedia::SceneCaptureType}
+*/
+
+/*!
+ \qmlproperty variant Video::gainControl
+
+ \sa {QtMultimedia::GainControl}
+*/
+
+/*!
+ \qmlproperty variant Video::contrast
+
+ \sa {QtMultimedia::contrast}
+*/
+
+/*!
+ \qmlproperty variant Video::saturation
+
+ \sa {QtMultimedia::Saturation}
+*/
+
+/*!
+ \qmlproperty variant Video::sharpness
+
+ \sa {QtMultimedia::Sharpness}
+*/
+
+/*!
+ \qmlproperty variant Video::deviceSettingDescription
+
+ \sa {QtMultimedia::DeviceSettingDescription}
+*/
+
+#endif
+
+#include "moc_qmlgraphicsvideo_p.cpp"
diff --git a/src/multimedia/qml/qmlgraphicsvideo_p.h b/src/multimedia/qml/qmlgraphicsvideo_p.h
new file mode 100644
index 0000000..a4f8e32
--- /dev/null
+++ b/src/multimedia/qml/qmlgraphicsvideo_p.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLGRAPHICSVIDEO_H
+#define QMLGRAPHICSVIDEO_H
+
+#include <QtMultimedia/private/qmlmediabase_p.h>
+
+#include <QtMultimedia/qgraphicsvideoitem.h>
+
+#include <QtCore/qbasictimer.h>
+#include <QtDeclarative/qmlgraphicsitem.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QTimerEvent;
+class QVideoSurfaceFormat;
+
+
+class Q_AUTOTEST_EXPORT QmlGraphicsVideo : public QmlGraphicsItem, public QmlMediaBase
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged)
+ Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(bool hasAudio READ hasAudio NOTIFY hasAudioChanged)
+ Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged)
+ Q_PROPERTY(int bufferProgress READ bufferProgress NOTIFY bufferProgressChanged)
+ Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged)
+ Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+ Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode)
+ Q_ENUMS(FillMode)
+ Q_ENUMS(Status)
+ Q_ENUMS(Error)
+public:
+ enum FillMode
+ {
+ Stretch = Qt::IgnoreAspectRatio,
+ PreserveAspectFit = Qt::KeepAspectRatio,
+ PreserveAspectCrop = Qt::KeepAspectRatioByExpanding
+ };
+
+ enum Status
+ {
+ UnknownStatus = QMediaPlayer::UnknownMediaStatus,
+ NoMedia = QMediaPlayer::NoMedia,
+ Loading = QMediaPlayer::LoadingMedia,
+ Loaded = QMediaPlayer::LoadedMedia,
+ Stalled = QMediaPlayer::StalledMedia,
+ Buffering = QMediaPlayer::BufferingMedia,
+ Buffered = QMediaPlayer::BufferedMedia,
+ EndOfMedia = QMediaPlayer::EndOfMedia,
+ InvalidMedia = QMediaPlayer::InvalidMedia
+ };
+
+ enum Error
+ {
+ NoError = QMediaPlayer::NoError,
+ ResourceError = QMediaPlayer::ResourceError,
+ FormatError = QMediaPlayer::FormatError,
+ NetworkError = QMediaPlayer::NetworkError,
+ AccessDenied = QMediaPlayer::AccessDeniedError,
+ ServiceMissing = QMediaPlayer::ServiceMissingError
+ };
+
+ QmlGraphicsVideo(QmlGraphicsItem *parent = 0);
+ ~QmlGraphicsVideo();
+
+ bool hasAudio() const;
+ bool hasVideo() const;
+
+ FillMode fillMode() const;
+ void setFillMode(FillMode mode);
+
+ Status status() const;
+ Error error() const;
+
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+Q_SIGNALS:
+ void sourceChanged();
+
+ void playingChanged();
+ void pausedChanged();
+
+ void started();
+ void resumed();
+ void paused();
+ void stopped();
+
+ void statusChanged();
+
+ void loaded();
+ void buffering();
+ void stalled();
+ void buffered();
+ void endOfMedia();
+
+ void durationChanged();
+ void positionChanged();
+
+ void volumeChanged();
+ void mutedChanged();
+ void hasAudioChanged();
+ void hasVideoChanged();
+
+ void bufferProgressChanged();
+
+ void seekableChanged();
+ void playbackRateChanged();
+
+ void errorChanged();
+ void error(QmlGraphicsVideo::Error error, const QString &errorString);
+
+protected:
+ void geometryChanged(const QRectF &geometry, const QRectF &);
+
+private Q_SLOTS:
+ void _q_nativeSizeChanged(const QSizeF &size);
+ void _q_error(int, const QString &);
+
+private:
+ Q_DISABLE_COPY(QmlGraphicsVideo)
+
+ QGraphicsVideoItem *m_graphicsItem;
+
+ Q_PRIVATE_SLOT(mediaBase(), void _q_stateChanged(QMediaPlayer::State))
+ Q_PRIVATE_SLOT(mediaBase(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus))
+ Q_PRIVATE_SLOT(mediaBase(), void _q_metaDataChanged())
+
+ inline QmlMediaBase *mediaBase() { return this; }
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QmlGraphicsVideo))
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qml/qmlmediabase.cpp b/src/multimedia/qml/qmlmediabase.cpp
new file mode 100644
index 0000000..11b4337
--- /dev/null
+++ b/src/multimedia/qml/qmlmediabase.cpp
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtMultimedia/private/qmlmediabase_p.h"
+
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qurl.h>
+
+#include <QtMultimedia/qmediaplayercontrol.h>
+#include <QtMultimedia/qmediaservice.h>
+#include <QtMultimedia/qmediaserviceprovider.h>
+#include <QtMultimedia/qmetadatacontrol.h>
+#include <QtMultimedia/private/qmetadatacontrolmetaobject_p.h>
+
+
+
+QT_BEGIN_NAMESPACE
+
+
+class QmlMediaBaseObject : public QMediaObject
+{
+public:
+ QmlMediaBaseObject(QMediaService *service)
+ : QMediaObject(0, service)
+ {
+ }
+};
+
+class QmlMediaBasePlayerControl : public QMediaPlayerControl
+{
+public:
+ QmlMediaBasePlayerControl(QObject *parent)
+ : QMediaPlayerControl(parent)
+ {
+ }
+
+ QMediaPlayer::State state() const { return QMediaPlayer::StoppedState; }
+ QMediaPlayer::MediaStatus mediaStatus() const { return QMediaPlayer::NoMedia; }
+
+ qint64 duration() const { return 0; }
+ qint64 position() const { return 0; }
+ void setPosition(qint64) {}
+ int volume() const { return 0; }
+ void setVolume(int) {}
+ bool isMuted() const { return false; }
+ void setMuted(bool) {}
+ int bufferStatus() const { return 0; }
+ bool isAudioAvailable() const { return false; }
+ bool isVideoAvailable() const { return false; }
+ bool isSeekable() const { return false; }
+ QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); }
+ qreal playbackRate() const { return 1; }
+ void setPlaybackRate(qreal) {}
+ QMediaContent media() const { return QMediaContent(); }
+ const QIODevice *mediaStream() const { return 0; }
+ void setMedia(const QMediaContent &, QIODevice *) {}
+
+ void play() {}
+ void pause() {}
+ void stop() {}
+};
+
+class QmlMediaBaseAnimation : public QObject
+{
+public:
+ QmlMediaBaseAnimation(QmlMediaBase *media)
+ : m_media(media)
+ {
+ }
+
+ void start() { if (!m_timer.isActive()) m_timer.start(500, this); }
+ void stop() { m_timer.stop(); }
+
+protected:
+ void timerEvent(QTimerEvent *event)
+ {
+ if (event->timerId() == m_timer.timerId()) {
+ event->accept();
+
+ if (m_media->m_state == QMediaPlayer::PlayingState)
+ emit m_media->positionChanged();
+ if (m_media->m_status == QMediaPlayer::BufferingMedia || QMediaPlayer::StalledMedia)
+ emit m_media->bufferProgressChanged();
+ } else {
+ QObject::timerEvent(event);
+ }
+ }
+
+private:
+ QmlMediaBase *m_media;
+ QBasicTimer m_timer;
+};
+
+void QmlMediaBase::_q_stateChanged(QMediaPlayer::State state)
+{
+ if (state != m_state) {
+ QMediaPlayer::State oldState = m_state;
+
+ m_state = state;
+
+ if (state == QMediaPlayer::StoppedState) {
+ emit stopped();
+ emit playingChanged();
+ } else if (oldState == QMediaPlayer::StoppedState) {
+ emit started();
+ emit playingChanged();
+ } else if (oldState == QMediaPlayer::PausedState) {
+ m_paused = false;
+
+ emit resumed();
+ emit pausedChanged();
+ }
+
+ if (state == m_state && state == QMediaPlayer::PausedState) {
+ bool wasPaused = m_paused;
+
+ m_paused = true;
+
+ emit paused();
+
+ if (!wasPaused)
+ emit pausedChanged();
+ }
+
+ if (m_state == QMediaPlayer::PlayingState
+ || m_status == QMediaPlayer::BufferingMedia
+ || m_status == QMediaPlayer::StalledMedia) {
+ m_animation->start();
+ } else {
+ m_animation->stop();
+ }
+ }
+}
+
+void QmlMediaBase::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status)
+{
+ if (status != m_status) {
+ m_status = status;
+
+ switch (status) {
+ case QMediaPlayer::LoadedMedia:
+ emit loaded();
+ break;
+ case QMediaPlayer::BufferingMedia:
+ emit buffering();
+ break;
+ case QMediaPlayer::BufferedMedia:
+ emit buffered();
+ break;
+ case QMediaPlayer::StalledMedia:
+ emit stalled();
+ break;
+ case QMediaPlayer::EndOfMedia:
+ emit endOfMedia();
+ break;
+ default:
+ break;
+ }
+
+ emit statusChanged();
+
+ if (m_state == QMediaPlayer::PlayingState
+ || m_status == QMediaPlayer::BufferingMedia
+ || m_status == QMediaPlayer::StalledMedia) {
+ m_animation->start();
+ } else {
+ m_animation->stop();
+ }
+ }
+}
+
+void QmlMediaBase::_q_metaDataChanged()
+{
+ m_metaObject->metaDataChanged();
+}
+
+QmlMediaBase::QmlMediaBase()
+ : m_mediaService(0)
+ , m_playerControl(0)
+ , m_mediaObject(0)
+ , m_mediaProvider(0)
+ , m_metaDataControl(0)
+ , m_metaObject(0)
+ , m_animation(0)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_status(QMediaPlayer::NoMedia)
+ , m_error(QMediaPlayer::NoError)
+ , m_paused(false)
+{
+}
+
+QmlMediaBase::~QmlMediaBase()
+{
+}
+
+void QmlMediaBase::shutdown()
+{
+ delete m_metaObject;
+ delete m_mediaObject;
+
+ if (m_mediaProvider)
+ m_mediaProvider->releaseService(m_mediaService);
+
+ delete m_animation;
+
+}
+
+void QmlMediaBase::setObject(QObject *object)
+{
+ if ((m_mediaProvider = QMediaServiceProvider::defaultServiceProvider())) {
+ if ((m_mediaService = m_mediaProvider->requestService(Q_MEDIASERVICE_MEDIAPLAYER))) {
+ m_playerControl = qobject_cast<QMediaPlayerControl *>(
+ m_mediaService->control(QMediaPlayerControl_iid));
+ m_metaDataControl = qobject_cast<QMetaDataControl *>(
+ m_mediaService->control(QMetaDataControl_iid));
+ m_mediaObject = new QmlMediaBaseObject(m_mediaService);
+ }
+ }
+
+ if (m_playerControl) {
+ QObject::connect(m_playerControl, SIGNAL(stateChanged(QMediaPlayer::State)),
+ object, SLOT(_q_stateChanged(QMediaPlayer::State)));
+ QObject::connect(m_playerControl, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ object, SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ QObject::connect(m_playerControl, SIGNAL(mediaChanged(QMediaContent)),
+ object, SIGNAL(sourceChanged()));
+ QObject::connect(m_playerControl, SIGNAL(durationChanged(qint64)),
+ object, SIGNAL(durationChanged()));
+ QObject::connect(m_playerControl, SIGNAL(positionChanged(qint64)),
+ object, SIGNAL(positionChanged()));
+ QObject::connect(m_playerControl, SIGNAL(volumeChanged(int)),
+ object, SIGNAL(volumeChanged()));
+ QObject::connect(m_playerControl, SIGNAL(mutedChanged(bool)),
+ object, SIGNAL(mutedChanged()));
+ QObject::connect(m_playerControl, SIGNAL(bufferStatusChanged(int)),
+ object, SIGNAL(bufferProgressChanged()));
+ QObject::connect(m_playerControl, SIGNAL(seekableChanged(bool)),
+ object, SIGNAL(seekableChanged()));
+ QObject::connect(m_playerControl, SIGNAL(playbackRateChanged(qreal)),
+ object, SIGNAL(playbackRateChanged()));
+ QObject::connect(m_playerControl, SIGNAL(error(int,QString)),
+ object, SLOT(_q_error(int,QString)));
+
+ m_animation = new QmlMediaBaseAnimation(this);
+ } else {
+ m_error = QMediaPlayer::ServiceMissingError;
+
+ m_playerControl = new QmlMediaBasePlayerControl(object);
+ }
+
+ if (m_metaDataControl) {
+ m_metaObject = new QMetaDataControlMetaObject(m_metaDataControl, object);
+
+ QObject::connect(m_metaDataControl, SIGNAL(metaDataChanged()),
+ object, SLOT(_q_metaDataChanged()));
+ }
+}
+
+QUrl QmlMediaBase::source() const
+{
+ return m_playerControl->media().canonicalUrl();
+}
+
+void QmlMediaBase::setSource(const QUrl &url)
+{
+ if (m_error != QMediaPlayer::ServiceMissingError && m_error != QMediaPlayer::NoError) {
+ m_error = QMediaPlayer::NoError;
+ m_errorString = QString();
+
+ emit errorChanged();
+ }
+
+ m_playerControl->setMedia(QMediaContent(url), 0);
+}
+
+bool QmlMediaBase::isPlaying() const
+{
+ return m_state != QMediaPlayer::StoppedState;
+}
+
+void QmlMediaBase::setPlaying(bool playing)
+{
+ if (playing && m_state == QMediaPlayer::StoppedState) {
+ if (m_paused)
+ m_playerControl->pause();
+ else
+ m_playerControl->play();
+ } else if (!playing) {
+ m_playerControl->stop();
+ }
+}
+
+bool QmlMediaBase::isPaused() const
+{
+ return m_paused;
+}
+
+void QmlMediaBase::setPaused(bool paused)
+{
+ if (m_paused != paused) {
+ if (paused && m_state == QMediaPlayer::PlayingState) {
+ m_playerControl->pause();
+ } else if (!paused && m_state == QMediaPlayer::PausedState) {
+ m_playerControl->play();
+ } else {
+ m_paused = paused;
+
+ emit pausedChanged();
+ }
+ }
+}
+
+int QmlMediaBase::duration() const
+{
+ return m_playerControl->duration();
+}
+
+int QmlMediaBase::position() const
+{
+ return m_playerControl->position();
+
+}
+
+void QmlMediaBase::setPosition(int position)
+{
+ m_playerControl->setPosition(position);
+}
+
+qreal QmlMediaBase::volume() const
+{
+ return qreal(m_playerControl->volume()) / 100;
+}
+
+void QmlMediaBase::setVolume(qreal volume)
+{
+ m_playerControl->setVolume(qRound(volume * 100));
+}
+
+bool QmlMediaBase::isMuted() const
+{
+ return m_playerControl->isMuted();
+}
+
+void QmlMediaBase::setMuted(bool muted)
+{
+ m_playerControl->setMuted(muted);
+}
+
+qreal QmlMediaBase::bufferProgress() const
+{
+ return qreal(m_playerControl->bufferStatus()) / 100;
+}
+
+bool QmlMediaBase::isSeekable() const
+{
+ return m_playerControl->isSeekable();
+}
+
+qreal QmlMediaBase::playbackRate() const
+{
+ return m_playerControl->playbackRate();
+}
+
+void QmlMediaBase::setPlaybackRate(qreal rate)
+{
+ m_playerControl->setPlaybackRate(rate);
+}
+
+QString QmlMediaBase::errorString() const
+{
+ return m_errorString;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/multimedia/qml/qmlmediabase_p.h b/src/multimedia/qml/qmlmediabase_p.h
new file mode 100644
index 0000000..948a0e8
--- /dev/null
+++ b/src/multimedia/qml/qmlmediabase_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLMEDIABASE_P_H
+#define QMLMEDIABASE_P_H
+
+
+#include <QtCore/qbasictimer.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlayerControl;
+class QMediaService;
+class QMediaServiceProvider;
+class QMetaDataControl;
+class QMetaDataControlMetaObject;
+class QmlMediaBaseAnimation;
+
+class Q_AUTOTEST_EXPORT QmlMediaBase
+{
+public:
+ QmlMediaBase();
+ virtual ~QmlMediaBase();
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+
+ bool isPlaying() const;
+ void setPlaying(bool playing);
+
+ bool isPaused() const;
+ void setPaused(bool paused);
+
+ int duration() const;
+
+ int position() const;
+ void setPosition(int position);
+
+ qreal volume() const;
+ void setVolume(qreal volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ qreal bufferProgress() const;
+
+ bool isSeekable() const;
+
+ qreal playbackRate() const;
+ void setPlaybackRate(qreal rate);
+
+ QString errorString() const;
+
+ void _q_stateChanged(QMediaPlayer::State state);
+ void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status);
+
+ void _q_metaDataChanged();
+
+protected:
+ void shutdown();
+
+ void setObject(QObject *object);
+
+ virtual void sourceChanged() = 0;
+
+ virtual void playingChanged() = 0;
+ virtual void pausedChanged() = 0;
+
+ virtual void started() = 0;
+ virtual void resumed() = 0;
+ virtual void paused() = 0;
+ virtual void stopped() = 0;
+
+ virtual void statusChanged() = 0;
+
+ virtual void loaded() = 0;
+ virtual void buffering() = 0;
+ virtual void stalled() = 0;
+ virtual void buffered() = 0;
+ virtual void endOfMedia() = 0;
+
+ virtual void durationChanged() = 0;
+ virtual void positionChanged() = 0;
+
+ virtual void volumeChanged() = 0;
+ virtual void mutedChanged() = 0;
+
+ virtual void bufferProgressChanged() = 0;
+
+ virtual void seekableChanged() = 0;
+ virtual void playbackRateChanged() = 0;
+
+ virtual void errorChanged() = 0;
+
+ QMediaService *m_mediaService;
+ QMediaPlayerControl *m_playerControl;
+
+ QMediaObject *m_mediaObject;
+ QMediaServiceProvider *m_mediaProvider;
+ QMetaDataControl *m_metaDataControl;
+ QMetaDataControlMetaObject *m_metaObject;
+ QmlMediaBaseAnimation *m_animation;
+
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_status;
+ QMediaPlayer::Error m_error;
+ bool m_paused;
+ QString m_errorString;
+
+ friend class QmlMediaBaseAnimation;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/multimedia/qml/qsoundeffect.cpp b/src/multimedia/qml/qsoundeffect.cpp
new file mode 100644
index 0000000..df9af7b
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmediacontent.h"
+#include "qmediaplayer.h"
+
+#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.
+
+ The following example plays a wav file on mouse click.
+
+ \qml
+ SoundEffect {
+ id: playSound
+ source: "test.wav"
+ }
+ MouseRegion {
+ id: playArea
+ anchors.fill: parent
+ onPressed: {
+ playSound.play()
+ }
+ }
+ \endqml
+
+ \sa SoundEffect
+*/
+
+/*!
+ \qmlproperty QUrl SoundEffect::source
+
+ This property provides a way to control the sound to play.
+*/
+
+/*!
+ \qmlproperty int SoundEffect::loopCount
+
+ This property provides a way to control the number of times to repeat the sound on each play().
+*/
+
+/*!
+ \qmlproperty int SoundEffect::volume
+
+ This property provides a way to control the volume for playback.
+*/
+
+/*!
+ \qmlproperty bool SoundEffect::muted
+
+ This property provides a way to control muting.
+*/
+
+/*!
+ \qmlproperty int SoundEffect::duration
+
+ This property holds the duration in milliseconds of the current source audio.
+*/
+
+/*!
+ \qmlsignal SoundEffect::sourceChanged()
+
+ This handler is called when the source has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::loopCountChanged()
+
+ This handler is called when the number of loops has changes.
+*/
+
+/*!
+ \qmlsignal SoundEffect::volumeChanged()
+
+ This handler is called when the volume has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::mutedChanged()
+
+ This handler is called when the mute state has changed.
+*/
+
+/*!
+ \qmlsignal SoundEffect::durationChanged()
+
+ This handler is called when the duration has changed.
+*/
+
+QSoundEffect::QSoundEffect(QObject *parent) :
+ QObject(parent),
+ m_loopCount(1),
+ m_volume(100),
+ m_muted(false),
+ m_runningCount(0)
+{
+ d = new QSoundEffectPrivate(this);
+ connect(d, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged()));
+ connect(d, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged()));
+ connect(d, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged()));
+ connect(d, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(repeat()));
+}
+
+QSoundEffect::~QSoundEffect()
+{
+ delete d;
+}
+
+QUrl QSoundEffect::source() const
+{
+ return d != 0 ? d->media().canonicalUrl() : QUrl();
+}
+
+void QSoundEffect::setSource(const QUrl &url)
+{
+ if (d != 0 && d->media().canonicalUrl() == url)
+ return;
+
+ d->setVolume(m_volume);
+ d->setMuted(m_muted);
+ d->setMedia(url);
+
+ if (url.isEmpty())
+ return;
+
+ emit sourceChanged();
+}
+
+int QSoundEffect::loopCount() const
+{
+ return m_loopCount;
+}
+
+void QSoundEffect::setLoopCount(int loopCount)
+{
+ if (m_loopCount == loopCount)
+ return;
+
+ m_loopCount = loopCount;
+ emit loopCountChanged();
+}
+
+int QSoundEffect::volume() const
+{
+ return d != 0 ? d->volume() : m_volume;
+}
+
+void QSoundEffect::setVolume(int volume)
+{
+ if (m_volume == volume)
+ return;
+
+ m_volume = volume;
+ if (d != 0)
+ d->setVolume(volume);
+ else
+ emit volumeChanged();
+}
+
+bool QSoundEffect::isMuted() const
+{
+ return d != 0 ? d->isMuted() : m_muted;
+}
+
+void QSoundEffect::setMuted(bool muted)
+{
+ if (m_muted == muted)
+ return;
+
+ m_muted = muted;
+ if (d != 0)
+ d->setMuted(muted);
+ else
+ emit mutedChanged();
+}
+
+int QSoundEffect::duration() const
+{
+ return d != 0 ? d->duration() : 0;
+}
+
+void QSoundEffect::play()
+{
+ m_runningCount = 0;
+
+ if (d != 0)
+ d->play();
+}
+
+void QSoundEffect::stop()
+{
+ if (d != 0)
+ d->stop();
+}
+
+void QSoundEffect::repeat()
+{
+ if (d->state() == QMediaPlayer::StoppedState) {
+ if (++m_runningCount < m_loopCount)
+ d->play();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/qml/qsoundeffect_p.h b/src/multimedia/qml/qsoundeffect_p.h
new file mode 100644
index 0000000..ab6f9e5
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUNDEFFECT_H
+#define QSOUNDEFFECT_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 <QtDeclarative/qml.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QSoundEffectPrivate;
+class Q_AUTOTEST_EXPORT QSoundEffect : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount NOTIFY loopCountChanged)
+ Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
+ Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
+
+public:
+ explicit QSoundEffect(QObject *parent = 0);
+ ~QSoundEffect();
+
+ 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);
+
+ int duration() const;
+
+signals:
+ void sourceChanged();
+ void loopCountChanged();
+ void volumeChanged();
+ void mutedChanged();
+ void durationChanged();
+
+public slots:
+ void play();
+ void stop();
+
+private slots:
+ void repeat();
+
+private:
+ Q_DISABLE_COPY(QSoundEffect)
+
+ int m_loopCount;
+ int m_volume;
+ bool m_muted;
+ int m_runningCount;
+
+ QSoundEffectPrivate* d;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QSoundEffect))
+
+QT_END_HEADER
+
+
+#endif // QSOUNDEFFECT_H
diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.cpp b/src/multimedia/qml/qsoundeffect_pulse_p.cpp
new file mode 100644
index 0000000..7057022
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_pulse_p.cpp
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include <QtMultimedia/qaudioformat.h>
+#include <QtNetwork>
+#include <QTime>
+
+#include "qmediacontent.h"
+#include "qmediaplayer.h"
+#include "qsoundeffect_p.h"
+
+#include "wavedecoder_p.h"
+
+#include "qsoundeffect_pulse_p.h"
+
+#if(Q_WS_MAEMO_5)
+#include <pulse/ext-stream-restore.h>
+#endif
+
+// Less than ideal
+#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16)
+
+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:
+ 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;
+ }
+
+ int volume()
+ {
+ return m_volume;
+ }
+
+private:
+ void prepare()
+ {
+ m_volume = 100;
+
+ 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());
+
+#if(Q_WS_MAEMO_5)
+ pa_context_set_state_callback(m_context, context_state_callback, this);
+#endif
+ 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, NULL, (pa_context_flags_t)0, NULL) < 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;
+ }
+
+#if(Q_WS_MAEMO_5)
+ 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:
+ pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self);
+ pa_ext_stream_restore_subscribe(c, 1, NULL, self);
+ break;
+ default:
+ break;
+ }
+ }
+ static void stream_restore_monitor_callback(pa_context *c, void *userdata)
+ {
+ PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata);
+ pa_ext_stream_restore2_read(c, &stream_restore_info_callback, self);
+ }
+ static void stream_restore_info_callback(pa_context *c, const pa_ext_stream_restore2_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"))) {
+ const unsigned str_length = 256;
+ char str[str_length];
+ pa_cvolume_snprint(str, str_length, &info->volume);
+ self->m_volume = QString(str).replace(" ","").replace("%","").mid(2).toInt();
+ }
+ }
+ }
+#endif
+
+ int m_volume;
+ bool m_prepared;
+ pa_context *m_context;
+ pa_threaded_mainloop *m_mainLoop;
+ pa_mainloop_api *m_mainLoopApi;
+};
+}
+
+Q_GLOBAL_STATIC(PulseDaemon, daemon)
+
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_muted(false),
+ m_playQueued(false),
+ m_volume(100),
+ m_duration(0),
+ m_dataUploaded(0),
+ m_state(QMediaPlayer::StoppedState),
+ m_status(QMediaPlayer::NoMedia),
+ m_reply(0),
+ m_stream(0),
+ m_networkAccessManager(0)
+{
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+ delete m_reply;
+ unloadSample();
+}
+
+qint64 QSoundEffectPrivate::duration() const
+{
+ return m_duration;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return m_volume;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+QMediaContent QSoundEffectPrivate::media() const
+{
+ return m_media;
+}
+
+QMediaPlayer::State QSoundEffectPrivate::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const
+{
+ return m_status;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_status == QMediaPlayer::LoadingMedia) {
+ m_playQueued = true;
+ return;
+ }
+
+ if (m_status != QMediaPlayer::BufferedMedia ||
+ m_state == QMediaPlayer::PlayingState)
+ return;
+
+ pa_volume_t m_vol = PA_VOLUME_NORM;
+
+ daemon()->lock();
+#if(Q_WS_MAEMO_5)
+ m_vol = PA_VOLUME_NORM/100*((daemon()->volume()+m_volume)/2);
+#endif
+ pa_operation_unref(
+ pa_context_play_sample(daemon()->context(),
+ m_name.constData(),
+ 0,
+ m_vol,
+ play_callback,
+ this)
+ );
+ daemon()->unlock();
+
+ m_playbackTime.start();
+
+ emit stateChanged(m_state = QMediaPlayer::PlayingState);
+}
+
+void QSoundEffectPrivate::stop()
+{
+ emit stateChanged(m_state = QMediaPlayer::StoppedState);
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_volume = volume;
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+}
+
+void QSoundEffectPrivate::setMedia(const QMediaContent &media)
+{
+ if (media.isNull()) {
+ m_media = QMediaContent();
+ unloadSample();
+ return;
+ }
+ if (m_media == media)
+ return;
+ m_media = media;
+
+ if (m_networkAccessManager == 0)
+ m_networkAccessManager = new QNetworkAccessManager(this);
+
+ m_stream = m_networkAccessManager->get(QNetworkRequest(m_media.canonicalUrl()));
+
+ unloadSample();
+ loadSample();
+
+ emit mediaChanged(m_media);
+}
+
+void QSoundEffectPrivate::decoderReady()
+{
+ if (m_waveDecoder->size() >= PA_SCACHE_ENTRY_SIZE_MAX) {
+ m_status = QMediaPlayer::InvalidMedia;
+ emit mediaStatusChanged(m_status);
+ qWarning("QtPulseAudio: attempting to load to large a sample");
+ return;
+ }
+
+ if (m_name.isNull())
+ m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
+
+ pa_sample_spec spec = audioFormatToSampleSpec(m_waveDecoder->audioFormat());
+
+ daemon()->lock();
+ pa_stream *stream = pa_stream_new(daemon()->context(), m_name.constData(), &spec, 0);
+ pa_stream_set_state_callback(stream, stream_state_callback, this);
+ pa_stream_set_write_callback(stream, stream_write_callback, this);
+ pa_stream_connect_upload(stream, (size_t)m_waveDecoder->size());
+ daemon()->unlock();
+}
+
+void QSoundEffectPrivate::decoderError()
+{
+ emit mediaStatusChanged(m_status = QMediaPlayer::InvalidMedia);
+}
+
+void QSoundEffectPrivate::checkPlayTime()
+{
+ int elapsed = m_playbackTime.elapsed();
+
+ if (elapsed >= m_duration) {
+ m_state = QMediaPlayer::StoppedState;
+ emit stateChanged(m_state);
+ }
+ else
+ startTimer(m_duration - elapsed);
+}
+
+void QSoundEffectPrivate::loadSample()
+{
+ m_waveDecoder = new WaveDecoder(m_stream);
+ connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady()));
+ connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError()));
+
+ m_status = QMediaPlayer::LoadingMedia;
+ emit mediaStatusChanged(m_status);
+}
+
+void QSoundEffectPrivate::unloadSample()
+{
+ if (m_status != QMediaPlayer::BufferedMedia)
+ return;
+
+ m_status = QMediaPlayer::NoMedia;
+
+ daemon()->lock();
+ pa_context_remove_sample(daemon()->context(), m_name.constData(), NULL, NULL);
+ daemon()->unlock();
+
+ m_duration = 0;
+ m_dataUploaded = 0;
+}
+
+void QSoundEffectPrivate::timerEvent(QTimerEvent *event)
+{
+ if (m_state == QMediaPlayer::PlayingState) {
+ m_state = QMediaPlayer::StoppedState;
+ emit stateChanged(m_state);
+ }
+
+ killTimer(event->timerId());
+}
+
+void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata)
+{
+ Q_UNUSED(length);
+
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+
+ size_t bufferSize = qMin(pa_stream_writable_size(s),
+ size_t(self->m_waveDecoder->bytesAvailable()));
+ char buffer[bufferSize];
+
+ size_t len = 0;
+ while (len < length) {
+ qint64 read = self->m_waveDecoder->read(buffer, qMin(bufferSize, length -len));
+ if (read > 0) {
+ if (pa_stream_write(s, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0)
+ len += size_t(read);
+ else
+ break;
+ }
+ }
+ self->m_dataUploaded += len;
+
+ if (self->m_waveDecoder->size() == self->m_dataUploaded) {
+ pa_stream_finish_upload(s);
+
+ self->m_duration = self->m_waveDecoder->duration();
+ emit self->durationChanged(self->m_duration);
+
+ self->m_status = QMediaPlayer::BufferedMedia;
+ emit self->mediaStatusChanged(self->m_status);
+
+ self->m_waveDecoder->deleteLater();
+ if (!self->m_media.isNull())
+ self->m_stream->deleteLater();
+
+ if (self->m_playQueued) {
+ self->m_playQueued = false;
+ QMetaObject::invokeMethod(self, "play");
+ }
+ }
+}
+
+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_CREATING:
+ case PA_STREAM_READY:
+ case PA_STREAM_TERMINATED:
+ break;
+
+ case PA_STREAM_FAILED:
+ default:
+ self->m_status = QMediaPlayer::InvalidMedia;
+ emit self->mediaStatusChanged(self->m_status);
+ break;
+ }
+}
+
+void QSoundEffectPrivate::play_callback(pa_context *c, int success, void *userdata)
+{
+ Q_UNUSED(c);
+
+ QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata);
+
+ if (success == 1)
+ QMetaObject::invokeMethod(self, "checkPlayTime", Qt::QueuedConnection);
+ else {
+ self->m_state = QMediaPlayer::StoppedState;
+ emit self->stateChanged(self->m_state);
+ }
+}
+
diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.h b/src/multimedia/qml/qsoundeffect_pulse_p.h
new file mode 100644
index 0000000..58a05d2
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_pulse_p.h
@@ -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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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 <QtMultimedia/qmediaplayer.h>
+#include <pulse/pulseaudio.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkReply;
+class QNetworkAccessManager;
+class WaveDecoder;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ qint64 duration() const;
+ int volume() const;
+ bool isMuted() const;
+ QMediaContent media() const;
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+ void setVolume(int volume);
+ void setMuted(bool muted);
+ void setMedia(const QMediaContent &media);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent &media);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void stateChanged(QMediaPlayer::State newState);
+ void durationChanged(qint64 duration);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(QMediaPlayer::Error error);
+
+private slots:
+ void decoderReady();
+ void decoderError();
+ void checkPlayTime();
+
+private:
+ void loadSample();
+ void unloadSample();
+
+ void timerEvent(QTimerEvent *event);
+
+ 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 play_callback(pa_context *c, int success, void *userdata);
+
+ bool m_muted;
+ bool m_playQueued;
+ int m_volume;
+ int m_duration;
+ int m_dataUploaded;
+ QTime m_playbackTime;
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_status;
+ QByteArray m_name;
+ QMediaContent m_media;
+ QNetworkReply *m_reply;
+ WaveDecoder *m_waveDecoder;
+ QIODevice *m_stream;
+ QNetworkAccessManager *m_networkAccessManager;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_PULSE_H
diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.cpp b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp
new file mode 100644
index 0000000..e5ac0d3
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp
@@ -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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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.
+//
+
+#include <QtCore/qcoreapplication.h>
+
+#include "qmediacontent.h"
+#include "qmediaplayer.h"
+
+#include "qsoundeffect_p.h"
+#include "qsoundeffect_qmedia_p.h"
+
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_muted(false),
+ m_volume(100),
+ m_player(0)
+{
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+ if (m_player) delete m_player;
+}
+
+qint64 QSoundEffectPrivate::duration() const
+{
+ if (m_player) return m_player->duration();
+
+ return 0;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ if (m_player) return m_player->volume();
+
+ return m_volume;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ if (m_player) return m_player->isMuted();
+
+ return m_muted;
+}
+
+QMediaContent QSoundEffectPrivate::media() const
+{
+ if (m_player) return m_player->media();
+
+ return QMediaContent();
+}
+
+QMediaPlayer::State QSoundEffectPrivate::state() const
+{
+ if (m_player) return m_player->state();
+
+ return QMediaPlayer::StoppedState;
+}
+
+QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const
+{
+ if (m_player) return m_player->mediaStatus();
+
+ return QMediaPlayer::UnknownMediaStatus;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_player && !m_player->isMuted())
+ m_player->play();
+}
+
+void QSoundEffectPrivate::stop()
+{
+ if (m_player)
+ m_player->stop();
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ m_volume = volume;
+
+ if (m_player)
+ m_player->setVolume(volume);
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+
+ if (m_player)
+ m_player->setMuted(muted);
+}
+
+void QSoundEffectPrivate::setMedia(const QMediaContent &media)
+{
+ if (media.isNull())
+ return;
+
+ if (m_player == 0) {
+ m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency);
+ m_player->setVolume(m_volume);
+ m_player->setMuted(m_muted);
+
+ connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
+ connect(m_player, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
+ connect(m_player, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
+ connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SIGNAL(stateChanged(QMediaPlayer::State)));
+ }
+
+ m_player->setMedia(media.canonicalUrl());
+}
+
diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.h b/src/multimedia/qml/qsoundeffect_qmedia_p.h
new file mode 100644
index 0000000..e17d720
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_qmedia_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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 <QtMultimedia/qmediaplayer.h>
+#include "qsoundeffect_p.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class WaveDecoder;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ qint64 duration() const;
+ int volume() const;
+ bool isMuted() const;
+ QMediaContent media() const;
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+ void setVolume(int volume);
+ void setMuted(bool muted);
+ void setMedia(const QMediaContent &media);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent &media);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void stateChanged(QMediaPlayer::State newState);
+ void durationChanged(qint64 duration);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(QMediaPlayer::Error error);
+
+private:
+ bool m_muted;
+ int m_volume;
+ QMediaPlayer *m_player;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QMEDIA_H
diff --git a/src/multimedia/qml/qsoundeffect_qsound_p.cpp b/src/multimedia/qml/qsoundeffect_qsound_p.cpp
new file mode 100644
index 0000000..0292d26
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_qsound_p.cpp
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** 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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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.
+//
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qfile.h>
+#include <QtGui/qsound.h>
+#include <QtMultimedia/qaudioformat.h>
+#include <QDebug>
+
+#include "qmediacontent.h"
+#include "qmediaplayer.h"
+#include "qsoundeffect_p.h"
+
+#include "wavedecoder_p.h"
+
+#include "qsoundeffect_qsound_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent):
+ QObject(parent),
+ m_queued(false),
+ m_muted(false),
+ m_state(QMediaPlayer::StoppedState),
+ m_status(QMediaPlayer::NoMedia),
+ m_file(0),
+ m_sound(0)
+{
+ m_timer = new QTimer(this);
+ connect(m_timer,SIGNAL(timeout()),SLOT(checkPlayTime()));
+ m_media = QMediaContent();
+}
+
+QSoundEffectPrivate::~QSoundEffectPrivate()
+{
+ if (m_sound) delete m_sound;
+ if (m_waveDecoder) delete m_waveDecoder;
+ m_file->close();
+}
+
+qint64 QSoundEffectPrivate::duration() const
+{
+ if (m_waveDecoder)
+ return m_waveDecoder->size();
+
+ return 0;
+}
+
+int QSoundEffectPrivate::volume() const
+{
+ return 100;
+}
+
+bool QSoundEffectPrivate::isMuted() const
+{
+ return m_muted;
+}
+
+QMediaContent QSoundEffectPrivate::media() const
+{
+ return m_media;
+}
+
+QMediaPlayer::State QSoundEffectPrivate::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const
+{
+ return m_status;
+}
+
+void QSoundEffectPrivate::play()
+{
+ if (m_sound && !m_muted) {
+ m_queued = false;
+ m_timer->start(20);
+ m_playbackTime.start();
+ m_sound->play();
+ emit stateChanged(m_state = QMediaPlayer::PlayingState);
+ } else if (m_status == QMediaPlayer::LoadingMedia)
+ m_queued = true;
+}
+
+void QSoundEffectPrivate::stop()
+{
+ m_timer->stop();
+
+ if (m_sound) {
+ m_sound->stop();
+ emit stateChanged(m_state = QMediaPlayer::StoppedState);
+ }
+}
+
+void QSoundEffectPrivate::setVolume(int volume)
+{
+ Q_UNUSED(volume)
+}
+
+void QSoundEffectPrivate::setMuted(bool muted)
+{
+ m_muted = muted;
+}
+
+void QSoundEffectPrivate::setMedia(const QMediaContent &media)
+{
+ m_queued = false;
+
+ if (media.isNull() || media.canonicalUrl().scheme() != "file") {
+ m_media = QMediaContent();
+ return;
+ }
+ if (m_media == media)
+ return;
+
+ m_media = media;
+ m_file = new QFile(m_media.canonicalUrl().toLocalFile());
+ m_file->open(QIODevice::ReadOnly|QIODevice::Unbuffered);
+
+ unloadSample();
+ loadSample();
+
+ emit mediaChanged(m_media);
+}
+
+void QSoundEffectPrivate::decoderReady()
+{
+ m_file->close();
+ m_sound = new QSound(m_media.canonicalUrl().toLocalFile());
+ emit mediaStatusChanged(m_status = QMediaPlayer::LoadedMedia);
+
+ if (m_queued)
+ play();
+}
+
+void QSoundEffectPrivate::decoderError()
+{
+ m_file->close();
+ emit mediaStatusChanged(m_status = QMediaPlayer::InvalidMedia);
+}
+
+void QSoundEffectPrivate::checkPlayTime()
+{
+ if (m_sound->isFinished()) {
+ m_timer->stop();
+ m_state = QMediaPlayer::StoppedState;
+ emit stateChanged(m_state);
+ }
+}
+
+void QSoundEffectPrivate::loadSample()
+{
+ m_waveDecoder = new WaveDecoder(m_file);
+ connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady()));
+ connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError()));
+
+ m_status = QMediaPlayer::LoadingMedia;
+ emit mediaStatusChanged(m_status);
+}
+
+void QSoundEffectPrivate::unloadSample()
+{
+ if (m_sound == 0)
+ return;
+
+ m_status = QMediaPlayer::NoMedia;
+
+ if (m_sound)
+ delete m_sound;
+
+ m_sound = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/qml/qsoundeffect_qsound_p.h b/src/multimedia/qml/qsoundeffect_qsound_p.h
new file mode 100644
index 0000000..45c0888
--- /dev/null
+++ b/src/multimedia/qml/qsoundeffect_qsound_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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/qdatetime.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+#include "qsoundeffect_p.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QTimer;
+class QSound;
+class QFile;
+class WaveDecoder;
+
+class QSoundEffectPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QSoundEffectPrivate(QObject* parent);
+ ~QSoundEffectPrivate();
+
+ qint64 duration() const;
+ int volume() const;
+ bool isMuted() const;
+ QMediaContent media() const;
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+ void setVolume(int volume);
+ void setMuted(bool muted);
+ void setMedia(const QMediaContent &media);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent &media);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void stateChanged(QMediaPlayer::State newState);
+ void durationChanged(qint64 duration);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(QMediaPlayer::Error error);
+
+private slots:
+ void decoderReady();
+ void decoderError();
+ void checkPlayTime();
+
+private:
+ void loadSample();
+ void unloadSample();
+
+ bool m_queued;
+ bool m_muted;
+ QTime m_playbackTime;
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_status;
+ QFile *m_file;
+ QByteArray m_name;
+ QMediaContent m_media;
+ WaveDecoder *m_waveDecoder;
+ QSound *m_sound;
+ QTimer *m_timer;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUNDEFFECT_QSOUND_H
diff --git a/src/multimedia/qml/wavedecoder_p.cpp b/src/multimedia/qml/wavedecoder_p.cpp
new file mode 100644
index 0000000..b7d6101
--- /dev/null
+++ b/src/multimedia/qml/wavedecoder_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "wavedecoder_p.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qendian.h>
+
+QT_BEGIN_NAMESPACE
+
+WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent):
+ QIODevice(parent),
+ haveFormat(false),
+ dataSize(0),
+ remaining(0),
+ source(s)
+{
+ open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+
+ if (source->bytesAvailable() >= sizeof(CombinedHeader))
+ QTimer::singleShot(0, this, SLOT(handleData()));
+ else
+ connect(source, SIGNAL(readyRead()), SLOT(handleData()));
+}
+
+WaveDecoder::~WaveDecoder()
+{
+}
+
+QAudioFormat WaveDecoder::audioFormat() const
+{
+ return format;
+}
+
+int WaveDecoder::duration() const
+{
+ return size() * 1000 / (format.sampleSize() / 8) / format.channels() / format.frequency();
+}
+
+qint64 WaveDecoder::size() const
+{
+ return haveFormat ? dataSize : 0;
+}
+
+bool WaveDecoder::isSequential() const
+{
+ return source->isSequential();
+}
+
+qint64 WaveDecoder::bytesAvailable() const
+{
+ return haveFormat ? source->bytesAvailable() : 0;
+}
+
+qint64 WaveDecoder::readData(char *data, qint64 maxlen)
+{
+ return haveFormat ? source->read(data, maxlen) : 0;
+}
+
+qint64 WaveDecoder::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return -1;
+}
+
+void WaveDecoder::handleData()
+{
+ if (source->bytesAvailable() < sizeof(CombinedHeader))
+ return;
+
+ source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
+ source->read((char*)&header, sizeof(CombinedHeader));
+
+ if (qstrncmp(header.riff.descriptor.id, "RIFF", 4) != 0 ||
+ qstrncmp(header.riff.type, "WAVE", 4) != 0 ||
+ qstrncmp(header.wave.descriptor.id, "fmt ", 4) != 0 ||
+ (header.wave.audioFormat != 0 && header.wave.audioFormat != 1) ||
+ qstrncmp(header.data.descriptor.id, "data", 4) != 0) {
+
+ emit invalidFormat();
+ }
+ else {
+ int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
+
+ format.setCodec("audio/pcm");
+ format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate));
+ format.setSampleSize(bps);
+ format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
+
+ dataSize = qFromLittleEndian<quint32>(header.data.descriptor.size);
+
+ haveFormat = true;
+ connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
+ emit formatKnown();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/qml/wavedecoder_p.h b/src/multimedia/qml/wavedecoder_p.h
new file mode 100644
index 0000000..3bcd90d
--- /dev/null
+++ b/src/multimedia/qml/wavedecoder_p.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 QtMultimedia module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WAVEDECODER_H
+#define WAVEDECODER_H
+
+#include <QtCore/qiodevice.h>
+#include <QtMultimedia/qaudioformat.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+class WaveDecoder : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ explicit WaveDecoder(QIODevice *source, QObject *parent = 0);
+ ~WaveDecoder();
+
+ QAudioFormat audioFormat() const;
+ int duration() const;
+
+ qint64 size() const;
+ bool isSequential() const;
+ qint64 bytesAvailable() const;
+
+signals:
+ void formatKnown();
+ void invalidFormat();
+
+private slots:
+ void handleData();
+
+private:
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+ 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;
+ };
+ struct DATAHeader
+ {
+ chunk descriptor;
+ };
+ struct CombinedHeader
+ {
+ RIFFHeader riff;
+ WAVEHeader wave;
+ DATAHeader data;
+ };
+
+ bool haveFormat;
+ qint64 dataSize;
+ qint64 remaining;
+ QAudioFormat format;
+ QIODevice *source;
+ CombinedHeader header;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // WAVEDECODER_H