diff --git a/.cproject b/.cproject
index fe231d90..be83e8e1 100644
--- a/.cproject
+++ b/.cproject
@@ -5,83 +5,290 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
@@ -108,11 +315,218 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1e6b9b1..7a5d835b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,7 +25,7 @@
################################################################################
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.8.6)
################ ADD CMAKE MODULES ##################
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")
diff --git a/include/OpenShot.h b/include/OpenShot.h
index 23c59067..60d56ddf 100644
--- a/include/OpenShot.h
+++ b/include/OpenShot.h
@@ -123,6 +123,11 @@
#include "TextReader.h"
#include "Timeline.h"
+/* Qt Video Player */
+#include "Qt/videoplayer.h"
+#include "Qt/videowidget.h"
+#include "Qt/videowidgetsurface.h"
+
/* Effects */
#include "effects/ChromaKey.h"
#include "effects/Deinterlace.h"
diff --git a/include/Qt/videoplayer.h b/include/Qt/videoplayer.h
new file mode 100644
index 00000000..d1fbc95a
--- /dev/null
+++ b/include/Qt/videoplayer.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #ifndef VIDEOPLAYER_H
+ #define VIDEOPLAYER_H
+
+ #include
+ #include
+
+ class QAbstractButton;
+ class QAbstractVideoSurface;
+ class QSlider;
+
+ 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/include/Qt/videowidget.h b/include/Qt/videowidget.h
new file mode 100644
index 00000000..26a9f5e7
--- /dev/null
+++ b/include/Qt/videowidget.h
@@ -0,0 +1,72 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #ifndef VIDEOWIDGET_H
+ #define VIDEOWIDGET_H
+
+ #include "videowidgetsurface.h"
+
+ #include
+
+ class QAbstractVideoSurface;
+
+ class VideoWidgetSurface;
+
+ 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;
+ };
+
+ #endif
diff --git a/include/Qt/videowidgetsurface.h b/include/Qt/videowidgetsurface.h
new file mode 100644
index 00000000..0568d3b9
--- /dev/null
+++ b/include/Qt/videowidgetsurface.h
@@ -0,0 +1,82 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #ifndef VIDEOWIDGETSURFACE_H
+ #define VIDEOWIDGETSURFACE_H
+
+ #include
+ #include
+ #include
+ #include
+ #include
+
+using namespace std;
+
+ class VideoWidgetSurface : public QAbstractVideoSurface
+ {
+ Q_OBJECT
+
+ public:
+ VideoWidgetSurface(QWidget *widget=0, QObject *parent = 0);
+
+ QList 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;
+ };
+
+ #endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3abe2b21..c90c2e62 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -65,13 +65,21 @@ IF (QT_EXECUTABLE)
ENDIF (QT_EXECUTABLE)
# Find QT4 libraries
-FIND_PACKAGE(Qt4 REQUIRED)
+FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtMultimedia REQUIRED)
# Include Qt headers (needed for compile)
include(${QT_USE_FILE})
include_directories(${QT_INCLUDES})
add_definitions(${QT_DEFINITIONS})
+# Add Multimedia library
+SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_QTMULTIMEDIA_LIBRARY})
+
+# Moc all Qt headers
+FILE(GLOB QT_HEADERS "/home/jonathan/apps/libopenshot/include/Qt/*.h")
+qt4_wrap_cpp (QT_MOC_FILES ${QT_HEADERS})
+message('${QT_MOC_FILES}')
+
################# BLACKMAGIC DECKLINK ###################
# Find BlackMagic DeckLinkAPI libraries
@@ -134,6 +142,12 @@ SET ( OPENSHOT_SOURCE_FILES
TextReader.cpp
Timeline.cpp
+ # Qt Video Player
+ ${QT_MOC_FILES}
+ Qt/videoplayer.cpp
+ Qt/videowidget.cpp
+ Qt/videowidgetsurface.cpp
+
# Third Party JSON Parser
../thirdparty/jsoncpp/src/lib_json/json_reader.cpp
../thirdparty/jsoncpp/src/lib_json/json_value.cpp
diff --git a/src/Main.cpp b/src/Main.cpp
index 6bd70561..38b76a82 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -33,20 +33,96 @@
#include "../include/OpenShot.h"
#include "../include/Json.h"
#include
-#include
+#include
+#include
+#include
+#include
using namespace openshot;
using namespace tr1;
-
int main(int argc, char* argv[])
{
+
+ // Start Qt Application
+ QApplication app(argc, argv);\
+
+ // Init video player widget
+ VideoPlayer player;
+ player.showMaximized();
+
+ // Prepare video surface
+ VideoWidgetSurface * videoWidget = new VideoWidgetSurface(&player);
+ QSize videoSize(1280, 720); // supplement with your video dimensions
+
+ // look at VideoWidgetSurface::supportedPixelFormats for supported formats
+ QVideoSurfaceFormat format( videoSize, QVideoFrame::Format_ARGB32);
+
+
+
+ // Get test frame
FFmpegReader r2("/home/jonathan/Videos/sintel_trailer-720p.mp4");
r2.Open();
- SDLPlayer p;
- p.Reader(&r2);
- p.Play();
- return 0;
+ tr1::shared_ptr frame = r2.GetFrame(600);
+
+ // Get image
+ tr1::shared_ptr image = r2.GetFrame(300)->GetImage();
+
+ // Create Qt Video Frame
+ QVideoFrame aFrame(32 * image->size().width() * image->size().height(), QSize(image->size().width(), image->size().height()), 32 * image->size().width(), QVideoFrame::Format_ARGB32);
+
+ // Get a reference to the internal videoframe buffer
+ aFrame.map(QAbstractVideoBuffer::WriteOnly);
+ uchar *pixels = aFrame.bits();
+
+ // Copy pixel data from ImageMagick to Qt
+ Magick::Blob my_blob_1;
+ image->write(&my_blob_1); // or PNG img1.write(&my_blob_1); const QByteArray imageData1((char*)(my_blob_1.data()),my_blob_1.length());
+
+ pixels = (uchar*)(my_blob_1.data()),my_blob_1.length();
+ //memcpy(pixels, my_blob_1.data(), my_blob_1.length());
+
+ // Get a list of pixels from source image
+// const Magick::PixelPacket *pixel_packets = frame->GetPixels();
+//
+// // Fill the AVFrame with RGB image data
+// int source_total_pixels = image->size().width() * image->size().height();
+// for (int packet = 0, row = 0; packet < source_total_pixels; packet++, row+=4)
+// {
+// // Update buffer (which is already linked to the AVFrame: pFrameRGB)
+// // Each color needs to be 8 bit (so I'm bit shifting the 16 bit ints)
+// pixels[row] = 255;
+// pixels[row+1] = 255;
+// pixels[row+2] = pixel_packets[packet].green >> 8;
+// pixels[row+3] = pixel_packets[packet].blue >> 8;
+// //pixels[row] = qRgb(pixel_packets[packet].red, pixel_packets[packet].green, pixel_packets[packet].blue);
+// }
+ aFrame.unmap();
+
+ // Start video player (which sets format's size)
+ videoWidget->start(format);
+
+ // Display frame
+ videoWidget->present(aFrame);
+
+
+
+ // Start Qt App
+ return app.exec();
+
+
+
+
+
+
+
+
+// FFmpegReader r2("/home/jonathan/Videos/sintel_trailer-720p.mp4");
+// r2.Open();
+// SDLPlayer p;
+// p.Reader(&r2);
+// p.Play();
+// return 0;
diff --git a/src/Qt/videoplayer.cpp b/src/Qt/videoplayer.cpp
new file mode 100644
index 00000000..0a3d9199
--- /dev/null
+++ b/src/Qt/videoplayer.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include "../../include/Qt/videoplayer.h"
+ #include "../../include/Qt/videowidget.h"
+
+ #include
+
+ 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()
+ {
+ QStringList supportedFormats;
+ foreach (QString fmt, QMovie::supportedFormats())
+ supportedFormats << fmt;
+ foreach (QString fmt, QImageReader::supportedImageFormats())
+ supportedFormats << fmt;
+
+ QString filter = "Images (";
+ foreach ( QString fmt, supportedFormats) {
+ filter.append(QString("*.%1 ").arg(fmt));
+ }
+ filter.append(")");
+
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),
+ QDir::homePath(), filter);
+
+ if (!fileName.isEmpty()) {
+ 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/src/Qt/videowidget.cpp b/src/Qt/videowidget.cpp
new file mode 100644
index 00000000..0a01c3f1
--- /dev/null
+++ b/src/Qt/videowidget.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include "../../include/Qt/videowidget.h"
+ #include "../../include/Qt/videowidgetsurface.h"
+
+ #include
+
+ 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);
+ }
+
+ VideoWidget::~VideoWidget()
+ {
+ delete surface;
+ }
+
+ QSize VideoWidget::sizeHint() const
+ {
+ return surface->surfaceFormat().sizeHint();
+ }
+
+ void VideoWidget::paintEvent(QPaintEvent *event)
+ {
+ QPainter painter(this);
+
+ if (surface->isActive()) {
+ 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());
+ }
+ }
+
+ void VideoWidget::resizeEvent(QResizeEvent *event)
+ {
+ QWidget::resizeEvent(event);
+
+ surface->updateVideoRect();
+ }
diff --git a/src/Qt/videowidgetsurface.cpp b/src/Qt/videowidgetsurface.cpp
new file mode 100644
index 00000000..46483fb5
--- /dev/null
+++ b/src/Qt/videowidgetsurface.cpp
@@ -0,0 +1,164 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include "../../include/Qt/videowidgetsurface.h"
+
+ #include
+
+ VideoWidgetSurface::VideoWidgetSurface(QWidget *widget, QObject *parent)
+ : QAbstractVideoSurface(parent)
+ , widget(widget)
+ , imageFormat(QImage::Format_Invalid)
+ {
+ }
+
+ QList VideoWidgetSurface::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+ {
+ if (handleType == QAbstractVideoBuffer::NoHandle) {
+ return QList()
+ << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_ARGB32
+ << QVideoFrame::Format_ARGB32_Premultiplied
+ << QVideoFrame::Format_RGB565
+ << QVideoFrame::Format_RGB555;
+ } else {
+ return QList();
+ }
+ }
+
+ bool VideoWidgetSurface::isFormatSupported(
+ const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const
+ {
+ Q_UNUSED(similar);
+
+ const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
+ const QSize size = format.frameSize();
+
+ return imageFormat != QImage::Format_Invalid
+ && !size.isEmpty()
+ && format.handleType() == QAbstractVideoBuffer::NoHandle;
+ }
+
+ bool VideoWidgetSurface::start(const QVideoSurfaceFormat &format)
+ {
+ const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(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;
+ }
+ }
+
+ void VideoWidgetSurface::stop()
+ {
+ currentFrame = QVideoFrame();
+ targetRect = QRect();
+
+ QAbstractVideoSurface::stop();
+
+ widget->update();
+ }
+
+ bool VideoWidgetSurface::present(const QVideoFrame &frame)
+ {
+ if (surfaceFormat().pixelFormat() != frame.pixelFormat()
+ || surfaceFormat().frameSize() != frame.size()) {
+ setError(IncorrectFormatError);
+ stop();
+
+ return false;
+ } else {
+ cout << "Paint new frame!" << endl;
+ currentFrame = frame;
+
+ widget->repaint(targetRect);
+
+ return true;
+ }
+ }
+
+ void VideoWidgetSurface::updateVideoRect()
+ {
+ cout << "update rect" << endl;
+ //QSize size = surfaceFormat().sizeHint();
+ QSize size(1280, 720);
+ //size.scale(widget->size().boundedTo(size), Qt::KeepAspectRatio);
+
+ targetRect = QRect(QPoint(0, 0), size);
+ targetRect.moveCenter(widget->rect().center());
+
+ }
+
+ 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();
+ }
+ }