summaryrefslogtreecommitdiffstats
path: root/src/plugins/mediaservices/qt7
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-02-18 14:58:16 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-02-18 14:58:16 (GMT)
commit50fe29b569849d05db1625fa30fbd8618a941c5a (patch)
treef30a6a1600c63e788aca29b71ca07bec2c554b47 /src/plugins/mediaservices/qt7
parentc18beac8163634b48bbf1e7280923e96f5ef0a51 (diff)
parent7c2ccecd96631caf290e070f9e34bbe54be275ce (diff)
downloadQt-50fe29b569849d05db1625fa30fbd8618a941c5a.zip
Qt-50fe29b569849d05db1625fa30fbd8618a941c5a.tar.gz
Qt-50fe29b569849d05db1625fa30fbd8618a941c5a.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-multimedia-team into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/qt-multimedia-team: (90 commits) Switch RGB24 and BGR24 shaders back. Disable the full screen video widget tests on X11. Use the IPropertyBag interface to get audio device names. Fix qmlgraphicsvideo.pro Add qmlgraphicsvideo test to auto.pro Fix QMediaServiceProvider test. Make QMediaPlaylist test pass. Fix QMediaPlayer test failure. Fix qmlaudio.pro. Make QMediaPlayer test compile. Remove tests not relevant to playback functionality. Remove tests that depend on playlist plugins. Support YUV444 formats in QPainterVideoSurface. Add qmlaudio test to auto.pro Fix license headers. Remove unused files. Extend the mappings between Direct Show and QVideoFrame color formats. Don't paint RGB24 frames as BGR24. Added multimedia to qmlviewer Fixed compile error in pulseaudio soundeffect implementation ...
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.h142
-rw-r--r--src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm412
-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.h112
-rw-r--r--src/plugins/mediaservices/qt7/qt7movierenderer.mm441
-rw-r--r--src/plugins/mediaservices/qt7/qt7movievideowidget.h131
-rw-r--r--src/plugins/mediaservices/qt7/qt7movievideowidget.mm409
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewoutput.h118
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewoutput.mm307
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewrenderer.h96
-rw-r--r--src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm341
-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.h134
-rw-r--r--src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm93
26 files changed, 4225 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..9aa9887
--- /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(QtMedia::MetaData key) const;
+ void setMetaData(QtMedia::MetaData key, const QVariant &value);
+ QList<QtMedia::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<QtMedia::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..96b7a68
--- /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(QtMedia::MetaData key) const
+{
+ return m_tags.value(key);
+}
+
+void QT7PlayerMetaDataControl::setMetaData(QtMedia::MetaData key, QVariant const &value)
+{
+ Q_UNUSED(key);
+ Q_UNUSED(value);
+}
+
+QList<QtMedia::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(QtMedia::AlbumArtist, metaMap.value(QLatin1String("ART")));
+ m_tags.insert(QtMedia::AlbumTitle, metaMap.value(QLatin1String("alb")));
+ m_tags.insert(QtMedia::Title, metaMap.value(QLatin1String("nam")));
+ m_tags.insert(QtMedia::Date, metaMap.value(QLatin1String("day")));
+ m_tags.insert(QtMedia::Genre, metaMap.value(QLatin1String("gnre")));
+ m_tags.insert(QtMedia::TrackNumber, metaMap.value(QLatin1String("trk")));
+ m_tags.insert(QtMedia::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..2a6bab7
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** 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;
+ void setPlaybackRate(qreal rate);
+
+ void setPosition(qint64 pos);
+
+ void play();
+ void pause();
+ void stop();
+
+ void setVolume(int volume);
+ void setMuted(bool muted);
+
+ void processEOS();
+
+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..d9bb646
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm
@@ -0,0 +1,412 @@
+/****************************************************************************
+**
+** 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;
+@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];
+
+ [movie retain];
+ }
+}
+
+- (void) processEOS:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ m_session->processEOS();
+}
+
+@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;
+
+ qDebug() << "set output" << output;
+
+ 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()
+{
+ m_state = QMediaPlayer::PlayingState;
+
+ float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+ [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate];
+
+ emit stateChanged(m_state);
+}
+
+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;
+
+ QUrl url;
+
+ if (!content.isNull())
+ url = content.canonicalUrl();
+ else
+ return;
+
+ NSError *err = 0;
+ QTDataReference *dataRef = 0;
+
+ if ( url.scheme() == "file" ) {
+ NSString *nsFileName = (NSString *)qString2CFStringRef( url.toLocalFile() );
+ dataRef = [QTDataReference dataReferenceWithReferenceToFile:nsFileName];
+ } else {
+ NSString *urlString = (NSString *)qString2CFStringRef( url.toString() );
+ NSURL *url = [NSURL URLWithString: urlString];
+ dataRef = [QTDataReference dataReferenceWithReferenceToURL:url];
+ }
+
+ NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:
+ dataRef, QTMovieDataReferenceAttribute,
+ [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]);
+
+ qDebug() << "QT7PlayerSession::setMedia error" << description;
+ emit error(QMediaPlayer::FormatError, description );
+ } else {
+ [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
+
+ if (m_videoOutput) {
+ m_videoOutput->setEnabled(true);
+ m_videoOutput->setMovie(m_QTMovie);
+ }
+
+ emit durationChanged(duration());
+ emit audioAvailableChanged(isAudioAvailable());
+ emit videoAvailableChanged(isVideoAvailable());
+
+ [(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);
+}
+
+#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..4543152
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movierenderer.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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);
+
+ 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..8cb0f46
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movierenderer.mm
@@ -0,0 +1,441 @@
+/****************************************************************************
+**
+** 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:@"QTMovieCurrentSizeAttribute"] 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_visualContext = 0;
+ }
+ }
+
+ if (!m_visualContext) {
+ if (m_usingGLContext) {
+ qDebug() << "Building OpenGL visual context";
+ m_currentGLContext = QGLContext::currentContext();
+ if (!createGLVisualContext()) {
+ qWarning() << "QT7MovieRenderer: failed to create visual context";
+ return;
+ }
+ } else {
+ qDebug() << "Building Pixel Buffer visual context";
+ 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);
+
+
+#endif
+
+ m_displayLink->start();
+}
+
+void QT7MovieRenderer::setEnabled(bool)
+{
+}
+
+void QT7MovieRenderer::setMovie(void *movie)
+{
+ qDebug() << "QT7MovieRenderer::setMovie" << movie;
+
+ if (m_movie == movie)
+ return;
+
+ QMutexLocker locker(&m_mutex);
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+ //ensure the old movie doesn't hold the visual context, otherwise it can't be reused
+ if (m_movie && m_visualContext)
+ SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], 0);
+#endif
+
+ m_movie = movie;
+ 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..266dad4
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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);
+
+ 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..e1e0162
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** 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:@"QTMovieCurrentSizeAttribute"] 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();
+}
+
+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..7f3ff91
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** 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);
+
+ 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..8182797
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** 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:@"QTMovieCurrentSizeAttribute"] 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();
+}
+
+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..6f381f8
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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);
+
+ 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..e08d0f3
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** 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();
+}
+
+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..2faf6bb
--- /dev/null
+++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 <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;
+};
+
+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"
+