diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2009-08-24 22:33:55 (GMT) |
---|---|---|
committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2009-08-24 23:02:27 (GMT) |
commit | b8cc86956ae45a6d07dfca04301e1b4905615ee7 (patch) | |
tree | 3587b6d2c66a5ad2505732e5f67df56dcccd5673 /examples/video | |
parent | e4002434bfde5c8206463ea3a0d4140835619944 (diff) | |
download | Qt-b8cc86956ae45a6d07dfca04301e1b4905615ee7.zip Qt-b8cc86956ae45a6d07dfca04301e1b4905615ee7.tar.gz Qt-b8cc86956ae45a6d07dfca04301e1b4905615ee7.tar.bz2 |
Integrate QAbstractVideoSurface API.
This introduces a QAbstractVideoSurface interface for implementing arbitrary
video outputs, and a QVideoFrame type. Also included is the
QVideoSurfaceFormat class which is used to configure the input to a video
surface, and the QAbstractVideoBuffer class which allows QVideoFrames
to be constructed from non-native frame types.
Reviewed-by: Dmytro Poplavskiy
Diffstat (limited to 'examples/video')
-rw-r--r-- | examples/video/video.pro | 6 | ||||
-rw-r--r-- | examples/video/videographicsitem/main.cpp | 55 | ||||
-rw-r--r-- | examples/video/videographicsitem/videographicsitem.pro | 16 | ||||
-rw-r--r-- | examples/video/videographicsitem/videoitem.cpp | 144 | ||||
-rw-r--r-- | examples/video/videographicsitem/videoitem.h | 78 | ||||
-rw-r--r-- | examples/video/videographicsitem/videoplayer.cpp | 210 | ||||
-rw-r--r-- | examples/video/videographicsitem/videoplayer.h | 86 | ||||
-rw-r--r-- | examples/video/videowidget/main.cpp | 54 | ||||
-rw-r--r-- | examples/video/videowidget/videoplayer.cpp | 183 | ||||
-rw-r--r-- | examples/video/videowidget/videoplayer.h | 79 | ||||
-rw-r--r-- | examples/video/videowidget/videowidget.cpp | 114 | ||||
-rw-r--r-- | examples/video/videowidget/videowidget.h | 76 | ||||
-rw-r--r-- | examples/video/videowidget/videowidget.pro | 14 | ||||
-rw-r--r-- | examples/video/videowidget/videowidgetsurface.cpp | 175 | ||||
-rw-r--r-- | examples/video/videowidget/videowidgetsurface.h | 81 |
15 files changed, 1371 insertions, 0 deletions
diff --git a/examples/video/video.pro b/examples/video/video.pro new file mode 100644 index 0000000..f0b63b6 --- /dev/null +++ b/examples/video/video.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + videographicsitem \ + videowidget + diff --git a/examples/video/videographicsitem/main.cpp b/examples/video/videographicsitem/main.cpp new file mode 100644 index 0000000..b80ac47 --- /dev/null +++ b/examples/video/videographicsitem/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include <QtGui/QApplication> + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + VideoPlayer player; + player.show(); + + return app.exec(); +} + diff --git a/examples/video/videographicsitem/videographicsitem.pro b/examples/video/videographicsitem/videographicsitem.pro new file mode 100644 index 0000000..7e0b4c5 --- /dev/null +++ b/examples/video/videographicsitem/videographicsitem.pro @@ -0,0 +1,16 @@ +QT += multimedia + +contains(QT_CONFIG, opengl): QT += opengl + +HEADERS += videoplayer.h \ + videoitem.h + +SOURCES += main.cpp \ + videoplayer.cpp \ + videoitem.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/video/videographicsitem +sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro *.png images +sources.path = $$[QT_INSTALL_EXAMPLES]/video/videographicsitem +INSTALLS += target sources diff --git a/examples/video/videographicsitem/videoitem.cpp b/examples/video/videographicsitem/videoitem.cpp new file mode 100644 index 0000000..6c17d6a --- /dev/null +++ b/examples/video/videographicsitem/videoitem.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoitem.h" + +#include <QtMultimedia> + +VideoItem::VideoItem(QGraphicsItem *parent) + : QGraphicsItem(parent) + , imageFormat(QImage::Format_Invalid) + , framePainted(false) +{ +} + +VideoItem::~VideoItem() +{ +} + +QRectF VideoItem::boundingRect() const +{ + return QRectF(QPointF(0,0), surfaceFormat().sizeHint()); +} + +void VideoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) { + const QTransform oldTransform = painter->transform(); + + if (surfaceFormat().scanLineDirection() == QVideoSurfaceFormat::BottomToTop) { + painter->scale(1, -1); + painter->translate(0, -boundingRect().height()); + } + + painter->drawImage(boundingRect(), QImage( + currentFrame.bits(), + imageSize.width(), + imageSize.height(), + imageFormat)); + + painter->setTransform(oldTransform); + + framePainted = true; + + currentFrame.unmap(); + } +} + +QList<QVideoFrame::PixelFormat> VideoItem::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + if (handleType == QAbstractVideoBuffer::NoHandle) { + return QList<QVideoFrame::PixelFormat>() + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_ARGB32 + << QVideoFrame::Format_ARGB32_Premultiplied + << QVideoFrame::Format_RGB565 + << QVideoFrame::Format_RGB555; + } else { + return QList<QVideoFrame::PixelFormat>(); + } +} + +bool VideoItem::start(const QVideoSurfaceFormat &format) +{ + if (isFormatSupported(format)) { + imageFormat = QVideoFrame::equivalentImageFormat(format.pixelFormat()); + imageSize = format.frameSize(); + framePainted = true; + + QAbstractVideoSurface::start(format); + + prepareGeometryChange(); + + return true; + } else { + return false; + } +} + +void VideoItem::stop() +{ + currentFrame = QVideoFrame(); + framePainted = false; + + QAbstractVideoSurface::stop(); +} + +bool VideoItem::present(const QVideoFrame &frame) +{ + if (!framePainted) { + if (!isStarted()) + setError(StoppedError); + + return false; + } else { + currentFrame = frame; + framePainted = false; + + update(); + + return true; + } +} diff --git a/examples/video/videographicsitem/videoitem.h b/examples/video/videographicsitem/videoitem.h new file mode 100644 index 0000000..868cd54 --- /dev/null +++ b/examples/video/videographicsitem/videoitem.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOITEM_H +#define VIDEOITEM_H + +#include <QtMultimedia/QAbstractVideoSurface> +#include <QtGui/QGraphicsItem> + +class VideoItem + : public QAbstractVideoSurface, + public QGraphicsItem +{ + Q_OBJECT +public: + explicit VideoItem(QGraphicsItem *parentItem = 0); + ~VideoItem(); + + QRectF boundingRect() const; + void paint( + QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + //video surface + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + bool present(const QVideoFrame &frame); + +private: + QImage::Format imageFormat; + QSize imageSize; + + QVideoFrame currentFrame; + bool framePainted; +}; + +#endif + diff --git a/examples/video/videographicsitem/videoplayer.cpp b/examples/video/videographicsitem/videoplayer.cpp new file mode 100644 index 0000000..85a5527 --- /dev/null +++ b/examples/video/videographicsitem/videoplayer.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" +#include "videoitem.h" + +#include <QtMultimedia> + +#ifndef QT_NO_OPENGL +# include <QtOpenGL/QGLWidget> +#endif + +VideoPlayer::VideoPlayer(QWidget *parent, Qt::WindowFlags flags) + : QWidget(parent, flags) + , videoItem(0) + , playButton(0) + , positionSlider(0) +{ + connect(&movie, SIGNAL(stateChanged(QMovie::MovieState)), + this, SLOT(movieStateChanged(QMovie::MovieState))); + connect(&movie, SIGNAL(frameChanged(int)), + this, SLOT(frameChanged(int))); + + videoItem = new VideoItem; + + QGraphicsScene *scene = new QGraphicsScene(this); + QGraphicsView *graphicsView = new QGraphicsView(scene); + +#ifndef QT_NO_OPENGL + graphicsView->setViewport(new QGLWidget); +#endif + + scene->addItem(videoItem); + + QSlider *rotateSlider = new QSlider(Qt::Horizontal); + rotateSlider->setRange(-180, 180); + rotateSlider->setValue(0); + + connect(rotateSlider, SIGNAL(valueChanged(int)), + this, SLOT(rotateVideo(int))); + + QAbstractButton *openButton = new QPushButton(tr("Open...")); + connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); + + playButton = new QPushButton; + playButton->setEnabled(false); + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + + connect(playButton, SIGNAL(clicked()), + this, SLOT(play())); + + positionSlider = new QSlider(Qt::Horizontal); + positionSlider->setRange(0, 0); + + connect(positionSlider, SIGNAL(sliderMoved(int)), + this, SLOT(setPosition(int))); + + connect(&movie, SIGNAL(frameChanged(int)), + positionSlider, SLOT(setValue(int))); + + QBoxLayout *controlLayout = new QHBoxLayout; + controlLayout->setMargin(0); + controlLayout->addWidget(openButton); + controlLayout->addWidget(playButton); + controlLayout->addWidget(positionSlider); + + QBoxLayout *layout = new QVBoxLayout; + layout->addWidget(graphicsView); + layout->addWidget(rotateSlider); + layout->addLayout(controlLayout); + + setLayout(layout); +} + +VideoPlayer::~VideoPlayer() +{ +} + +void VideoPlayer::openFile() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie")); + + if (!fileName.isEmpty()) { + if (videoItem->isStarted()) + videoItem->stop(); + + movie.setFileName(fileName); + + playButton->setEnabled(true); + positionSlider->setMaximum(movie.frameCount()); + + movie.jumpToFrame(0); + } +} + +void VideoPlayer::play() +{ + switch(movie.state()) { + case QMovie::NotRunning: + movie.start(); + break; + case QMovie::Paused: + movie.setPaused(false); + break; + case QMovie::Running: + movie.setPaused(true); + break; + } +} + +void VideoPlayer::movieStateChanged(QMovie::MovieState state) +{ + switch(state) { + case QMovie::NotRunning: + case QMovie::Paused: + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + break; + case QMovie::Running: + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + break; + } +} + +void VideoPlayer::frameChanged(int frame) +{ + if (!presentImage(movie.currentImage())) { + movie.stop(); + playButton->setEnabled(false); + positionSlider->setMaximum(0); + } else { + positionSlider->setValue(frame); + } +} + +void VideoPlayer::setPosition(int frame) +{ + movie.jumpToFrame(frame); +} + +void VideoPlayer::rotateVideo(int angle) +{ + //rotate around the center of video element + qreal x = videoItem->boundingRect().width() / 2.0; + qreal y = videoItem->boundingRect().height() / 2.0; + videoItem->setTransform(QTransform().translate(x, y).rotate(angle).translate(-x, -y)); +} + +bool VideoPlayer::presentImage(const QImage &image) +{ + QVideoFrame frame(image); + + if (!frame.isValid()) + return false; + + QVideoSurfaceFormat currentFormat = videoItem->surfaceFormat(); + + if (frame.pixelFormat() != currentFormat.pixelFormat() + || frame.size() != currentFormat.frameSize()) { + QVideoSurfaceFormat format(frame.size(), frame.pixelFormat()); + + if (!videoItem->start(format)) + return false; + } + + if (!videoItem->present(frame)) { + videoItem->stop(); + + return false; + } else { + return true; + } +} diff --git a/examples/video/videographicsitem/videoplayer.h b/examples/video/videographicsitem/videoplayer.h new file mode 100644 index 0000000..246f727 --- /dev/null +++ b/examples/video/videographicsitem/videoplayer.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOPLAYER_H +#define VIDEOPLAYER_H + +#include <QtGui/QMovie> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QAbstractVideoSurface; +class QSlider; +QT_END_NAMESPACE + + +class VideoItem; + +class VideoPlayer : public QWidget +{ + Q_OBJECT +public: + VideoPlayer(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~VideoPlayer(); + + QSize sizeHint() const { return QSize(800, 600); } + +public slots: + void openFile(); + void play(); + +private slots: + void movieStateChanged(QMovie::MovieState state); + void frameChanged(int frame); + void setPosition(int frame); + void rotateVideo(int angle); + +private: + bool presentImage(const QImage &image); + + QMovie movie; + VideoItem *videoItem; + QAbstractButton *playButton; + QSlider *positionSlider; +}; + +#endif + diff --git a/examples/video/videowidget/main.cpp b/examples/video/videowidget/main.cpp new file mode 100644 index 0000000..4fba301 --- /dev/null +++ b/examples/video/videowidget/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include <QtGui/QApplication> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + VideoPlayer player; + player.show(); + + return app.exec(); +} diff --git a/examples/video/videowidget/videoplayer.cpp b/examples/video/videowidget/videoplayer.cpp new file mode 100644 index 0000000..2e4c758 --- /dev/null +++ b/examples/video/videowidget/videoplayer.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include "videowidget.h" + +#include <QtMultimedia> + +VideoPlayer::VideoPlayer(QWidget *parent) + : QWidget(parent) + , surface(0) + , playButton(0) + , positionSlider(0) +{ + connect(&movie, SIGNAL(stateChanged(QMovie::MovieState)), + this, SLOT(movieStateChanged(QMovie::MovieState))); + connect(&movie, SIGNAL(frameChanged(int)), + this, SLOT(frameChanged(int))); + + VideoWidget *videoWidget = new VideoWidget; + surface = videoWidget->videoSurface(); + + QAbstractButton *openButton = new QPushButton(tr("Open...")); + connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); + + playButton = new QPushButton; + playButton->setEnabled(false); + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + + connect(playButton, SIGNAL(clicked()), + this, SLOT(play())); + + positionSlider = new QSlider(Qt::Horizontal); + positionSlider->setRange(0, 0); + + connect(positionSlider, SIGNAL(sliderMoved(int)), + this, SLOT(setPosition(int))); + + connect(&movie, SIGNAL(frameChanged(int)), + positionSlider, SLOT(setValue(int))); + + QBoxLayout *controlLayout = new QHBoxLayout; + controlLayout->setMargin(0); + controlLayout->addWidget(openButton); + controlLayout->addWidget(playButton); + controlLayout->addWidget(positionSlider); + + QBoxLayout *layout = new QVBoxLayout; + layout->addWidget(videoWidget); + layout->addLayout(controlLayout); + + setLayout(layout); +} + +VideoPlayer::~VideoPlayer() +{ +} + +void VideoPlayer::openFile() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie")); + + if (!fileName.isEmpty()) { + if (surface->isStarted()) + surface->stop(); + + movie.setFileName(fileName); + + playButton->setEnabled(true); + positionSlider->setMaximum(movie.frameCount()); + + movie.jumpToFrame(0); + } +} + +void VideoPlayer::play() +{ + switch(movie.state()) { + case QMovie::NotRunning: + movie.start(); + break; + case QMovie::Paused: + movie.setPaused(false); + break; + case QMovie::Running: + movie.setPaused(true); + break; + } +} + +void VideoPlayer::movieStateChanged(QMovie::MovieState state) +{ + switch(state) { + case QMovie::NotRunning: + case QMovie::Paused: + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + break; + case QMovie::Running: + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + break; + } +} + +void VideoPlayer::frameChanged(int frame) +{ + if (!presentImage(movie.currentImage())) { + movie.stop(); + playButton->setEnabled(false); + positionSlider->setMaximum(0); + } else { + positionSlider->setValue(frame); + } +} + +void VideoPlayer::setPosition(int frame) +{ + movie.jumpToFrame(frame); +} + +bool VideoPlayer::presentImage(const QImage &image) +{ + QVideoFrame frame(image); + + if (!frame.isValid()) + return false; + + QVideoSurfaceFormat currentFormat = surface->surfaceFormat(); + + if (frame.pixelFormat() != currentFormat.pixelFormat() + || frame.size() != currentFormat.frameSize()) { + QVideoSurfaceFormat format(frame.size(), frame.pixelFormat()); + + if (!surface->start(format)) + return false; + } + + if (!surface->present(frame)) { + surface->stop(); + + return false; + } else { + return true; + } +} diff --git a/examples/video/videowidget/videoplayer.h b/examples/video/videowidget/videoplayer.h new file mode 100644 index 0000000..76f3e9e --- /dev/null +++ b/examples/video/videowidget/videoplayer.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOPLAYER_H +#define VIDEOPLAYER_H + +#include <QtGui/QMovie> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QAbstractVideoSurface; +class QSlider; +QT_END_NAMESPACE + +class VideoPlayer : public QWidget +{ + Q_OBJECT +public: + VideoPlayer(QWidget *parent = 0); + ~VideoPlayer(); + +public slots: + void openFile(); + void play(); + +private slots: + void movieStateChanged(QMovie::MovieState state); + void frameChanged(int frame); + void setPosition(int frame); + +private: + bool presentImage(const QImage &image); + + QMovie movie; + QAbstractVideoSurface *surface; + QAbstractButton *playButton; + QSlider *positionSlider; +}; + +#endif diff --git a/examples/video/videowidget/videowidget.cpp b/examples/video/videowidget/videowidget.cpp new file mode 100644 index 0000000..b29d2ae --- /dev/null +++ b/examples/video/videowidget/videowidget.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videowidget.h" + +#include "videowidgetsurface.h" + +#include <QtMultimedia> + +//! [0] +VideoWidget::VideoWidget(QWidget *parent) + : QWidget(parent) + , surface(0) +{ + setAutoFillBackground(false); + setAttribute(Qt::WA_NoSystemBackground, true); + setAttribute(Qt::WA_PaintOnScreen, true); + + QPalette palette = this->palette(); + palette.setColor(QPalette::Background, Qt::black); + setPalette(palette); + + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + surface = new VideoWidgetSurface(this); +} +//! [0] + +//! [1] +VideoWidget::~VideoWidget() +{ + delete surface; +} +//! [1] + +//! [2] +QSize VideoWidget::sizeHint() const +{ + return surface->surfaceFormat().sizeHint(); +} +//! [2] + + +//! [3] +void VideoWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + if (surface->isStarted()) { + const QRect videoRect = surface->videoRect(); + + if (!videoRect.contains(event->rect())) { + QRegion region = event->region(); + region.subtract(videoRect); + + QBrush brush = palette().background(); + + foreach (const QRect &rect, region.rects()) + painter.fillRect(rect, brush); + } + + surface->paint(&painter); + } else { + painter.fillRect(event->rect(), palette().background()); + } +} +//! [3] + +//! [4] +void VideoWidget::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + surface->updateVideoRect(); +} +//! [4] diff --git a/examples/video/videowidget/videowidget.h b/examples/video/videowidget/videowidget.h new file mode 100644 index 0000000..737d32d --- /dev/null +++ b/examples/video/videowidget/videowidget.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include "videowidgetsurface.h" + +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QAbstractVideoSurface; +QT_END_NAMESPACE + +class VideoWidgetSurface; + +//! [0] +class VideoWidget : public QWidget +{ + Q_OBJECT +public: + VideoWidget(QWidget *parent = 0); + ~VideoWidget(); + + QAbstractVideoSurface *videoSurface() const { return surface; } + + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + +private: + VideoWidgetSurface *surface; +}; +//! [0] + +#endif diff --git a/examples/video/videowidget/videowidget.pro b/examples/video/videowidget/videowidget.pro new file mode 100644 index 0000000..a006f2f --- /dev/null +++ b/examples/video/videowidget/videowidget.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += multimedia + +HEADERS = \ + videoplayer.h \ + videowidget.h \ + videowidgetsurface.h + +SOURCES = \ + main.cpp \ + videoplayer.cpp \ + videowidget.cpp \ + videowidgetsurface.cpp diff --git a/examples/video/videowidget/videowidgetsurface.cpp b/examples/video/videowidget/videowidgetsurface.cpp new file mode 100644 index 0000000..6089b6f --- /dev/null +++ b/examples/video/videowidget/videowidgetsurface.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videowidgetsurface.h" + +#include <QtMultimedia> + +VideoWidgetSurface::VideoWidgetSurface(QWidget *widget, QObject *parent) + : QAbstractVideoSurface(parent) + , widget(widget) + , imageFormat(QImage::Format_Invalid) +{ +} + +//! [0] +QList<QVideoFrame::PixelFormat> VideoWidgetSurface::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + if (handleType == QAbstractVideoBuffer::NoHandle) { + return QList<QVideoFrame::PixelFormat>() + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_ARGB32 + << QVideoFrame::Format_ARGB32_Premultiplied + << QVideoFrame::Format_RGB565 + << QVideoFrame::Format_RGB555; + } else { + return QList<QVideoFrame::PixelFormat>(); + } +} +//! [0] + +//! [1] +bool VideoWidgetSurface::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const +{ + Q_UNUSED(similar); + + const QImage::Format imageFormat = QVideoFrame::equivalentImageFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + return imageFormat != QImage::Format_Invalid + && !size.isEmpty() + && format.handleType() == QAbstractVideoBuffer::NoHandle; +} +//! [1] + +//! [2] +bool VideoWidgetSurface::start(const QVideoSurfaceFormat &format) +{ + const QImage::Format imageFormat = QVideoFrame::equivalentImageFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) { + this->imageFormat = imageFormat; + imageSize = size; + sourceRect = format.viewport(); + + QAbstractVideoSurface::start(format); + + widget->updateGeometry(); + updateVideoRect(); + + return true; + } else { + return false; + } +} +//! [2] + +//! [3] +void VideoWidgetSurface::stop() +{ + currentFrame = QVideoFrame(); + targetRect = QRect(); + + QAbstractVideoSurface::stop(); + + widget->update(); +} +//! [3] + +//! [4] +bool VideoWidgetSurface::present(const QVideoFrame &frame) +{ + if (surfaceFormat().pixelFormat() != frame.pixelFormat() + || surfaceFormat().frameSize() != frame.size()) { + setError(IncorrectFormatError); + stop(); + + return false; + } else { + currentFrame = frame; + + widget->repaint(targetRect); + + return true; + } +} +//! [4] + +//! [5] +void VideoWidgetSurface::updateVideoRect() +{ + QSize size = surfaceFormat().sizeHint(); + size.scale(widget->size().boundedTo(size), Qt::KeepAspectRatio); + + targetRect = QRect(QPoint(0, 0), size); + targetRect.moveCenter(widget->rect().center()); +} +//! [5] + +//! [6] +void VideoWidgetSurface::paint(QPainter *painter) +{ + if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) { + const QTransform oldTransform = painter->transform(); + + if (surfaceFormat().scanLineDirection() == QVideoSurfaceFormat::BottomToTop) { + painter->scale(1, -1); + painter->translate(0, -widget->height()); + } + + QImage image( + currentFrame.bits(), + currentFrame.width(), + currentFrame.height(), + currentFrame.bytesPerLine(), + imageFormat); + + painter->drawImage(targetRect, image, sourceRect); + + painter->setTransform(oldTransform); + + currentFrame.unmap(); + } +} +//! [6] diff --git a/examples/video/videowidget/videowidgetsurface.h b/examples/video/videowidget/videowidgetsurface.h new file mode 100644 index 0000000..56ba329 --- /dev/null +++ b/examples/video/videowidget/videowidgetsurface.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOWIDGETSURFACE_H +#define VIDEOWIDGETSURFACE_H + +#include <QtCore/QRect> +#include <QtGui/QImage> +#include <QtMultimedia/QAbstractVideoSurface> +#include <QtMultimedia/QVideoFrame> + +//! [0] +class VideoWidgetSurface : public QAbstractVideoSurface +{ + Q_OBJECT +public: + VideoWidgetSurface(QWidget *widget, QObject *parent = 0); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + bool isFormatSupported(const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + + bool present(const QVideoFrame &frame); + + QRect videoRect() const { return targetRect; } + void updateVideoRect(); + + void paint(QPainter *painter); + +private: + QWidget *widget; + QImage::Format imageFormat; + QRect targetRect; + QSize imageSize; + QRect sourceRect; + QVideoFrame currentFrame; +}; +//! [0] + +#endif |