summaryrefslogtreecommitdiffstats
path: root/src/plugins/mediaservices/qt7
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/mediaservices/qt7')
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri18
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h128
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm193
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h84
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm261
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h90
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm151
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h147
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm517
-rw-r--r--src/plugins/mediaservices/qt7/qcvdisplaylink.h90
-rw-r--r--src/plugins/mediaservices/qt7/qcvdisplaylink.mm159
-rw-r--r--src/plugins/mediaservices/qt7/qt7.pro45
-rw-r--r--src/plugins/mediaservices/qt7/qt7backend.h68
-rw-r--r--src/plugins/mediaservices/qt7/qt7backend.mm60
-rw-r--r--src/plugins/mediaservices/qt7/qt7movierenderer.h113
-rw-r--r--src/plugins/mediaservices/qt7/qt7movierenderer.mm454
-rw-r--r--src/plugins/mediaservices/qt7/qt7movievideowidget.h132
-rw-r--r--src/plugins/mediaservices/qt7/qt7movievideowidget.mm417
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewoutput.h119
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewoutput.mm312
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewrenderer.h97
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm349
-rw-r--r--src/plugins/mediaservices/qt7/qt7serviceplugin.h64
-rw-r--r--src/plugins/mediaservices/qt7/qt7serviceplugin.mm78
-rw-r--r--src/plugins/mediaservices/qt7/qt7videooutputcontrol.h136
-rw-r--r--src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm93
26 files changed, 4375 insertions, 0 deletions
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri b/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri
new file mode 100644
index 0000000..577209e
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri
@@ -0,0 +1,18 @@
+INCLUDEPATH += $$PWD
+
+DEFINES += QMEDIA_QT7_PLAYER
+
+HEADERS += \
+ $$PWD/qt7playercontrol.h \
+ $$PWD/qt7playermetadata.h \
+ $$PWD/qt7playerservice.h \
+ $$PWD/qt7playersession.h
+
+OBJECTIVE_SOURCES += \
+ $$PWD/qt7playercontrol.mm \
+ $$PWD/qt7playermetadata.mm \
+ $$PWD/qt7playerservice.mm \
+ $$PWD/qt7playersession.mm
+
+
+
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h
new file mode 100644
index 0000000..907d13d
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7PLAYERCONTROL_H
+#define QT7PLAYERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qmacdefines_mac.h>
+
+#include <QtMultimedia/qmediaplayercontrol.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerSession;
+class QT7PlayerService;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+
+class QT7PlayerControl : public QMediaPlayerControl
+{
+Q_OBJECT
+public:
+ QT7PlayerControl(QObject *parent = 0);
+ ~QT7PlayerControl();
+
+ void setSession(QT7PlayerSession *session);
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent &content, QIODevice *stream);
+
+ qint64 position() const;
+ qint64 duration() const;
+
+ int bufferStatus() const;
+
+ int volume() const;
+ bool isMuted() const;
+
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ bool isSeekable() const;
+
+ QMediaTimeRange availablePlaybackRanges() const;
+
+ qreal playbackRate() const;
+ void setPlaybackRate(qreal rate);
+
+public Q_SLOTS:
+ void setPosition(qint64 pos);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent& content);
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void videoAvailableChanged(bool videoAvailable);
+ void bufferStatusChanged(int percentFilled);
+ void seekableChanged(bool);
+ void seekRangeChanged(const QPair<qint64,qint64>&);
+ void playbackRateChanged(qreal rate);
+ void error(int error, const QString &errorString);
+
+private:
+ QT7PlayerSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm
new file mode 100644
index 0000000..0f4ac41
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 "qt7playercontrol.h"
+#include "qt7playersession.h"
+
+#include <QtMultimedia/qmediaplaylistnavigator.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QT7PlayerControl::QT7PlayerControl(QObject *parent)
+ : QMediaPlayerControl(parent)
+{
+}
+
+QT7PlayerControl::~QT7PlayerControl()
+{
+}
+
+void QT7PlayerControl::setSession(QT7PlayerSession *session)
+{
+ m_session = session;
+
+ connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
+ connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+ connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SIGNAL(stateChanged(QMediaPlayer::State)));
+ connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
+ connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
+ connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool)));
+ connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool)));
+ connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+}
+
+qint64 QT7PlayerControl::position() const
+{
+ return m_session->position();
+}
+
+qint64 QT7PlayerControl::duration() const
+{
+ return m_session->duration();
+}
+
+QMediaPlayer::State QT7PlayerControl::state() const
+{
+ return m_session->state();
+}
+
+QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const
+{
+ return m_session->mediaStatus();
+}
+
+int QT7PlayerControl::bufferStatus() const
+{
+ return m_session->bufferStatus();
+}
+
+int QT7PlayerControl::volume() const
+{
+ return m_session->volume();
+}
+
+bool QT7PlayerControl::isMuted() const
+{
+ return m_session->isMuted();
+}
+
+bool QT7PlayerControl::isSeekable() const
+{
+ return m_session->isSeekable();
+}
+
+QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const
+{
+ return isSeekable() ? QMediaTimeRange(0, duration()) : QMediaTimeRange();
+}
+
+qreal QT7PlayerControl::playbackRate() const
+{
+ return m_session->playbackRate();
+}
+
+void QT7PlayerControl::setPlaybackRate(qreal rate)
+{
+ m_session->setPlaybackRate(rate);
+}
+
+void QT7PlayerControl::setPosition(qint64 pos)
+{
+ m_session->setPosition(pos);
+}
+
+void QT7PlayerControl::play()
+{
+ m_session->play();
+}
+
+void QT7PlayerControl::pause()
+{
+ m_session->pause();
+}
+
+void QT7PlayerControl::stop()
+{
+ m_session->stop();
+}
+
+void QT7PlayerControl::setVolume(int volume)
+{
+ m_session->setVolume(volume);
+}
+
+void QT7PlayerControl::setMuted(bool muted)
+{
+ m_session->setMuted(muted);
+}
+
+QMediaContent QT7PlayerControl::media() const
+{
+ return m_session->media();
+}
+
+const QIODevice *QT7PlayerControl::mediaStream() const
+{
+ return m_session->mediaStream();
+}
+
+void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+ m_session->setMedia(content, stream);
+
+ emit mediaChanged(content);
+}
+
+bool QT7PlayerControl::isAudioAvailable() const
+{
+ return m_session->isAudioAvailable();
+}
+
+bool QT7PlayerControl::isVideoAvailable() const
+{
+ return m_session->isVideoAvailable();
+}
+
+#include "moc_qt7playercontrol.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h
new file mode 100644
index 0000000..f16807a
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7PLAYERMETADATACONTROL_H
+#define QT7PLAYERMETADATACONTROL_H
+
+#include <QtMultimedia/qmetadatacontrol.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerSession;
+
+class QT7PlayerMetaDataControl : public QMetaDataControl
+{
+ Q_OBJECT
+public:
+ QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent);
+ virtual ~QT7PlayerMetaDataControl();
+
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+
+ QVariant metaData(QtMultimedia::MetaData key) const;
+ void setMetaData(QtMultimedia::MetaData key, const QVariant &value);
+ QList<QtMultimedia::MetaData> availableMetaData() const;
+
+ QVariant extendedMetaData(const QString &key) const ;
+ void setExtendedMetaData(const QString &key, const QVariant &value);
+ QStringList availableExtendedMetaData() const;
+
+private slots:
+ void updateTags();
+
+private:
+ QT7PlayerSession *m_session;
+ QMap<QtMultimedia::MetaData, QVariant> m_tags;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm
new file mode 100644
index 0000000..a14981a
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 "qt7backend.h"
+#include "qt7playermetadata.h"
+#include "qt7playersession.h"
+#include <QtCore/qvarlengtharray.h>
+
+#import <QTKit/QTMovie.h>
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ #include <QuickTime/QuickTime.h>
+ #undef check // avoid name clash;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent)
+ :QMetaDataControl(parent), m_session(session)
+{
+}
+
+QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl()
+{
+}
+
+bool QT7PlayerMetaDataControl::isMetaDataAvailable() const
+{
+ return !m_tags.isEmpty();
+}
+
+bool QT7PlayerMetaDataControl::isWritable() const
+{
+ return false;
+}
+
+QVariant QT7PlayerMetaDataControl::metaData(QtMultimedia::MetaData key) const
+{
+ return m_tags.value(key);
+}
+
+void QT7PlayerMetaDataControl::setMetaData(QtMultimedia::MetaData key, QVariant const &value)
+{
+ Q_UNUSED(key);
+ Q_UNUSED(value);
+}
+
+QList<QtMultimedia::MetaData> QT7PlayerMetaDataControl::availableMetaData() const
+{
+ return m_tags.keys();
+}
+
+QVariant QT7PlayerMetaDataControl::extendedMetaData(const QString &key) const
+{
+ Q_UNUSED(key);
+ return QVariant();
+}
+
+void QT7PlayerMetaDataControl::setExtendedMetaData(const QString &key, QVariant const &value)
+{
+ Q_UNUSED(key);
+ Q_UNUSED(value);
+}
+
+QStringList QT7PlayerMetaDataControl::availableExtendedMetaData() const
+{
+ return QStringList();
+}
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+
+static QString stripCopyRightSymbol(const QString &key)
+{
+ return key.right(key.length()-1);
+}
+
+static QString convertQuickTimeKeyToUserKey(const QString &key)
+{
+ if (key == QLatin1String("com.apple.quicktime.displayname"))
+ return QLatin1String("nam");
+ else if (key == QLatin1String("com.apple.quicktime.album"))
+ return QLatin1String("alb");
+ else if (key == QLatin1String("com.apple.quicktime.artist"))
+ return QLatin1String("ART");
+ else
+ return QLatin1String("???");
+}
+
+static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
+ QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
+{
+ QTPropertyValueType type;
+ ByteCount propSize;
+ UInt32 propFlags;
+ OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
+
+
+ *value = malloc(propSize);
+
+ err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
+
+ if (type == 'code' || type == 'itsk' || type == 'itlk') {
+ // convert from native endian to big endian
+ OSTypePtr pType = (OSTypePtr)*value;
+ *pType = EndianU32_NtoB(*pType);
+ }
+
+ return err;
+}
+
+static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
+{
+ QTPropertyValuePtr value = 0;
+ ByteCount ignore = 0;
+ OSStatus err = readMetaValue(
+ metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
+
+ UInt32 type = *((UInt32 *) value);
+ if (value)
+ free(value);
+ return type;
+}
+
+static QString cFStringToQString(CFStringRef str)
+{
+ if(!str)
+ return QString();
+ CFIndex length = CFStringGetLength(str);
+ const UniChar *chars = CFStringGetCharactersPtr(str);
+ if (chars)
+ return QString(reinterpret_cast<const QChar *>(chars), length);
+
+ QVarLengthArray<UniChar> buffer(length);
+ CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
+ return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
+}
+
+
+static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
+{
+ QTPropertyValuePtr value = 0;
+ ByteCount size = 0;
+ OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
+
+ QString string;
+ UInt32 dataType = getMetaType(metaDataRef, item);
+ switch (dataType){
+ case kQTMetaDataTypeUTF8:
+ case kQTMetaDataTypeMacEncodedText:
+ string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
+ break;
+ case kQTMetaDataTypeUTF16BE:
+ string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
+ break;
+ default:
+ break;
+ }
+
+ if (value)
+ free(value);
+ return string;
+}
+
+
+static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
+{
+ QTMetaDataItem item = kQTMetaDataItemUninitialized;
+ OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
+ while (err == noErr){
+ QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
+ if (format == kQTMetaDataStorageFormatQuickTime)
+ key = convertQuickTimeKeyToUserKey(key);
+ else
+ key = stripCopyRightSymbol(key);
+
+ if (!result.contains(key)){
+ QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
+ result.insert(key, val);
+ }
+ err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
+ }
+}
+#endif
+
+
+void QT7PlayerMetaDataControl::updateTags()
+{
+ bool wasEmpty = m_tags.isEmpty();
+ m_tags.clear();
+
+ QTMovie *movie = (QTMovie*)m_session->movie();
+
+ if (movie) {
+ QMultiMap<QString, QString> metaMap;
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ QTMetaDataRef metaDataRef;
+ OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef);
+
+ readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
+ readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
+ readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
+#else
+ NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"];
+ metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
+#endif // QUICKTIME_C_API_AVAILABLE
+
+ m_tags.insert(QtMultimedia::AlbumArtist, metaMap.value(QLatin1String("ART")));
+ m_tags.insert(QtMultimedia::AlbumTitle, metaMap.value(QLatin1String("alb")));
+ m_tags.insert(QtMultimedia::Title, metaMap.value(QLatin1String("nam")));
+ m_tags.insert(QtMultimedia::Date, metaMap.value(QLatin1String("day")));
+ m_tags.insert(QtMultimedia::Genre, metaMap.value(QLatin1String("gnre")));
+ m_tags.insert(QtMultimedia::TrackNumber, metaMap.value(QLatin1String("trk")));
+ m_tags.insert(QtMultimedia::Description, metaMap.value(QLatin1String("des")));
+ }
+
+ if (!wasEmpty || !m_tags.isEmpty())
+ emit metaDataChanged();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qt7playermetadata.cpp"
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h
new file mode 100644
index 0000000..d4b30b8
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7PLAYERSERVICE_H
+#define QT7PLAYERSERVICE_H
+
+#include <QtCore/qobject.h>
+#include <QtMultimedia/qmediaservice.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaMetaData;
+class QMediaPlayerControl;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+class QT7PlayerControl;
+class QT7PlayerMetaDataControl;
+class QT7VideoOutputControl;
+class QT7VideoWindowControl;
+class QT7VideoWidgetControl;
+class QT7VideoRendererControl;
+class QT7VideoOutput;
+class QT7PlayerSession;
+
+class QT7PlayerService : public QMediaService
+{
+Q_OBJECT
+public:
+ QT7PlayerService(QObject *parent = 0);
+ ~QT7PlayerService();
+
+ QMediaControl *control(const char *name) const;
+
+private slots:
+ void updateVideoOutput();
+
+private:
+ QT7PlayerSession *m_session;
+ QT7PlayerControl *m_control;
+ QT7VideoOutputControl *m_videoOutputControl;
+ QT7VideoWindowControl *m_videoWidnowControl;
+ QT7VideoWidgetControl *m_videoWidgetControl;
+ QT7VideoRendererControl *m_videoRendererControl;
+ QT7PlayerMetaDataControl *m_playerMetaDataControl;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm
new file mode 100644
index 0000000..df15fa8
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 <QtCore/qvariant.h>
+#include <QtCore/qdebug.h>
+#include <QtGui/qwidget.h>
+
+#include "qt7backend.h"
+#include "qt7playerservice.h"
+#include "qt7playercontrol.h"
+#include "qt7playersession.h"
+#include "qt7videooutputcontrol.h"
+#include "qt7movieviewoutput.h"
+#include "qt7movieviewrenderer.h"
+#include "qt7movierenderer.h"
+#include "qt7movievideowidget.h"
+#include "qt7playermetadata.h"
+
+#include <QtMultimedia/qmediaplaylistnavigator.h>
+#include <QtMultimedia/qmediaplaylist.h>
+
+QT_BEGIN_NAMESPACE
+
+QT7PlayerService::QT7PlayerService(QObject *parent):
+ QMediaService(parent)
+{
+ m_session = new QT7PlayerSession;
+
+ m_control = new QT7PlayerControl(this);
+ m_control->setSession(m_session);
+
+ m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this);
+ connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
+
+ m_videoOutputControl = new QT7VideoOutputControl(this);
+
+ m_videoWidnowControl = 0;
+ m_videoWidgetControl = 0;
+ m_videoRendererControl = 0;
+
+#if defined(QT_MAC_USE_COCOA)
+ m_videoWidnowControl = new QT7MovieViewOutput(this);
+ m_videoOutputControl->enableOutput(QVideoOutputControl::WindowOutput);
+ qDebug() << "Using cocoa";
+#endif
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ m_videoRendererControl = new QT7MovieRenderer(this);
+ m_videoOutputControl->enableOutput(QVideoOutputControl::RendererOutput);
+
+ m_videoWidgetControl = new QT7MovieVideoWidget(this);
+ m_videoOutputControl->enableOutput(QVideoOutputControl::WidgetOutput);
+ qDebug() << "QuickTime C API is available";
+#else
+ m_videoRendererControl = new QT7MovieViewRenderer(this);
+ m_videoOutputControl->enableOutput(QVideoOutputControl::RendererOutput);
+ qDebug() << "QuickTime C API is not available";
+#endif
+
+
+ connect(m_videoOutputControl, SIGNAL(videoOutputChanged(QVideoOutputControl::Output)),
+ this, SLOT(updateVideoOutput()));
+}
+
+QT7PlayerService::~QT7PlayerService()
+{
+}
+
+QMediaControl *QT7PlayerService::control(const char *name) const
+{
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+ return m_control;
+
+ if (qstrcmp(name, QVideoOutputControl_iid) == 0)
+ return m_videoOutputControl;
+
+ if (qstrcmp(name, QVideoWindowControl_iid) == 0)
+ return m_videoWidnowControl;
+
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0)
+ return m_videoRendererControl;
+
+ if (qstrcmp(name, QVideoWidgetControl_iid) == 0)
+ return m_videoWidgetControl;
+
+ if (qstrcmp(name, QMetaDataControl_iid) == 0)
+ return m_playerMetaDataControl;
+
+ return 0;
+}
+
+void QT7PlayerService::updateVideoOutput()
+{
+ qDebug() << "QT7PlayerService::updateVideoOutput" << m_videoOutputControl->output();
+
+ switch (m_videoOutputControl->output()) {
+ case QVideoOutputControl::WindowOutput:
+ m_session->setVideoOutput(m_videoWidnowControl);
+ break;
+ case QVideoOutputControl::RendererOutput:
+ m_session->setVideoOutput(m_videoRendererControl);
+ break;
+ case QVideoOutputControl::WidgetOutput:
+ m_session->setVideoOutput(m_videoWidgetControl);
+ break;
+ default:
+ m_session->setVideoOutput(0);
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qt7playerservice.cpp"
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h
new file mode 100644
index 0000000..4742e2e
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7PLAYERSESSION_H
+#define QT7PLAYERSESSION_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qmacdefines_mac.h>
+
+#include <QtMultimedia/qmediaplayercontrol.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerControl;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+class QT7VideoOutput;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+class QT7PlayerSession : public QObject
+{
+Q_OBJECT
+public:
+ QT7PlayerSession(QObject *parent = 0);
+ ~QT7PlayerSession();
+
+ void *movie() const;
+
+ void setControl(QT7PlayerControl *control);
+ void setVideoOutput(QT7VideoOutput *output);
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent &content, QIODevice *stream);
+
+ qint64 position() const;
+ qint64 duration() const;
+
+ int bufferStatus() const;
+
+ int volume() const;
+ bool isMuted() const;
+
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ bool isSeekable() const;
+
+ qreal playbackRate() const;
+
+public slots:
+ void setPlaybackRate(qreal rate);
+
+ void setPosition(qint64 pos);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void processEOS();
+ void processStateChange();
+ void processVolumeChange();
+ void processNaturalSizeChange();
+
+signals:
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool audioAvailable);
+ void videoAvailableChanged(bool videoAvailable);
+ void error(int error, const QString &errorString);
+
+private:
+ void *m_QTMovie;
+ void *m_movieObserver;
+
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ QIODevice *m_mediaStream;
+ QMediaContent m_resources;
+
+ QT7VideoOutput *m_videoOutput;
+
+ mutable qint64 m_currentTime;
+
+ bool m_muted;
+ int m_volume;
+ qreal m_rate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm
new file mode 100644
index 0000000..5507633
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm
@@ -0,0 +1,517 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#import <QTKit/QTDataReference.h>
+#import <QTKit/QTMovie.h>
+
+#include "qt7backend.h"
+
+#include "qt7playersession.h"
+#include "qt7playercontrol.h"
+#include "qt7videooutputcontrol.h"
+
+#include <QtMultimedia/qmediaplaylistnavigator.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+
+@interface QTMovieObserver : NSObject
+{
+@private
+ QT7PlayerSession *m_session;
+ QTMovie *m_movie;
+}
+
+- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session;
+- (void) setMovie:(QTMovie *)movie;
+- (void) processEOS:(NSNotification *)notification;
+- (void) processStateChange:(NSNotification *)notification;
+@end
+
+@implementation QTMovieObserver
+
+- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session
+{
+ if (!(self = [super init]))
+ return nil;
+
+ self->m_session = session;
+ return self;
+}
+
+- (void) setMovie:(QTMovie *)movie
+{
+ if (m_movie == movie)
+ return;
+
+ if (m_movie) {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [m_movie release];
+ }
+
+ m_movie = movie;
+
+ if (movie) {
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(processEOS:)
+ name:QTMovieDidEndNotification
+ object:m_movie];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(processStateChange:)
+ name:QTMovieLoadStateDidChangeNotification
+ object:m_movie];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(processVolumeChange:)
+ name:QTMovieVolumeDidChangeNotification
+ object:m_movie];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(processNaturalSizeChange:)
+ name:
+#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
+ QTMovieNaturalSizeDidChangeNotification
+#else
+ QTMovieEditedNotification
+#endif
+ object:m_movie];
+ [movie retain];
+ }
+}
+
+- (void) processEOS:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ m_session->processEOS();
+}
+
+- (void) processStateChange:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ m_session->processStateChange();
+}
+
+- (void) processVolumeChange:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ m_session->processVolumeChange();
+}
+
+- (void) processNaturalSizeChange :(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ m_session->processNaturalSizeChange();
+}
+
+@end
+
+static CFStringRef qString2CFStringRef(const QString &string)
+{
+ return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(string.unicode()),
+ string.length());
+}
+
+QT7PlayerSession::QT7PlayerSession(QObject *parent)
+ : QObject(parent)
+ , m_QTMovie(0)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_mediaStream(0)
+ , m_videoOutput(0)
+ , m_muted(false)
+ , m_volume(100)
+ , m_rate(1.0)
+{
+ m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this];
+}
+
+QT7PlayerSession::~QT7PlayerSession()
+{
+ [(QTMovieObserver*)m_movieObserver setMovie:nil];
+ [(QTMovieObserver*)m_movieObserver release];
+}
+
+void *QT7PlayerSession::movie() const
+{
+ return m_QTMovie;
+}
+
+void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output)
+{
+ if (m_videoOutput == output)
+ return;
+
+ if (m_videoOutput) {
+ m_videoOutput->setEnabled(false);
+ m_videoOutput->setMovie(0);
+ }
+
+ m_videoOutput = output;
+
+ if (m_videoOutput) {
+ m_videoOutput->setEnabled(m_QTMovie != 0);
+ m_videoOutput->setMovie(m_QTMovie);
+ }
+}
+
+
+qint64 QT7PlayerSession::position() const
+{
+ if (!m_QTMovie || m_state == QMediaPlayer::PausedState)
+ return m_currentTime;
+
+ AutoReleasePool pool;
+
+ QTTime qtTime = [(QTMovie*)m_QTMovie currentTime];
+ quint64 t = static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
+ m_currentTime = t;
+
+ return m_currentTime;
+}
+
+qint64 QT7PlayerSession::duration() const
+{
+ if (!m_QTMovie)
+ return 0;
+
+ AutoReleasePool pool;
+
+ QTTime qtTime = [(QTMovie*)m_QTMovie duration];
+
+ return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
+}
+
+QMediaPlayer::State QT7PlayerSession::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const
+{
+ return m_mediaStatus;
+}
+
+int QT7PlayerSession::bufferStatus() const
+{
+ return 100;
+}
+
+int QT7PlayerSession::volume() const
+{
+ return m_volume;
+}
+
+bool QT7PlayerSession::isMuted() const
+{
+ return m_muted;
+}
+
+bool QT7PlayerSession::isSeekable() const
+{
+ return true;
+}
+
+qreal QT7PlayerSession::playbackRate() const
+{
+ return m_rate;
+}
+
+void QT7PlayerSession::setPlaybackRate(qreal rate)
+{
+ if (qFuzzyCompare(m_rate, rate))
+ return;
+
+ m_rate = rate;
+
+ if (m_QTMovie && m_state == QMediaPlayer::PlayingState) {
+ float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+ [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate];
+ }
+}
+
+void QT7PlayerSession::setPosition(qint64 pos)
+{
+ if ( !isSeekable() || pos == position())
+ return;
+
+ AutoReleasePool pool;
+
+ pos = qMin(pos, duration());
+
+ QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime];
+ newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale;
+ [(QTMovie*)m_QTMovie setCurrentTime:newQTTime];
+}
+
+void QT7PlayerSession::play()
+{
+ float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+ [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate];
+
+ if (m_state != QMediaPlayer::PlayingState)
+ emit stateChanged(m_state = QMediaPlayer::PlayingState);
+}
+
+void QT7PlayerSession::pause()
+{
+ m_state = QMediaPlayer::PausedState;
+
+ [(QTMovie*)m_QTMovie setRate:0];
+
+ emit stateChanged(m_state);
+}
+
+void QT7PlayerSession::stop()
+{
+ m_state = QMediaPlayer::StoppedState;
+
+ [(QTMovie*)m_QTMovie setRate:0];
+ setPosition(0);
+
+ if (m_state == QMediaPlayer::StoppedState)
+ emit stateChanged(m_state);
+}
+
+void QT7PlayerSession::setVolume(int volume)
+{
+ if (m_QTMovie) {
+ m_volume = volume;
+ [(QTMovie*)m_QTMovie setVolume:(volume/100.0f)];
+ }
+}
+
+void QT7PlayerSession::setMuted(bool muted)
+{
+ if (m_muted != muted) {
+ m_muted = muted;
+
+ if (m_QTMovie)
+ [(QTMovie*)m_QTMovie setMuted:m_muted];
+
+ emit mutedChanged(muted);
+ }
+}
+
+QMediaContent QT7PlayerSession::media() const
+{
+ return m_resources;
+}
+
+const QIODevice *QT7PlayerSession::mediaStream() const
+{
+ return m_mediaStream;
+}
+
+void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+ AutoReleasePool pool;
+
+ if (m_QTMovie) {
+ [(QTMovieObserver*)m_movieObserver setMovie:nil];
+
+ if (m_videoOutput) {
+ m_videoOutput->setEnabled(false);
+ m_videoOutput->setMovie(0);
+ }
+
+ [(QTMovie*)m_QTMovie release];
+ m_QTMovie = 0;
+ }
+
+ m_resources = content;
+ m_mediaStream = stream;
+ m_mediaStatus = QMediaPlayer::NoMedia;
+
+ QUrl url;
+
+ if (!content.isNull())
+ url = content.canonicalUrl();
+ else
+ return;
+
+ qDebug() << "Open media" << url;
+
+ NSError *err = 0;
+ NSString *urlString = (NSString *)qString2CFStringRef(url.toString());
+
+ NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSURL URLWithString:urlString], QTMovieURLAttribute,
+ [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute,
+ [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute,
+ [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute,
+ [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute,
+ nil];
+
+ m_QTMovie = [[QTMovie movieWithAttributes:attr error:&err] retain];
+
+ if (err) {
+ [(QTMovie*)m_QTMovie release];
+ m_QTMovie = 0;
+ QString description = QString::fromUtf8([[err localizedDescription] UTF8String]);
+
+ emit error(QMediaPlayer::FormatError, description );
+ } else {
+ [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
+
+ if (m_videoOutput) {
+ m_videoOutput->setMovie(m_QTMovie);
+ m_videoOutput->setEnabled(true);
+ }
+ processStateChange();
+
+ [(QTMovie*)m_QTMovie setMuted:m_muted];
+ setVolume(m_volume);
+ }
+}
+
+bool QT7PlayerSession::isAudioAvailable() const
+{
+ if (!m_QTMovie)
+ return false;
+
+ AutoReleasePool pool;
+ return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES;
+}
+
+bool QT7PlayerSession::isVideoAvailable() const
+{
+ if (!m_QTMovie)
+ return false;
+
+ AutoReleasePool pool;
+ return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES;
+}
+
+void QT7PlayerSession::processEOS()
+{
+ m_mediaStatus = QMediaPlayer::EndOfMedia;
+ emit stateChanged(m_state = QMediaPlayer::StoppedState);
+ emit mediaStatusChanged(m_mediaStatus);
+}
+
+void QT7PlayerSession::processStateChange()
+{
+ signed long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute]
+ longValue];
+ qDebug() << "Moview load state changed:" << state;
+
+#ifndef QUICKTIME_C_API_AVAILABLE
+ enum {
+ kMovieLoadStateError = -1L,
+ kMovieLoadStateLoading = 1000,
+ kMovieLoadStateLoaded = 2000,
+ kMovieLoadStatePlayable = 10000,
+ kMovieLoadStatePlaythroughOK = 20000,
+ kMovieLoadStateComplete = 100000
+ };
+#endif
+
+ QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
+ bool isPlaying = (m_state != QMediaPlayer::StoppedState);
+
+ if (state >= kMovieLoadStateComplete) {
+ newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
+ } else if (state >= kMovieLoadStatePlayable)
+ newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia;
+ else if (state >= kMovieLoadStateLoading)
+ newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia;
+
+ if (state == kMovieLoadStateError) {
+ newStatus = QMediaPlayer::InvalidMedia;
+ emit error(QMediaPlayer::FormatError, tr("Playback failed"));
+ }
+
+ if (newStatus != m_mediaStatus) {
+ switch (newStatus) {
+ case QMediaPlayer::BufferedMedia:
+ case QMediaPlayer::BufferingMedia:
+ //delayed playback start is necessary for network sources
+ if (m_state == QMediaPlayer::PlayingState) {
+ QMetaObject::invokeMethod(this, "play", Qt::QueuedConnection);
+ }
+ //fall
+ case QMediaPlayer::LoadedMedia:
+ case QMediaPlayer::LoadingMedia:
+ emit durationChanged(duration());
+ emit audioAvailableChanged(isAudioAvailable());
+ emit videoAvailableChanged(isVideoAvailable());
+ break;
+ case QMediaPlayer::InvalidMedia:
+ emit stateChanged(m_state = QMediaPlayer::StoppedState);
+ default:
+ break;
+ }
+
+ emit mediaStatusChanged(m_mediaStatus = newStatus);
+ }
+}
+
+void QT7PlayerSession::processVolumeChange()
+{
+ if (!m_QTMovie)
+ return;
+
+ int newVolume = qRound(100.0f*[((QTMovie*)m_QTMovie) volume]);
+
+ if (newVolume != m_volume) {
+ emit volumeChanged(m_volume = newVolume);
+ }
+}
+
+void QT7PlayerSession::processNaturalSizeChange()
+{
+ if (m_videoOutput) {
+ NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+ qDebug() << "Native size changed:" << QSize(size.width, size.height);
+ m_videoOutput->updateNaturalSize(QSize(size.width, size.height));
+ }
+}
+
+#include "moc_qt7playersession.cpp"
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/mediaservices/qt7/qcvdisplaylink.h b/src/plugins/mediaservices/qt7/qcvdisplaylink.h
new file mode 100644
index 0000000..5cd8f73
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qcvdisplaylink.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QCVDISPLAYLINK_H
+#define QCVDISPLAYLINK_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+
+#include <CoreVideo/CVDisplayLink.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QCvDisplayLink : public QObject
+{
+Q_OBJECT
+public:
+ QCvDisplayLink(QObject *parent = 0);
+ virtual ~QCvDisplayLink();
+
+ bool isValid();
+ bool isActive() const;
+
+public slots:
+ void start();
+ void stop();
+
+signals:
+ void tick(const CVTimeStamp &ts);
+
+public:
+ void displayLinkEvent(const CVTimeStamp *);
+
+protected:
+ virtual bool event(QEvent *);
+
+private:
+ CVDisplayLinkRef m_displayLink;
+ QMutex m_displayLinkMutex;
+ bool m_pendingDisplayLinkEvent;
+ bool m_isActive;
+ CVTimeStamp m_frameTimeStamp;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/plugins/mediaservices/qt7/qcvdisplaylink.mm b/src/plugins/mediaservices/qt7/qcvdisplaylink.mm
new file mode 100644
index 0000000..98ae71d
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qcvdisplaylink.mm
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 "qcvdisplaylink.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdebug.h>
+
+
+QT_USE_NAMESPACE
+
+static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ Q_UNUSED(displayLink);
+ Q_UNUSED(inNow);
+ Q_UNUSED(flagsIn);
+ Q_UNUSED(flagsOut);
+
+ QCvDisplayLink *link = (QCvDisplayLink *)displayLinkContext;
+
+ link->displayLinkEvent(inOutputTime);
+ return kCVReturnSuccess;
+}
+
+
+QCvDisplayLink::QCvDisplayLink(QObject *parent)
+ :QObject(parent),
+ m_pendingDisplayLinkEvent(false),
+ m_isActive(false)
+{
+ // create display link for the main display
+ CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
+ if (m_displayLink) {
+ // set the current display of a display link.
+ CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay);
+
+ // set the renderer output callback function
+ CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this);
+ }
+}
+
+QCvDisplayLink::~QCvDisplayLink()
+{
+ if (m_displayLink) {
+ CVDisplayLinkStop(m_displayLink);
+ CVDisplayLinkRelease(m_displayLink);
+ m_displayLink = NULL;
+ }
+}
+
+bool QCvDisplayLink::isValid()
+{
+ return m_displayLink != 0;
+}
+
+bool QCvDisplayLink::isActive() const
+{
+ return m_isActive;
+}
+
+void QCvDisplayLink::start()
+{
+ if (m_displayLink && !m_isActive) {
+ CVDisplayLinkStart(m_displayLink);
+ m_isActive = true;
+ }
+}
+
+void QCvDisplayLink::stop()
+{
+ if (m_displayLink && m_isActive) {
+ CVDisplayLinkStop(m_displayLink);
+ m_isActive = false;
+ }
+}
+
+void QCvDisplayLink::displayLinkEvent(const CVTimeStamp *ts)
+{
+ // This function is called from a
+ // thread != gui thread. So we post the event.
+ // But we need to make sure that we don't post faster
+ // than the event loop can eat:
+ m_displayLinkMutex.lock();
+ bool pending = m_pendingDisplayLinkEvent;
+ m_pendingDisplayLinkEvent = true;
+ m_frameTimeStamp = *ts;
+ m_displayLinkMutex.unlock();
+
+ if (!pending)
+ qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
+}
+
+bool QCvDisplayLink::event(QEvent *event)
+{
+ switch (event->type()){
+ case QEvent::User: {
+ m_displayLinkMutex.lock();
+ m_pendingDisplayLinkEvent = false;
+ CVTimeStamp ts = m_frameTimeStamp;
+ m_displayLinkMutex.unlock();
+
+ emit tick(ts);
+
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return QObject::event(event);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qcvdisplaylink.cpp"
+
diff --git a/src/plugins/mediaservices/qt7/qt7.pro b/src/plugins/mediaservices/qt7/qt7.pro
new file mode 100644
index 0000000..13d14d7
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7.pro
@@ -0,0 +1,45 @@
+TARGET = qt7
+include(../../qpluginbase.pri)
+
+QT += opengl multimedia
+
+LIBS += -framework AppKit -framework AudioUnit \
+ -framework AudioToolbox -framework CoreAudio \
+ -framework QuartzCore -framework QTKit
+
+# The Quicktime framework is only awailable for 32-bit builds, so we
+# need to check for this before linking against it.
+# QMAKE_MAC_XARCH is not awailable on Tiger, but at the same time,
+# we never build for 64-bit architechtures on Tiger either:
+contains(QMAKE_MAC_XARCH, no) {
+ LIBS += -framework QuickTime
+} else {
+ LIBS += -Xarch_i386 -framework QuickTime -Xarch_ppc -framework QuickTime
+}
+
+HEADERS += \
+ qt7backend.h \
+ qt7videooutputcontrol.h \
+ qt7movieviewoutput.h \
+ qt7movievideowidget.h \
+ qt7movieviewrenderer.h \
+ qt7serviceplugin.h \
+ qt7movierenderer.h \
+ qcvdisplaylink.h
+
+OBJECTIVE_SOURCES += \
+ qt7backend.mm \
+ qt7serviceplugin.mm \
+ qt7movieviewoutput.mm \
+ qt7movievideowidget.mm \
+ qt7movieviewrenderer.mm \
+ qt7movierenderer.mm \
+ qt7videooutputcontrol.mm \
+ qcvdisplaylink.mm
+
+include(mediaplayer/mediaplayer.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices
+target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices
+INSTALLS += target
+
diff --git a/src/plugins/mediaservices/qt7/qt7backend.h b/src/plugins/mediaservices/qt7/qt7backend.h
new file mode 100644
index 0000000..5668965
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7backend.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7BACKEND_H
+#define QT7BACKEND_H
+
+#include <QtCore/qstring.h>
+
+#ifndef Q_WS_MAC64
+#define QUICKTIME_C_API_AVAILABLE
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class AutoReleasePool
+{
+private:
+ void *pool;
+public:
+ AutoReleasePool();
+ ~AutoReleasePool();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7backend.mm b/src/plugins/mediaservices/qt7/qt7backend.mm
new file mode 100644
index 0000000..478589b
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7backend.mm
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 "qt7backend.h"
+
+#import <Foundation/NSAutoreleasePool.h>
+#include <CoreFoundation/CFBase.h>
+
+
+QT_BEGIN_NAMESPACE
+
+AutoReleasePool::AutoReleasePool()
+{
+ pool = (void*)[[NSAutoreleasePool alloc] init];
+}
+
+AutoReleasePool::~AutoReleasePool()
+{
+ [(NSAutoreleasePool*)pool release];
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.h b/src/plugins/mediaservices/qt7/qt7movierenderer.h
new file mode 100644
index 0000000..a547329
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movierenderer.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7MOVIERENDERER_H
+#define QT7MOVIERENDERER_H
+
+#include "qt7backend.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+
+#include <qvideorenderercontrol.h>
+#include <qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+#include "qt7videooutputcontrol.h"
+
+#include <CoreVideo/CVOpenGLTexture.h>
+#include <QuickTime/QuickTime.h>
+
+
+QT_BEGIN_HEADER
+
+class QGLContext;
+
+QT_BEGIN_NAMESPACE
+
+class QCvDisplayLink;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+class QT7MovieRenderer : public QT7VideoRendererControl
+{
+Q_OBJECT
+public:
+ QT7MovieRenderer(QObject *parent = 0);
+ virtual ~QT7MovieRenderer();
+
+ void setEnabled(bool);
+ void setMovie(void *movie);
+ void updateNaturalSize(const QSize &newSize);
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+ QSize nativeSize() const;
+
+private slots:
+ void updateVideoFrame(const CVTimeStamp &ts);
+
+private:
+ void setupVideoOutput();
+ bool createPixelBufferVisualContext();
+ bool createGLVisualContext();
+
+ void *m_movie;
+
+ QMutex m_mutex;
+
+ QCvDisplayLink *m_displayLink;
+#ifdef QUICKTIME_C_API_AVAILABLE
+ QTVisualContextRef m_visualContext;
+ bool m_usingGLContext;
+ const QGLContext *m_currentGLContext;
+ QSize m_pixelBufferContextGeometry;
+#endif
+ QAbstractVideoSurface *m_surface;
+ QSize m_nativeSize;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.mm b/src/plugins/mediaservices/qt7/qt7movierenderer.mm
new file mode 100644
index 0000000..587f3b9
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movierenderer.mm
@@ -0,0 +1,454 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#import <QTKit/QTKit.h>
+
+#include "qt7backend.h"
+
+#include "qt7playercontrol.h"
+#include "qt7movierenderer.h"
+#include "qt7playersession.h"
+#include "qcvdisplaylink.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QGLWidget>
+
+#include <QtMultimedia/qabstractvideobuffer.h>
+#include <QtMultimedia/qabstractvideosurface.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+
+QT_BEGIN_NAMESPACE
+
+class CVGLTextureVideoBuffer : public QAbstractVideoBuffer
+{
+public:
+ CVGLTextureVideoBuffer(CVOpenGLTextureRef buffer)
+ : QAbstractVideoBuffer(NoHandle)
+ , m_buffer(buffer)
+ , m_mode(NotMapped)
+ {
+ CVOpenGLTextureRetain(m_buffer);
+ }
+
+ virtual ~CVGLTextureVideoBuffer()
+ {
+ CVOpenGLTextureRelease(m_buffer);
+ }
+
+ QVariant handle() const
+ {
+ GLuint id = CVOpenGLTextureGetName(m_buffer);
+ return QVariant(int(id));
+ }
+
+ HandleType handleType() const
+ {
+ return GLTextureHandle;
+ }
+
+ MapMode mapMode() const { return m_mode; }
+
+ uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ {
+ if (numBytes)
+ *numBytes = 0;
+
+ if (bytesPerLine)
+ *bytesPerLine = 0;
+
+ m_mode = mode;
+ return 0;
+ }
+
+ void unmap() { m_mode = NotMapped; }
+
+private:
+ CVOpenGLTextureRef m_buffer;
+ MapMode m_mode;
+};
+
+
+class CVPixelBufferVideoBuffer : public QAbstractVideoBuffer
+{
+public:
+ CVPixelBufferVideoBuffer(CVPixelBufferRef buffer)
+ : QAbstractVideoBuffer(NoHandle)
+ , m_buffer(buffer)
+ , m_mode(NotMapped)
+ {
+ CVPixelBufferRetain(m_buffer);
+ }
+
+ virtual ~CVPixelBufferVideoBuffer()
+ {
+ CVPixelBufferRelease(m_buffer);
+ }
+
+ MapMode mapMode() const { return m_mode; }
+
+ uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ {
+ if (mode != NotMapped && m_mode == NotMapped) {
+ CVPixelBufferLockBaseAddress(m_buffer, 0);
+
+ if (numBytes)
+ *numBytes = CVPixelBufferGetDataSize(m_buffer);
+
+ if (bytesPerLine)
+ *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer);
+
+ m_mode = mode;
+
+ return (uchar*)CVPixelBufferGetBaseAddress(m_buffer);
+ } else {
+ return 0;
+ }
+ }
+
+ void unmap()
+ {
+ if (m_mode != NotMapped) {
+ m_mode = NotMapped;
+ CVPixelBufferUnlockBaseAddress(m_buffer, 0);
+ }
+ }
+
+private:
+ CVPixelBufferRef m_buffer;
+ MapMode m_mode;
+};
+
+
+
+QT7MovieRenderer::QT7MovieRenderer(QObject *parent)
+ :QT7VideoRendererControl(parent),
+ m_movie(0),
+#ifdef QUICKTIME_C_API_AVAILABLE
+ m_visualContext(0),
+ m_usingGLContext(false),
+ m_currentGLContext(0),
+#endif
+ m_surface(0)
+{
+ qDebug() << "QT7MovieRenderer";
+
+ m_displayLink = new QCvDisplayLink(this);
+ connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
+}
+
+
+bool QT7MovieRenderer::createGLVisualContext()
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+ AutoReleasePool pool;
+ CGLContextObj cglContext = CGLGetCurrentContext();
+ NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
+ CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
+
+ OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, cglContext,
+ cglPixelFormat, NULL, &m_visualContext);
+ if (err != noErr)
+ qWarning() << "Could not create visual context (OpenGL)";
+
+ return (err == noErr);
+#endif // QUICKTIME_C_API_AVAILABLE
+
+ return false;
+}
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+static bool DictionarySetValue(CFMutableDictionaryRef dict, CFStringRef key, SInt32 value)
+{
+ CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
+
+ if (number) {
+ CFDictionarySetValue( dict, key, number );
+ CFRelease( number );
+ return true;
+ }
+ return false;
+}
+#endif // QUICKTIME_C_API_AVAILABLE
+
+bool QT7MovieRenderer::createPixelBufferVisualContext()
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+ if (m_visualContext) {
+ QTVisualContextRelease(m_visualContext);
+ m_visualContext = 0;
+ }
+
+ m_pixelBufferContextGeometry = m_nativeSize;
+
+ CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ //DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32ARGBPixelFormat );
+ DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat );
+ DictionarySetValue(pixelBufferOptions, kCVPixelBufferWidthKey, m_nativeSize.width() );
+ DictionarySetValue(pixelBufferOptions, kCVPixelBufferHeightKey, m_nativeSize.height() );
+ DictionarySetValue(pixelBufferOptions, kCVPixelBufferBytesPerRowAlignmentKey, 16);
+ //CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
+
+ CFMutableDictionaryRef visualContextOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(visualContextOptions, kQTVisualContextPixelBufferAttributesKey, pixelBufferOptions);
+ CFDictionarySetValue(visualContextOptions, kQTVisualContextWorkingColorSpaceKey, CGColorSpaceCreateDeviceRGB());
+
+ OSStatus err = QTPixelBufferContextCreate(kCFAllocatorDefault,
+ visualContextOptions,
+ &m_visualContext);
+ CFRelease(pixelBufferOptions);
+ CFRelease(visualContextOptions);
+
+ if (err != noErr) {
+ qWarning() << "Could not create visual context (PixelBuffer)";
+ return false;
+ }
+
+ return true;
+#endif // QUICKTIME_C_API_AVAILABLE
+
+ return false;
+}
+
+
+QT7MovieRenderer::~QT7MovieRenderer()
+{
+ m_displayLink->stop();
+}
+
+void QT7MovieRenderer::setupVideoOutput()
+{
+ AutoReleasePool pool;
+
+ qDebug() << "QT7MovieRenderer::setupVideoOutput" << m_movie;
+
+ if (m_movie == 0 || m_surface == 0) {
+ m_displayLink->stop();
+ return;
+ }
+
+ NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+ m_nativeSize = QSize(size.width, size.height);
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ bool usedGLContext = m_usingGLContext;
+
+ if (!m_nativeSize.isEmpty()) {
+
+ bool glSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
+
+ //Try rendering using opengl textures first:
+ if (glSupported) {
+ QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle);
+
+ if (m_surface->isActive())
+ m_surface->stop();
+
+ qDebug() << "Starting the surface with format" << format;
+ if (!m_surface->start(format)) {
+ qDebug() << "failed to start video surface" << m_surface->error();
+ glSupported = false;
+ } else {
+ m_usingGLContext = true;
+ }
+
+ }
+
+ if (!glSupported) {
+ m_usingGLContext = false;
+ QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
+
+ if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
+ qDebug() << "Surface format was changed, stop the surface.";
+ m_surface->stop();
+ }
+
+ if (!m_surface->isActive()) {
+ qDebug() << "Starting the surface with format" << format;
+ if (!m_surface->start(format))
+ qDebug() << "failed to start video surface" << m_surface->error();
+ }
+ }
+ }
+
+
+ if (m_visualContext) {
+ //check if the visual context still can be reused
+ if (usedGLContext != m_usingGLContext ||
+ (m_usingGLContext && (m_currentGLContext != QGLContext::currentContext())) ||
+ (!m_usingGLContext && (m_pixelBufferContextGeometry != m_nativeSize))) {
+ QTVisualContextRelease(m_visualContext);
+ m_pixelBufferContextGeometry = QSize();
+ m_visualContext = 0;
+ }
+ }
+
+ if (!m_nativeSize.isEmpty()) {
+ if (!m_visualContext) {
+ if (m_usingGLContext) {
+ qDebug() << "Building OpenGL visual context" << m_nativeSize;
+ m_currentGLContext = QGLContext::currentContext();
+ if (!createGLVisualContext()) {
+ qWarning() << "QT7MovieRenderer: failed to create visual context";
+ return;
+ }
+ } else {
+ qDebug() << "Building Pixel Buffer visual context" << m_nativeSize;
+ if (!createPixelBufferVisualContext()) {
+ qWarning() << "QT7MovieRenderer: failed to create visual context";
+ return;
+ }
+ }
+ }
+
+ // targets a Movie to render into a visual context
+ SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
+
+ m_displayLink->start();
+ }
+#endif
+
+}
+
+void QT7MovieRenderer::setEnabled(bool)
+{
+}
+
+void QT7MovieRenderer::setMovie(void *movie)
+{
+ qDebug() << "QT7MovieRenderer::setMovie" << movie;
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ QMutexLocker locker(&m_mutex);
+
+ if (m_movie != movie) {
+ if (m_movie) {
+ //ensure the old movie doesn't hold the visual context, otherwise it can't be reused
+ SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
+ [(QTMovie*)m_movie release];
+ }
+
+ m_movie = movie;
+ [(QTMovie*)m_movie retain];
+
+ setupVideoOutput();
+ }
+#endif
+}
+
+void QT7MovieRenderer::updateNaturalSize(const QSize &newSize)
+{
+ if (m_nativeSize != newSize) {
+ m_nativeSize = newSize;
+ setupVideoOutput();
+ }
+}
+
+QAbstractVideoSurface *QT7MovieRenderer::surface() const
+{
+ return m_surface;
+}
+
+void QT7MovieRenderer::setSurface(QAbstractVideoSurface *surface)
+{
+ qDebug() << "Set video surface" << surface;
+
+ if (surface == m_surface)
+ return;
+
+ QMutexLocker locker(&m_mutex);
+
+ if (m_surface && m_surface->isActive())
+ m_surface->stop();
+
+ m_surface = surface;
+ setupVideoOutput();
+}
+
+
+QSize QT7MovieRenderer::nativeSize() const
+{
+ return m_nativeSize;
+}
+
+void QT7MovieRenderer::updateVideoFrame(const CVTimeStamp &ts)
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+
+ QMutexLocker locker(&m_mutex);
+
+ if (m_surface && m_surface->isActive() &&
+ m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
+
+ CVImageBufferRef imageBuffer = NULL;
+
+ OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &imageBuffer);
+
+ if (status == noErr && imageBuffer) {
+ //qDebug() << "render video frame";
+ QAbstractVideoBuffer *buffer = 0;
+
+ if (m_usingGLContext) {
+ buffer = new CVGLTextureVideoBuffer((CVOpenGLTextureRef)imageBuffer);
+ CVOpenGLTextureRelease((CVOpenGLTextureRef)imageBuffer);
+ //qDebug() << "render GL video frame" << buffer->handle();
+ } else {
+ buffer = new CVPixelBufferVideoBuffer((CVPixelBufferRef)imageBuffer);
+ CVPixelBufferRelease((CVPixelBufferRef)imageBuffer);
+ }
+
+ QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_RGB32);
+ m_surface->present(frame);
+ QTVisualContextTask(m_visualContext);
+ }
+ }
+#else
+ Q_UNUSED(ts);
+#endif
+}
+
+#include "moc_qt7movierenderer.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.h b/src/plugins/mediaservices/qt7/qt7movievideowidget.h
new file mode 100644
index 0000000..3acd373
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7MOVIEVIDEOWIDGET_H
+#define QT7MOVIEVIDEOWIDGET_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+
+#include <qvideowindowcontrol.h>
+#include <qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+#include "qt7videooutputcontrol.h"
+
+#include <CoreVideo/CVOpenGLTexture.h>
+#include <QuickTime/QuickTime.h>
+
+
+QT_BEGIN_HEADER
+
+class GLVideoWidget;
+
+QT_BEGIN_NAMESPACE
+
+class QCvDisplayLink;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+class QT7MovieVideoWidget : public QT7VideoWidgetControl
+{
+Q_OBJECT
+public:
+ QT7MovieVideoWidget(QObject *parent = 0);
+ virtual ~QT7MovieVideoWidget();
+
+ void setEnabled(bool);
+ void setMovie(void *movie);
+ void updateNaturalSize(const QSize &newSize);
+
+ QWidget *videoWidget();
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ QSize nativeSize() const;
+
+ QVideoWidget::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(QVideoWidget::AspectRatioMode mode);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+private slots:
+ void updateVideoFrame(const CVTimeStamp &ts);
+
+private:
+ void setupVideoOutput();
+ bool createVisualContext();
+
+ void updateColors();
+
+ void *m_movie;
+ GLVideoWidget *m_videoWidget;
+
+ QCvDisplayLink *m_displayLink;
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ QTVisualContextRef m_visualContext;
+#endif
+
+ bool m_fullscreen;
+ QSize m_nativeSize;
+ QVideoWidget::AspectRatioMode m_aspectRatioMode;
+ int m_brightness;
+ int m_contrast;
+ int m_hue;
+ int m_saturation;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm
new file mode 100644
index 0000000..6e74fcd
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm
@@ -0,0 +1,417 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#import <QTKit/QTKit.h>
+
+#include "qt7backend.h"
+
+#include "qt7playercontrol.h"
+#include "qt7movievideowidget.h"
+#include "qt7playersession.h"
+#include "qcvdisplaylink.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QGLWidget>
+
+#import <QuartzCore/QuartzCore.h>
+
+#include "math.h"
+
+QT_BEGIN_NAMESPACE
+
+class GLVideoWidget : public QGLWidget
+{
+public:
+
+ GLVideoWidget(QWidget *parent, const QGLFormat &format)
+ : QGLWidget(format, parent),
+ m_texRef(0),
+ m_nativeSize(640,480),
+ m_aspectRatioMode(QVideoWidget::KeepAspectRatio)
+ {
+ setAutoFillBackground(false);
+ }
+
+ void initializeGL()
+ {
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ }
+
+ void resizeGL(int w, int h)
+ {
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glViewport(0, 0, GLsizei(w), GLsizei(h));
+ gluOrtho2D(0, GLsizei(w), 0, GLsizei(h));
+ updateGL();
+ }
+
+ void paintGL()
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+ if (!m_texRef)
+ return;
+
+ glPushMatrix();
+ glDisable(GL_CULL_FACE);
+ GLenum target = CVOpenGLTextureGetTarget(m_texRef);
+ glEnable(target);
+
+ glBindTexture(target, CVOpenGLTextureGetName(m_texRef));
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ GLfloat lowerLeft[2], lowerRight[2], upperRight[2], upperLeft[2];
+ CVOpenGLTextureGetCleanTexCoords(m_texRef, lowerLeft, lowerRight, upperRight, upperLeft);
+
+ glBegin(GL_QUADS);
+ QRect rect = displayRect();
+ glTexCoord2f(lowerLeft[0], lowerLeft[1]);
+ glVertex2i(rect.topLeft().x(), rect.topLeft().y());
+ glTexCoord2f(lowerRight[0], lowerRight[1]);
+ glVertex2i(rect.topRight().x() + 1, rect.topRight().y());
+ glTexCoord2f(upperRight[0], upperRight[1]);
+ glVertex2i(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
+ glTexCoord2f(upperLeft[0], upperLeft[1]);
+ glVertex2i(rect.bottomLeft().x(), rect.bottomLeft().y() + 1);
+ glEnd();
+ glPopMatrix();
+ }
+
+ void setCVTexture(CVOpenGLTextureRef texRef)
+ {
+ if (m_texRef)
+ CVOpenGLTextureRelease(m_texRef);
+
+ m_texRef = texRef;
+
+ if (m_texRef)
+ CVOpenGLTextureRetain(m_texRef);
+
+ if (isVisible()) {
+ makeCurrent();
+ paintGL();
+ swapBuffers();
+ }
+ }
+
+ QSize sizeHint() const
+ {
+ return m_nativeSize;
+ }
+
+ void setNativeSize(const QSize &size)
+ {
+ m_nativeSize = size;
+ }
+
+ void setAspectRatioMode(QVideoWidget::AspectRatioMode mode)
+ {
+ if (m_aspectRatioMode != mode) {
+ m_aspectRatioMode = mode;
+ update();
+ }
+ }
+
+private:
+ QRect displayRect() const
+ {
+ QRect displayRect = rect();
+
+ if (m_aspectRatioMode == QVideoWidget::KeepAspectRatio) {
+ QSize size = m_nativeSize;
+ size.scale(displayRect.size(), Qt::KeepAspectRatio);
+
+ displayRect = QRect(QPoint(0, 0), size);
+ displayRect.moveCenter(rect().center());
+ }
+ return displayRect;
+ }
+
+ CVOpenGLTextureRef m_texRef;
+ QSize m_nativeSize;
+ QVideoWidget::AspectRatioMode m_aspectRatioMode;
+};
+
+QT7MovieVideoWidget::QT7MovieVideoWidget(QObject *parent)
+ :QT7VideoWidgetControl(parent),
+ m_movie(0),
+ m_videoWidget(0),
+ m_fullscreen(false),
+ m_aspectRatioMode(QVideoWidget::KeepAspectRatio),
+ m_brightness(0),
+ m_contrast(0),
+ m_hue(0),
+ m_saturation(0)
+{
+ qDebug() << "QT7MovieVideoWidget";
+
+ QGLFormat format = QGLFormat::defaultFormat();
+ format.setSwapInterval(1); // Vertical sync (avoid tearing)
+ m_videoWidget = new GLVideoWidget(0, format);
+
+ m_displayLink = new QCvDisplayLink(this);
+
+ connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
+
+ if (!createVisualContext()) {
+ qWarning() << "QT7MovieVideoWidget: failed to create visual context";
+ }
+}
+
+
+bool QT7MovieVideoWidget::createVisualContext()
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+ m_videoWidget->makeCurrent();
+
+ AutoReleasePool pool;
+ CGLContextObj cglContext = CGLGetCurrentContext();
+ NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
+ CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
+
+ CFTypeRef keys[] = { kQTVisualContextWorkingColorSpaceKey };
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CFDictionaryRef textureContextAttributes = CFDictionaryCreate(kCFAllocatorDefault,
+ (const void **)keys,
+ (const void **)&colorSpace, 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault,
+ cglContext,
+ cglPixelFormat,
+ textureContextAttributes,
+ &m_visualContext);
+ if (err != noErr)
+ qWarning() << "Could not create visual context (OpenGL)";
+
+
+ return (err == noErr);
+#endif // QUICKTIME_C_API_AVAILABLE
+
+ return false;
+}
+
+QT7MovieVideoWidget::~QT7MovieVideoWidget()
+{
+ m_displayLink->stop();
+ [(QTMovie*)m_movie release];
+ delete m_videoWidget;
+}
+
+QWidget *QT7MovieVideoWidget::videoWidget()
+{
+ return m_videoWidget;
+}
+
+void QT7MovieVideoWidget::setupVideoOutput()
+{
+ AutoReleasePool pool;
+
+ qDebug() << "QT7MovieVideoWidget::setupVideoOutput" << m_movie;
+
+ if (m_movie == 0) {
+ m_displayLink->stop();
+ return;
+ }
+
+ NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+ m_nativeSize = QSize(size.width, size.height);
+ m_videoWidget->setNativeSize(m_nativeSize);
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ // targets a Movie to render into a visual context
+ SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
+#endif
+
+ m_displayLink->start();
+}
+
+void QT7MovieVideoWidget::setEnabled(bool)
+{
+}
+
+void QT7MovieVideoWidget::setMovie(void *movie)
+{
+ if (m_movie == movie)
+ return;
+
+ if (m_movie) {
+#ifdef QUICKTIME_C_API_AVAILABLE
+ SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
+#endif
+ [(QTMovie*)m_movie release];
+ }
+
+ m_movie = movie;
+ [(QTMovie*)m_movie retain];
+
+ setupVideoOutput();
+}
+
+void QT7MovieVideoWidget::updateNaturalSize(const QSize &newSize)
+{
+ if (m_nativeSize != newSize) {
+ m_nativeSize = newSize;
+ setupVideoOutput();
+ }
+}
+
+bool QT7MovieVideoWidget::isFullScreen() const
+{
+ return m_fullscreen;
+}
+
+void QT7MovieVideoWidget::setFullScreen(bool fullScreen)
+{
+ m_fullscreen = fullScreen;
+}
+
+QSize QT7MovieVideoWidget::nativeSize() const
+{
+ return m_nativeSize;
+}
+
+QVideoWidget::AspectRatioMode QT7MovieVideoWidget::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void QT7MovieVideoWidget::setAspectRatioMode(QVideoWidget::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+ m_videoWidget->setAspectRatioMode(mode);
+}
+
+int QT7MovieVideoWidget::brightness() const
+{
+ return m_brightness;
+}
+
+void QT7MovieVideoWidget::setBrightness(int brightness)
+{
+ m_brightness = brightness;
+ updateColors();
+}
+
+int QT7MovieVideoWidget::contrast() const
+{
+ return m_contrast;
+}
+
+void QT7MovieVideoWidget::setContrast(int contrast)
+{
+ m_contrast = contrast;
+ updateColors();
+}
+
+int QT7MovieVideoWidget::hue() const
+{
+ return m_hue;
+}
+
+void QT7MovieVideoWidget::setHue(int hue)
+{
+ m_hue = hue;
+ updateColors();
+}
+
+int QT7MovieVideoWidget::saturation() const
+{
+ return m_saturation;
+}
+
+void QT7MovieVideoWidget::setSaturation(int saturation)
+{
+ m_saturation = saturation;
+ updateColors();
+}
+
+void QT7MovieVideoWidget::updateColors()
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+ if (m_movie) {
+ QTMovie *movie = (QTMovie*)m_movie;
+
+ Float32 value;
+ value = m_brightness/100.0;
+ SetMovieVisualBrightness([movie quickTimeMovie], value, 0);
+ value = pow(2, m_contrast/50.0);
+ SetMovieVisualContrast([movie quickTimeMovie], value, 0);
+ value = m_hue/100.0;
+ SetMovieVisualHue([movie quickTimeMovie], value, 0);
+ value = 1.0+m_saturation/100.0;
+ SetMovieVisualSaturation([movie quickTimeMovie], value, 0);
+ }
+#endif
+}
+
+void QT7MovieVideoWidget::updateVideoFrame(const CVTimeStamp &ts)
+{
+#ifdef QUICKTIME_C_API_AVAILABLE
+ AutoReleasePool pool;
+ // check for new frame
+ if (m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
+ CVOpenGLTextureRef currentFrame = NULL;
+
+ // get a "frame" (image buffer) from the Visual Context, indexed by the provided time
+ OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &currentFrame);
+
+ // the above call may produce a null frame so check for this first
+ // if we have a frame, then draw it
+ if (status == noErr && currentFrame) {
+ //qDebug() << "render video frame";
+ m_videoWidget->setCVTexture(currentFrame);
+ CVOpenGLTextureRelease(currentFrame);
+ }
+ QTVisualContextTask(m_visualContext);
+ }
+#else
+ Q_UNUSED(ts);
+#endif
+}
+
+#include "moc_qt7movievideowidget.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h
new file mode 100644
index 0000000..30eefa7
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7MOVIEVIEWOUTPUT_H
+#define QT7MOVIEVIEWOUTPUT_H
+
+#include <QtCore/qobject.h>
+
+#include <QtMultimedia/qvideowindowcontrol.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+#include "qt7videooutputcontrol.h"
+
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerSession;
+class QT7PlayerService;
+
+class QT7MovieViewOutput : public QT7VideoWindowControl
+{
+public:
+ QT7MovieViewOutput(QObject *parent = 0);
+ ~QT7MovieViewOutput();
+
+ void setEnabled(bool);
+ void setMovie(void *movie);
+ void updateNaturalSize(const QSize &newSize);
+
+ WId winId() const;
+ void setWinId(WId id);
+
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ void repaint();
+
+ QSize nativeSize() const;
+
+ QVideoWidget::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(QVideoWidget::AspectRatioMode mode);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+private:
+ void setupVideoOutput();
+
+ void *m_movie;
+ void *m_movieView;
+
+ WId m_winId;
+ QRect m_displayRect;
+ bool m_fullscreen;
+ QSize m_nativeSize;
+ QVideoWidget::AspectRatioMode m_aspectRatioMode;
+ int m_brightness;
+ int m_contrast;
+ int m_hue;
+ int m_saturation;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm
new file mode 100644
index 0000000..b549487
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#import <QTKit/QTKit.h>
+
+#include "qt7backend.h"
+
+#include "qt7playercontrol.h"
+#include "qt7movieviewoutput.h"
+#include "qt7playersession.h"
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+
+#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
+
+@interface TransparentQTMovieView : QTMovieView
+{
+@private
+ QRect *m_drawRect;
+ qreal m_brightness, m_contrast, m_saturation, m_hue;
+}
+
+- (TransparentQTMovieView *) init;
+- (void) setDrawRect:(QRect &)rect;
+- (void) setContrast:(qreal) contrast;
+@end
+
+@implementation TransparentQTMovieView
+
+- (TransparentQTMovieView *) init
+{
+ self = [super initWithFrame:NSZeroRect];
+ if (self) {
+ [self setControllerVisible:NO];
+ [self setContrast:1.0];
+ [self setDelegate:self];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [super dealloc];
+}
+
+- (void) setContrast:(qreal) contrast
+{
+ m_hue = 0.0;
+ m_brightness = 0.0;
+ m_contrast = contrast;
+ m_saturation = 1.0;
+}
+
+
+- (void) setDrawRect:(QRect &)rect
+{
+ *m_drawRect = rect;
+
+ NSRect nsrect;
+ nsrect.origin.x = m_drawRect->x();
+ nsrect.origin.y = m_drawRect->y();
+ nsrect.size.width = m_drawRect->width();
+ nsrect.size.height = m_drawRect->height();
+ [self setFrame:nsrect];
+}
+
+- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
+{
+ // This method is called from QTMovieView just
+ // before the image will be drawn.
+ Q_UNUSED(view);
+
+ if ( !qFuzzyCompare(m_brightness, 0.0) ||
+ !qFuzzyCompare(m_contrast, 1.0) ||
+ !qFuzzyCompare(m_saturation, 1.0)){
+ CIFilter *colorFilter = [CIFilter filterWithName:@"CIColorControls"];
+ [colorFilter setValue:[NSNumber numberWithFloat:m_brightness] forKey:@"inputBrightness"];
+ [colorFilter setValue:[NSNumber numberWithFloat:(m_contrast < 1) ? m_contrast : 1 + ((m_contrast-1)*3)] forKey:@"inputContrast"];
+ [colorFilter setValue:[NSNumber numberWithFloat:m_saturation] forKey:@"inputSaturation"];
+ [colorFilter setValue:img forKey:@"inputImage"];
+ img = [colorFilter valueForKey:@"outputImage"];
+ }
+
+ /*if (m_hue){
+ CIFilter *colorFilter = [CIFilter filterWithName:@"CIHueAdjust"];
+ [colorFilter setValue:[NSNumber numberWithFloat:(m_hue * 3.14)] forKey:@"inputAngle"];
+ [colorFilter setValue:img forKey:@"inputImage"];
+ img = [colorFilter valueForKey:@"outputImage"];
+ }*/
+
+ return img;
+}
+
+
+VIDEO_TRANSPARENT(mouseDown);
+VIDEO_TRANSPARENT(mouseDragged);
+VIDEO_TRANSPARENT(mouseUp);
+VIDEO_TRANSPARENT(mouseMoved);
+VIDEO_TRANSPARENT(mouseEntered);
+VIDEO_TRANSPARENT(mouseExited);
+VIDEO_TRANSPARENT(rightMouseDown);
+VIDEO_TRANSPARENT(rightMouseDragged);
+VIDEO_TRANSPARENT(rightMouseUp);
+VIDEO_TRANSPARENT(otherMouseDown);
+VIDEO_TRANSPARENT(otherMouseDragged);
+VIDEO_TRANSPARENT(otherMouseUp);
+VIDEO_TRANSPARENT(keyDown);
+VIDEO_TRANSPARENT(keyUp);
+VIDEO_TRANSPARENT(scrollWheel)
+
+@end
+
+
+QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent)
+ :QT7VideoWindowControl(parent),
+ m_movie(0),
+ m_movieView(0),
+ m_winId(0),
+ m_fullscreen(false),
+ m_aspectRatioMode(QVideoWidget::KeepAspectRatio),
+ m_brightness(0),
+ m_contrast(0),
+ m_hue(0),
+ m_saturation(0)
+{
+}
+
+QT7MovieViewOutput::~QT7MovieViewOutput()
+{
+}
+
+void QT7MovieViewOutput::setupVideoOutput()
+{
+ AutoReleasePool pool;
+
+ //qDebug() << "QT7MovieViewOutput::setupVideoOutput" << m_movie << m_winId;
+ if (m_movie == 0 || m_winId <= 0)
+ return;
+
+ NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+ m_nativeSize = QSize(size.width, size.height);
+
+ if (!m_movieView)
+ m_movieView = [[TransparentQTMovieView alloc] init];
+
+ [(QTMovieView*)m_movieView setControllerVisible:NO];
+ [(QTMovieView*)m_movieView setMovie:(QTMovie*)m_movie];
+
+ [(NSView *)m_winId addSubview:(QTMovieView*)m_movieView];
+
+ setDisplayRect(m_displayRect);
+}
+
+void QT7MovieViewOutput::setEnabled(bool)
+{
+}
+
+void QT7MovieViewOutput::setMovie(void *movie)
+{
+ m_movie = movie;
+ setupVideoOutput();
+}
+
+void QT7MovieViewOutput::updateNaturalSize(const QSize &newSize)
+{
+ m_nativeSize = newSize;
+}
+
+WId QT7MovieViewOutput::winId() const
+{
+ return m_winId;
+}
+
+void QT7MovieViewOutput::setWinId(WId id)
+{
+ m_winId = id;
+ setupVideoOutput();
+}
+
+QRect QT7MovieViewOutput::displayRect() const
+{
+ return m_displayRect;
+}
+
+void QT7MovieViewOutput::setDisplayRect(const QRect &rect)
+{
+ m_displayRect = rect;
+
+ if (m_movieView) {
+ AutoReleasePool pool;
+ [(QTMovieView*)m_movieView setPreservesAspectRatio:(m_aspectRatioMode == QVideoWidget::KeepAspectRatio ? YES : NO)];
+ [(QTMovieView*)m_movieView setFrame:NSMakeRect(m_displayRect.x(),
+ m_displayRect.y(),
+ m_displayRect.width(),
+ m_displayRect.height())];
+ }
+
+}
+
+bool QT7MovieViewOutput::isFullScreen() const
+{
+ return m_fullscreen;
+}
+
+void QT7MovieViewOutput::setFullScreen(bool fullScreen)
+{
+ m_fullscreen = fullScreen;
+ setDisplayRect(m_displayRect);
+}
+
+void QT7MovieViewOutput::repaint()
+{
+}
+
+QSize QT7MovieViewOutput::nativeSize() const
+{
+ return m_nativeSize;
+}
+
+QVideoWidget::AspectRatioMode QT7MovieViewOutput::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void QT7MovieViewOutput::setAspectRatioMode(QVideoWidget::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+ setDisplayRect(m_displayRect);
+}
+
+int QT7MovieViewOutput::brightness() const
+{
+ return m_brightness;
+}
+
+void QT7MovieViewOutput::setBrightness(int brightness)
+{
+ m_brightness = brightness;
+}
+
+int QT7MovieViewOutput::contrast() const
+{
+ return m_contrast;
+}
+
+void QT7MovieViewOutput::setContrast(int contrast)
+{
+ m_contrast = contrast;
+ [(TransparentQTMovieView*)m_movieView setContrast:(contrast/100.0+1.0)];
+}
+
+int QT7MovieViewOutput::hue() const
+{
+ return m_hue;
+}
+
+void QT7MovieViewOutput::setHue(int hue)
+{
+ m_hue = hue;
+}
+
+int QT7MovieViewOutput::saturation() const
+{
+ return m_saturation;
+}
+
+void QT7MovieViewOutput::setSaturation(int saturation)
+{
+ m_saturation = saturation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h
new file mode 100644
index 0000000..336006c
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7MOVIEVIEWRENDERER_H
+#define QT7MOVIEVIEWRENDERER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmutex.h>
+
+#include <QtMultimedia/qvideowindowcontrol.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+#include "qt7videooutputcontrol.h"
+#include <QtMultimedia/qvideoframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+class QVideoFrame;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+class QT7MovieViewRenderer : public QT7VideoRendererControl
+{
+public:
+ QT7MovieViewRenderer(QObject *parent = 0);
+ ~QT7MovieViewRenderer();
+
+ void setEnabled(bool);
+ void setMovie(void *movie);
+ void updateNaturalSize(const QSize &newSize);
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+ void renderFrame(const QVideoFrame &);
+
+protected:
+ bool event(QEvent *event);
+
+private:
+ void setupVideoOutput();
+
+ void *m_movie;
+ void *m_movieView;
+ QSize m_nativeSize;
+ QAbstractVideoSurface *m_surface;
+ QVideoFrame m_currentFrame;
+ QMutex m_mutex;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm
new file mode 100644
index 0000000..342feb8
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#import <QTKit/QTKit.h>
+
+#include "qt7backend.h"
+
+#include "qt7playercontrol.h"
+#include "qt7movieviewrenderer.h"
+#include "qt7playersession.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QtMultimedia/qabstractvideobuffer.h>
+#include <QtMultimedia/qabstractvideosurface.h>
+#include <QtMultimedia/qvideosurfaceformat.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class NSBitmapVideoBuffer : public QAbstractVideoBuffer
+{
+public:
+ NSBitmapVideoBuffer(NSBitmapImageRep *buffer)
+ : QAbstractVideoBuffer(NoHandle)
+ , m_buffer(buffer)
+ , m_mode(NotMapped)
+ {
+ [m_buffer retain];
+ }
+
+ virtual ~NSBitmapVideoBuffer()
+ {
+ [m_buffer release];
+ }
+
+ MapMode mapMode() const { return m_mode; }
+
+ uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
+ {
+ if (mode != NotMapped && m_mode == NotMapped) {
+ if (numBytes)
+ *numBytes = [m_buffer bytesPerPlane];
+
+ if (bytesPerLine)
+ *bytesPerLine = [m_buffer bytesPerRow];
+
+ m_mode = mode;
+
+ return [m_buffer bitmapData];
+ } else {
+ return 0;
+ }
+ }
+
+ void unmap() { m_mode = NotMapped; }
+
+private:
+ NSBitmapImageRep *m_buffer;
+ MapMode m_mode;
+};
+
+
+#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
+
+@interface HiddenQTMovieView : QTMovieView
+{
+@private
+ QWidget *m_window;
+ QT7MovieViewRenderer *m_renderer;
+}
+
+- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
+- (void) setRenderer:(QT7MovieViewRenderer *)renderer;
+- (void) setDrawRect:(const QRect &)rect;
+@end
+
+@implementation HiddenQTMovieView
+
+- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer
+{
+ self = [super initWithFrame:NSZeroRect];
+ if (self) {
+ [self setControllerVisible:NO];
+ [self setDelegate:self];
+
+ self->m_renderer = renderer;
+
+ self->m_window = new QWidget;
+ self->m_window->setWindowOpacity(0.0);
+ self->m_window->show();
+ self->m_window->hide();
+
+ [(NSView *)(self->m_window->winId()) addSubview:self];
+ [self setDrawRect:QRect(0,0,1,1)];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [super dealloc];
+}
+
+- (void) setRenderer:(QT7MovieViewRenderer *)renderer
+{
+ m_renderer = renderer;
+}
+
+- (void) setDrawRect:(const QRect &)rect
+{
+ NSRect nsrect;
+ nsrect.origin.x = rect.x();
+ nsrect.origin.y = rect.y();
+ nsrect.size.width = rect.width();
+ nsrect.size.height = rect.height();
+ [self setFrame:nsrect];
+}
+
+- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
+{
+ // This method is called from QTMovieView just
+ // before the image will be drawn.
+ Q_UNUSED(view);
+ if (m_renderer) {
+ NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img];
+ CGRect bounds = [img extent];
+ int w = bounds.size.width;
+ int h = bounds.size.height;
+
+ // Swap red and blue (same as QImage::rgbSwapped, but without copy)
+ uchar *data = [bitmap bitmapData];
+ //qDebug() << data << w << h;
+ int bytesPerLine = [bitmap bytesPerRow];
+ for (int i=0; i<h; ++i) {
+ quint32 *p = (quint32*)data;
+ data += bytesPerLine;
+ quint32 *end = p + w;
+ while (p < end) {
+ *p = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
+ p++;
+ }
+ }
+
+ QVideoFrame frame( new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
+
+ //static int i=0;
+ //i++;
+ //QImage img([bitmap bitmapData], w, h, QImage::Format_RGB32);
+ //img.save(QString("img%1.jpg").arg(i));
+
+ [bitmap release];
+
+ if (m_renderer)
+ m_renderer->renderFrame(frame);
+ }
+
+ return img;
+}
+
+// Override this method so that the movie doesn't stop if
+// the window becomes invisible
+- (void)viewWillMoveToWindow:(NSWindow *)newWindow
+{
+ Q_UNUSED(newWindow);
+}
+
+
+VIDEO_TRANSPARENT(mouseDown);
+VIDEO_TRANSPARENT(mouseDragged);
+VIDEO_TRANSPARENT(mouseUp);
+VIDEO_TRANSPARENT(mouseMoved);
+VIDEO_TRANSPARENT(mouseEntered);
+VIDEO_TRANSPARENT(mouseExited);
+VIDEO_TRANSPARENT(rightMouseDown);
+VIDEO_TRANSPARENT(rightMouseDragged);
+VIDEO_TRANSPARENT(rightMouseUp);
+VIDEO_TRANSPARENT(otherMouseDown);
+VIDEO_TRANSPARENT(otherMouseDragged);
+VIDEO_TRANSPARENT(otherMouseUp);
+VIDEO_TRANSPARENT(keyDown);
+VIDEO_TRANSPARENT(keyUp);
+VIDEO_TRANSPARENT(scrollWheel)
+
+@end
+
+
+QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
+ :QT7VideoRendererControl(parent),
+ m_movie(0),
+ m_movieView(0),
+ m_surface(0)
+{
+}
+
+QT7MovieViewRenderer::~QT7MovieViewRenderer()
+{
+ [(HiddenQTMovieView*)m_movieView setRenderer:0];
+
+ QMutexLocker locker(&m_mutex);
+ m_currentFrame = QVideoFrame();
+ [(HiddenQTMovieView*)m_movieView release];
+}
+
+void QT7MovieViewRenderer::setupVideoOutput()
+{
+ AutoReleasePool pool;
+
+ qDebug() << "QT7MovieViewRenderer::setupVideoOutput" << m_movie << m_surface;
+
+ HiddenQTMovieView *movieView = (HiddenQTMovieView*)m_movieView;
+
+ if (movieView && !m_movie) {
+ [movieView setMovie:nil];
+ }
+
+ if (m_movie) {
+ NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+
+ m_nativeSize = QSize(size.width, size.height);
+
+ if (!movieView) {
+ movieView = [[HiddenQTMovieView alloc] initWithRenderer:this];
+ m_movieView = movieView;
+ [movieView setControllerVisible:NO];
+ }
+
+ [movieView setMovie:(QTMovie*)m_movie];
+ //[movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
+ }
+
+ if (m_surface && !m_nativeSize.isEmpty()) {
+ QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
+
+ if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
+ qDebug() << "Surface format was changed, stop the surface.";
+ m_surface->stop();
+ }
+
+ if (!m_surface->isActive()) {
+ qDebug() << "Starting the surface with format" << format;
+ if (!m_surface->start(format))
+ qDebug() << "failed to start video surface" << m_surface->error();
+ }
+ }
+}
+
+void QT7MovieViewRenderer::setEnabled(bool)
+{
+}
+
+void QT7MovieViewRenderer::setMovie(void *movie)
+{
+ if (movie == m_movie)
+ return;
+
+ QMutexLocker locker(&m_mutex);
+ m_movie = movie;
+ setupVideoOutput();
+}
+
+void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize)
+{
+ if (m_nativeSize != newSize) {
+ m_nativeSize = newSize;
+ setupVideoOutput();
+ }
+}
+
+QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
+{
+ return m_surface;
+}
+
+void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface)
+{
+ if (surface == m_surface)
+ return;
+
+ QMutexLocker locker(&m_mutex);
+
+ if (m_surface && m_surface->isActive())
+ m_surface->stop();
+
+ m_surface = surface;
+ setupVideoOutput();
+}
+
+void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ m_currentFrame = frame;
+ }
+
+ qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
+}
+
+bool QT7MovieViewRenderer::event(QEvent *event)
+{
+ if (event->type() == QEvent::User) {
+ QMutexLocker locker(&m_mutex);
+ if (m_surface->isActive())
+ m_surface->present(m_currentFrame);
+ }
+
+ return QT7VideoRendererControl::event(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7serviceplugin.h b/src/plugins/mediaservices/qt7/qt7serviceplugin.h
new file mode 100644
index 0000000..c5afda1
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7serviceplugin.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7SERVICEPLUGIN_H
+#define QT7SERVICEPLUGIN_H
+
+#include <QtMultimedia/qmediaserviceproviderplugin.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QT7ServicePlugin : public QMediaServiceProviderPlugin
+{
+public:
+ QStringList keys() const;
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGSTREAMERSERVICEPLUGIN_H
diff --git a/src/plugins/mediaservices/qt7/qt7serviceplugin.mm b/src/plugins/mediaservices/qt7/qt7serviceplugin.mm
new file mode 100644
index 0000000..c59a453
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7serviceplugin.mm
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 <QtCore/qstring.h>
+#include <QtCore/qdebug.h>
+
+#include "qt7serviceplugin.h"
+#include "qt7playerservice.h"
+
+#include <QtMultimedia/qmediaserviceprovider.h>
+
+QT_BEGIN_NAMESPACE
+
+QStringList QT7ServicePlugin::keys() const
+{
+ return QStringList()
+#ifdef QMEDIA_QT7_PLAYER
+ << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER);
+#endif
+}
+
+QMediaService* QT7ServicePlugin::create(QString const& key)
+{
+#ifdef QMEDIA_QT7_PLAYER
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
+ return new QT7PlayerService;
+#endif
+
+ qWarning() << "Attempt to create unknown service with key" << key;
+ return 0;
+}
+
+void QT7ServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+Q_EXPORT_PLUGIN2(qt7_serviceplugin, QT7ServicePlugin);
+
+QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h
new file mode 100644
index 0000000..2c60919
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 QT7VIDEOOUTPUTCONTROL_H
+#define QT7VIDEOOUTPUTCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qsize.h>
+
+#include <QtMultimedia/qvideooutputcontrol.h>
+#include <QtMultimedia/qvideowindowcontrol.h>
+#include <QtMultimedia/qvideowidgetcontrol.h>
+#include <QtMultimedia/qvideorenderercontrol.h>
+#include <QtMultimedia/qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+
+class QT7VideoOutput {
+public:
+ virtual ~QT7VideoOutput() {}
+ virtual void setEnabled(bool enabled) = 0;
+ virtual void setMovie(void *movie) = 0;
+ virtual void updateNaturalSize(const QSize &newSize) = 0;
+};
+
+class QT7VideoWindowControl : public QVideoWindowControl, public QT7VideoOutput
+{
+public:
+ virtual ~QT7VideoWindowControl() {}
+
+protected:
+ QT7VideoWindowControl(QObject *parent)
+ :QVideoWindowControl(parent)
+ {}
+};
+
+class QT7VideoRendererControl : public QVideoRendererControl, public QT7VideoOutput
+{
+public:
+ virtual ~QT7VideoRendererControl() {}
+
+protected:
+ QT7VideoRendererControl(QObject *parent)
+ :QVideoRendererControl(parent)
+ {}
+};
+
+class QT7VideoWidgetControl : public QVideoWidgetControl, public QT7VideoOutput
+{
+public:
+ virtual ~QT7VideoWidgetControl() {}
+
+protected:
+ QT7VideoWidgetControl(QObject *parent)
+ :QVideoWidgetControl(parent)
+ {}
+};
+
+class QT7VideoOutputControl : public QVideoOutputControl
+{
+Q_OBJECT
+public:
+ QT7VideoOutputControl(QObject *parent = 0);
+ ~QT7VideoOutputControl();
+
+ void setSession(QT7PlayerSession *session);
+
+ QList<Output> availableOutputs() const;
+ void enableOutput(Output);
+
+ Output output() const;
+ void setOutput(Output output);
+
+signals:
+ void videoOutputChanged(QVideoOutputControl::Output);
+
+private:
+ QT7PlayerSession *m_session;
+ Output m_output;
+ QList<Output> m_outputs;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm
new file mode 100644
index 0000000..a468431
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 "qt7playercontrol.h"
+#include "qt7videooutputcontrol.h"
+#include "qt7playersession.h"
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QT7VideoOutputControl::QT7VideoOutputControl(QObject *parent)
+ :QVideoOutputControl(parent),
+ m_session(0),
+ m_output(QVideoOutputControl::NoOutput)
+{
+}
+
+QT7VideoOutputControl::~QT7VideoOutputControl()
+{
+}
+
+void QT7VideoOutputControl::setSession(QT7PlayerSession *session)
+{
+ m_session = session;
+}
+
+QList<QVideoOutputControl::Output> QT7VideoOutputControl::availableOutputs() const
+{
+ return m_outputs;
+}
+
+void QT7VideoOutputControl::enableOutput(QVideoOutputControl::Output output)
+{
+ if (!m_outputs.contains(output))
+ m_outputs.append(output);
+}
+
+QVideoOutputControl::Output QT7VideoOutputControl::output() const
+{
+ return m_output;
+}
+
+void QT7VideoOutputControl::setOutput(Output output)
+{
+ if (m_output != output) {
+ m_output = output;
+ emit videoOutputChanged(m_output);
+ }
+
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qt7videooutputcontrol.cpp"
+