summaryrefslogtreecommitdiffstats
path: root/examples/multimediawidgets
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimediawidgets')
-rw-r--r--examples/multimediawidgets/camera/camera.cpp435
-rw-r--r--examples/multimediawidgets/camera/camera.h121
-rw-r--r--examples/multimediawidgets/camera/camera.pro25
-rw-r--r--examples/multimediawidgets/camera/camera.ui492
-rw-r--r--examples/multimediawidgets/camera/doc/images/camera-example.pngbin0 -> 13647 bytes
-rw-r--r--examples/multimediawidgets/camera/doc/src/camera.qdoc80
-rw-r--r--examples/multimediawidgets/camera/imagesettings.cpp125
-rw-r--r--examples/multimediawidgets/camera/imagesettings.h82
-rw-r--r--examples/multimediawidgets/camera/imagesettings.ui123
-rw-r--r--examples/multimediawidgets/camera/main.cpp53
-rw-r--r--examples/multimediawidgets/camera/videosettings.cpp191
-rw-r--r--examples/multimediawidgets/camera/videosettings.h82
-rw-r--r--examples/multimediawidgets/camera/videosettings.ui211
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/customvideoitem.pro16
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/main.cpp54
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.cpp145
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h78
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp174
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h84
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideosurface.pro4
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/customvideowidget.pro18
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/main.cpp53
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp143
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.h77
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.cpp113
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h70
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.cpp173
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h81
-rw-r--r--examples/multimediawidgets/declarative-camera/CameraButton.qml71
-rw-r--r--examples/multimediawidgets/declarative-camera/CameraPropertyButton.qml106
-rw-r--r--examples/multimediawidgets/declarative-camera/CameraPropertyPopup.qml122
-rw-r--r--examples/multimediawidgets/declarative-camera/FocusButton.qml62
-rw-r--r--examples/multimediawidgets/declarative-camera/PhotoCaptureControls.qml159
-rw-r--r--examples/multimediawidgets/declarative-camera/PhotoPreview.qml62
-rw-r--r--examples/multimediawidgets/declarative-camera/VideoCaptureControls.qml132
-rw-r--r--examples/multimediawidgets/declarative-camera/VideoPreview.qml72
-rw-r--r--examples/multimediawidgets/declarative-camera/ZoomControl.qml118
-rw-r--r--examples/multimediawidgets/declarative-camera/declarative-camera.pro10
-rw-r--r--examples/multimediawidgets/declarative-camera/declarative-camera.qml151
-rw-r--r--examples/multimediawidgets/declarative-camera/declarative-camera.qmlproject18
-rw-r--r--examples/multimediawidgets/declarative-camera/doc/images/qml-camera.pngbin0 -> 28409 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/doc/src/declarative-camera.qdoc69
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_auto_mode.pngbin0 -> 778 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_camera_setting.pngbin0 -> 717 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_flash_auto.pngbin0 -> 1119 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_flash_fill.pngbin0 -> 610 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_flash_off.pngbin0 -> 717 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_flash_redeye.pngbin0 -> 945 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_white_balance_cloudy.pngbin0 -> 625 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_white_balance_flourescent.pngbin0 -> 554 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_white_balance_incandescent.pngbin0 -> 600 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/camera_white_balance_sunny.pngbin0 -> 587 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/toolbutton.pngbin0 -> 2550 bytes
-rw-r--r--examples/multimediawidgets/declarative-camera/images/toolbutton.sci5
-rw-r--r--examples/multimediawidgets/declarative-camera/qmlcamera.cpp58
-rw-r--r--examples/multimediawidgets/multimediawidgets.pro18
-rw-r--r--examples/multimediawidgets/player/doc/src/player.qdoc96
-rw-r--r--examples/multimediawidgets/player/histogramwidget.cpp154
-rw-r--r--examples/multimediawidgets/player/histogramwidget.h83
-rw-r--r--examples/multimediawidgets/player/main.cpp62
-rw-r--r--examples/multimediawidgets/player/player.cpp428
-rw-r--r--examples/multimediawidgets/player/player.h127
-rw-r--r--examples/multimediawidgets/player/player.pro28
-rw-r--r--examples/multimediawidgets/player/playercontrols.cpp205
-rw-r--r--examples/multimediawidgets/player/playercontrols.h98
-rw-r--r--examples/multimediawidgets/player/playlistmodel.cpp156
-rw-r--r--examples/multimediawidgets/player/playlistmodel.h88
-rw-r--r--examples/multimediawidgets/player/videowidget.cpp81
-rw-r--r--examples/multimediawidgets/player/videowidget.h59
-rw-r--r--examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.pngbin0 -> 54436 bytes
-rw-r--r--examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc40
-rw-r--r--examples/multimediawidgets/videographicsitem/main.cpp54
-rw-r--r--examples/multimediawidgets/videographicsitem/videographicsitem.pro14
-rw-r--r--examples/multimediawidgets/videographicsitem/videoplayer.cpp167
-rw-r--r--examples/multimediawidgets/videographicsitem/videoplayer.h83
-rw-r--r--examples/multimediawidgets/videowidget/doc/images/video-videowidget.pngbin0 -> 54199 bytes
-rw-r--r--examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc38
-rw-r--r--examples/multimediawidgets/videowidget/main.cpp54
-rw-r--r--examples/multimediawidgets/videowidget/videoplayer.cpp142
-rw-r--r--examples/multimediawidgets/videowidget/videoplayer.h77
-rw-r--r--examples/multimediawidgets/videowidget/videowidget.pro16
81 files changed, 6886 insertions, 0 deletions
diff --git a/examples/multimediawidgets/camera/camera.cpp b/examples/multimediawidgets/camera/camera.cpp
new file mode 100644
index 000000000..c270d5585
--- /dev/null
+++ b/examples/multimediawidgets/camera/camera.cpp
@@ -0,0 +1,435 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "camera.h"
+#include "ui_camera.h"
+#include "videosettings.h"
+#include "imagesettings.h"
+
+#include <QMediaService>
+#include <QMediaRecorder>
+#include <QCameraViewfinder>
+
+#include <QMessageBox>
+#include <QPalette>
+
+#include <QtWidgets>
+
+#if (defined(Q_WS_MAEMO_6)) && QT_VERSION >= 0x040700
+#define HAVE_CAMERA_BUTTONS
+#endif
+
+Camera::Camera(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::Camera),
+ camera(0),
+ imageCapture(0),
+ mediaRecorder(0),
+ isCapturingImage(false),
+ applicationExiting(false)
+{
+ ui->setupUi(this);
+
+ //Camera devices:
+ QByteArray cameraDevice;
+
+ QActionGroup *videoDevicesGroup = new QActionGroup(this);
+ videoDevicesGroup->setExclusive(true);
+ foreach(const QByteArray &deviceName, QCamera::availableDevices()) {
+ QString description = camera->deviceDescription(deviceName);
+ QAction *videoDeviceAction = new QAction(description, videoDevicesGroup);
+ videoDeviceAction->setCheckable(true);
+ videoDeviceAction->setData(QVariant(deviceName));
+ if (cameraDevice.isEmpty()) {
+ cameraDevice = deviceName;
+ videoDeviceAction->setChecked(true);
+ }
+ ui->menuDevices->addAction(videoDeviceAction);
+ }
+
+ connect(videoDevicesGroup, SIGNAL(triggered(QAction*)), SLOT(updateCameraDevice(QAction*)));
+ connect(ui->captureWidget, SIGNAL(currentChanged(int)), SLOT(updateCaptureMode()));
+
+#ifdef HAVE_CAMERA_BUTTONS
+ ui->lockButton->hide();
+#endif
+
+ setCamera(cameraDevice);
+}
+
+Camera::~Camera()
+{
+ delete mediaRecorder;
+ delete imageCapture;
+ delete camera;
+}
+
+void Camera::setCamera(const QByteArray &cameraDevice)
+{
+ delete imageCapture;
+ delete mediaRecorder;
+ delete camera;
+
+ if (cameraDevice.isEmpty())
+ camera = new QCamera;
+ else
+ camera = new QCamera(cameraDevice);
+
+ connect(camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(updateCameraState(QCamera::State)));
+ connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(displayCameraError()));
+
+ mediaRecorder = new QMediaRecorder(camera);
+ connect(mediaRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(updateRecorderState(QMediaRecorder::State)));
+
+ imageCapture = new QCameraImageCapture(camera);
+
+ connect(mediaRecorder, SIGNAL(durationChanged(qint64)), this, SLOT(updateRecordTime()));
+ connect(mediaRecorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayRecorderError()));
+
+ mediaRecorder->setMetaData(QMediaMetaData::Title, QVariant(QLatin1String("Test Title")));
+
+ connect(ui->exposureCompensation, SIGNAL(valueChanged(int)), SLOT(setExposureCompensation(int)));
+
+ camera->setViewfinder(ui->viewfinder);
+
+ updateCameraState(camera->state());
+ updateLockStatus(camera->lockStatus(), QCamera::UserRequest);
+ updateRecorderState(mediaRecorder->state());
+
+ connect(imageCapture, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(readyForCapture(bool)));
+ connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(processCapturedImage(int,QImage)));
+ connect(imageCapture, SIGNAL(imageSaved(int,QString)), this, SLOT(imageSaved(int,QString)));
+
+ connect(camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(updateLockStatus(QCamera::LockStatus, QCamera::LockChangeReason)));
+
+ ui->captureWidget->setTabEnabled(0, (camera->isCaptureModeSupported(QCamera::CaptureStillImage)));
+ ui->captureWidget->setTabEnabled(1, (camera->isCaptureModeSupported(QCamera::CaptureVideo)));
+
+ updateCaptureMode();
+ camera->start();
+}
+
+void Camera::keyPressEvent(QKeyEvent * event)
+{
+ if (event->isAutoRepeat())
+ return;
+
+ switch (event->key()) {
+ case Qt::Key_CameraFocus:
+ displayViewfinder();
+ camera->searchAndLock();
+ event->accept();
+ break;
+ case Qt::Key_Camera:
+ if (camera->captureMode() == QCamera::CaptureStillImage) {
+ takeImage();
+ } else {
+ if (mediaRecorder->state() == QMediaRecorder::RecordingState)
+ stop();
+ else
+ record();
+ }
+ event->accept();
+ break;
+ default:
+ QMainWindow::keyPressEvent(event);
+ }
+}
+
+void Camera::keyReleaseEvent(QKeyEvent *event)
+{
+ if (event->isAutoRepeat())
+ return;
+
+ switch (event->key()) {
+ case Qt::Key_CameraFocus:
+ camera->unlock();
+ break;
+ default:
+ QMainWindow::keyReleaseEvent(event);
+ }
+}
+
+void Camera::updateRecordTime()
+{
+ QString str = QString("Recorded %1 sec").arg(mediaRecorder->duration()/1000);
+ ui->statusbar->showMessage(str);
+}
+
+void Camera::processCapturedImage(int requestId, const QImage& img)
+{
+ Q_UNUSED(requestId);
+ QImage scaledImage = img.scaled(ui->viewfinder->size(),
+ Qt::KeepAspectRatio,
+ Qt::SmoothTransformation);
+
+ ui->lastImagePreviewLabel->setPixmap(QPixmap::fromImage(scaledImage));
+
+ // Display captured image for 4 seconds.
+ displayCapturedImage();
+ QTimer::singleShot(4000, this, SLOT(displayViewfinder()));
+}
+
+void Camera::configureCaptureSettings()
+{
+ switch (camera->captureMode()) {
+ case QCamera::CaptureStillImage:
+ configureImageSettings();
+ break;
+ case QCamera::CaptureVideo:
+ configureVideoSettings();
+ break;
+ default:
+ break;
+ }
+}
+
+void Camera::configureVideoSettings()
+{
+ VideoSettings settingsDialog(mediaRecorder);
+
+ settingsDialog.setAudioSettings(audioSettings);
+ settingsDialog.setVideoSettings(videoSettings);
+ settingsDialog.setFormat(videoContainerFormat);
+
+ if (settingsDialog.exec()) {
+ audioSettings = settingsDialog.audioSettings();
+ videoSettings = settingsDialog.videoSettings();
+ videoContainerFormat = settingsDialog.format();
+
+ mediaRecorder->setEncodingSettings(
+ audioSettings,
+ videoSettings,
+ videoContainerFormat);
+ }
+}
+
+void Camera::configureImageSettings()
+{
+ ImageSettings settingsDialog(imageCapture);
+
+ settingsDialog.setImageSettings(imageSettings);
+
+ if (settingsDialog.exec()) {
+ imageSettings = settingsDialog.imageSettings();
+ imageCapture->setEncodingSettings(imageSettings);
+ }
+}
+
+void Camera::record()
+{
+ mediaRecorder->record();
+ updateRecordTime();
+}
+
+void Camera::pause()
+{
+ mediaRecorder->pause();
+}
+
+void Camera::stop()
+{
+ mediaRecorder->stop();
+}
+
+void Camera::setMuted(bool muted)
+{
+ mediaRecorder->setMuted(muted);
+}
+
+void Camera::toggleLock()
+{
+ switch (camera->lockStatus()) {
+ case QCamera::Searching:
+ case QCamera::Locked:
+ camera->unlock();
+ break;
+ case QCamera::Unlocked:
+ camera->searchAndLock();
+ }
+}
+
+void Camera::updateLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason)
+{
+ QColor indicationColor = Qt::black;
+
+ switch (status) {
+ case QCamera::Searching:
+ indicationColor = Qt::yellow;
+ ui->statusbar->showMessage(tr("Focusing..."));
+ ui->lockButton->setText(tr("Focusing..."));
+ break;
+ case QCamera::Locked:
+ indicationColor = Qt::darkGreen;
+ ui->lockButton->setText(tr("Unlock"));
+ ui->statusbar->showMessage(tr("Focused"), 2000);
+ break;
+ case QCamera::Unlocked:
+ indicationColor = reason == QCamera::LockFailed ? Qt::red : Qt::black;
+ ui->lockButton->setText(tr("Focus"));
+ if (reason == QCamera::LockFailed)
+ ui->statusbar->showMessage(tr("Focus Failed"), 2000);
+ }
+
+ QPalette palette = ui->lockButton->palette();
+ palette.setColor(QPalette::ButtonText, indicationColor);
+ ui->lockButton->setPalette(palette);
+}
+
+void Camera::takeImage()
+{
+ isCapturingImage = true;
+ imageCapture->capture();
+}
+
+void Camera::startCamera()
+{
+ camera->start();
+}
+
+void Camera::stopCamera()
+{
+ camera->stop();
+}
+
+void Camera::updateCaptureMode()
+{
+ int tabIndex = ui->captureWidget->currentIndex();
+ QCamera::CaptureModes captureMode = tabIndex == 0 ? QCamera::CaptureStillImage : QCamera::CaptureVideo;
+
+ if (camera->isCaptureModeSupported(captureMode))
+ camera->setCaptureMode(captureMode);
+}
+
+void Camera::updateCameraState(QCamera::State state)
+{
+ switch (state) {
+ case QCamera::ActiveState:
+ ui->actionStartCamera->setEnabled(false);
+ ui->actionStopCamera->setEnabled(true);
+ ui->captureWidget->setEnabled(true);
+ ui->actionSettings->setEnabled(true);
+ break;
+ case QCamera::UnloadedState:
+ case QCamera::LoadedState:
+ ui->actionStartCamera->setEnabled(true);
+ ui->actionStopCamera->setEnabled(false);
+ ui->captureWidget->setEnabled(false);
+ ui->actionSettings->setEnabled(false);
+ }
+}
+
+void Camera::updateRecorderState(QMediaRecorder::State state)
+{
+ switch (state) {
+ case QMediaRecorder::StoppedState:
+ ui->recordButton->setEnabled(true);
+ ui->pauseButton->setEnabled(true);
+ ui->stopButton->setEnabled(false);
+ break;
+ case QMediaRecorder::PausedState:
+ ui->recordButton->setEnabled(true);
+ ui->pauseButton->setEnabled(false);
+ ui->stopButton->setEnabled(true);
+ break;
+ case QMediaRecorder::RecordingState:
+ ui->recordButton->setEnabled(false);
+ ui->pauseButton->setEnabled(true);
+ ui->stopButton->setEnabled(true);
+ break;
+ }
+}
+
+void Camera::setExposureCompensation(int index)
+{
+ camera->exposure()->setExposureCompensation(index*0.5);
+}
+
+void Camera::displayRecorderError()
+{
+ QMessageBox::warning(this, tr("Capture error"), mediaRecorder->errorString());
+}
+
+void Camera::displayCameraError()
+{
+ QMessageBox::warning(this, tr("Camera error"), camera->errorString());
+}
+
+void Camera::updateCameraDevice(QAction *action)
+{
+ setCamera(action->data().toByteArray());
+}
+
+void Camera::displayViewfinder()
+{
+ ui->stackedWidget->setCurrentIndex(0);
+}
+
+void Camera::displayCapturedImage()
+{
+ ui->stackedWidget->setCurrentIndex(1);
+}
+
+void Camera::readyForCapture(bool ready)
+{
+ ui->takeImageButton->setEnabled(ready);
+}
+
+void Camera::imageSaved(int id, const QString &fileName)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(fileName);
+
+ isCapturingImage = false;
+ if (applicationExiting)
+ close();
+}
+
+void Camera::closeEvent(QCloseEvent *event)
+{
+ if (isCapturingImage) {
+ setEnabled(false);
+ applicationExiting = true;
+ event->ignore();
+ } else {
+ event->accept();
+ }
+}
diff --git a/examples/multimediawidgets/camera/camera.h b/examples/multimediawidgets/camera/camera.h
new file mode 100644
index 000000000..299483f67
--- /dev/null
+++ b/examples/multimediawidgets/camera/camera.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 CAMERA_H
+#define CAMERA_H
+
+#include <QCamera>
+#include <QCameraImageCapture>
+#include <QMediaRecorder>
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class Camera; }
+QT_END_NAMESPACE
+
+class Camera : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ Camera(QWidget *parent = 0);
+ ~Camera();
+
+private slots:
+ void setCamera(const QByteArray &cameraDevice);
+
+ void startCamera();
+ void stopCamera();
+
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool);
+
+ void toggleLock();
+ void takeImage();
+
+ void configureCaptureSettings();
+ void configureVideoSettings();
+ void configureImageSettings();
+
+ void displayRecorderError();
+ void displayCameraError();
+
+ void updateCameraDevice(QAction *action);
+
+ void updateCameraState(QCamera::State);
+ void updateCaptureMode();
+ void updateRecorderState(QMediaRecorder::State state);
+ void setExposureCompensation(int index);
+
+ void updateRecordTime();
+
+ void processCapturedImage(int requestId, const QImage &img);
+ void updateLockStatus(QCamera::LockStatus, QCamera::LockChangeReason);
+
+ void displayViewfinder();
+ void displayCapturedImage();
+
+ void readyForCapture(bool ready);
+ void imageSaved(int id, const QString &fileName);
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+ void closeEvent(QCloseEvent *event);
+
+private:
+ Ui::Camera *ui;
+
+ QCamera *camera;
+ QCameraImageCapture *imageCapture;
+ QMediaRecorder* mediaRecorder;
+
+ QImageEncoderSettings imageSettings;
+ QAudioEncoderSettings audioSettings;
+ QVideoEncoderSettings videoSettings;
+ QString videoContainerFormat;
+ bool isCapturingImage;
+ bool applicationExiting;
+};
+
+#endif
diff --git a/examples/multimediawidgets/camera/camera.pro b/examples/multimediawidgets/camera/camera.pro
new file mode 100644
index 000000000..fe8f39385
--- /dev/null
+++ b/examples/multimediawidgets/camera/camera.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+TARGET = camera
+
+QT += multimedia multimediawidgets
+
+HEADERS = \
+ camera.h \
+ imagesettings.h \
+ videosettings.h
+
+SOURCES = \
+ main.cpp \
+ camera.cpp \
+ imagesettings.cpp \
+ videosettings.cpp
+
+FORMS += \
+ camera.ui \
+ videosettings.ui \
+ imagesettings.ui
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/camera
+INSTALLS += target
+
+QT+=widgets
diff --git a/examples/multimediawidgets/camera/camera.ui b/examples/multimediawidgets/camera/camera.ui
new file mode 100644
index 000000000..ea790fab0
--- /dev/null
+++ b/examples/multimediawidgets/camera/camera.ui
@@ -0,0 +1,492 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Camera</class>
+ <widget class="QMainWindow" name="Camera">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>668</width>
+ <height>422</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Camera</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0" rowspan="3">
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>145</red>
+ <green>145</green>
+ <blue>145</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>145</red>
+ <green>145</green>
+ <blue>145</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>145</red>
+ <green>145</green>
+ <blue>145</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>145</red>
+ <green>145</green>
+ <blue>145</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="viewfinderPage">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QCameraViewfinder" name="viewfinder" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="previewPage">
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="lastImagePreviewLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QPushButton" name="lockButton">
+ <property name="text">
+ <string>Focus</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QTabWidget" name="captureWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Image</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="takeImageButton">
+ <property name="text">
+ <string>Capture Photo</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>161</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Exposure Compensation:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QSlider" name="exposureCompensation">
+ <property name="minimum">
+ <number>-4</number>
+ </property>
+ <property name="maximum">
+ <number>4</number>
+ </property>
+ <property name="pageStep">
+ <number>2</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Video</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="recordButton">
+ <property name="text">
+ <string>Record</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="pauseButton">
+ <property name="text">
+ <string>Pause</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="stopButton">
+ <property name="text">
+ <string>Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>76</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="0">
+ <widget class="QPushButton" name="muteButton">
+ <property name="text">
+ <string>Mute</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>668</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="actionStartCamera"/>
+ <addaction name="actionStopCamera"/>
+ <addaction name="separator"/>
+ <addaction name="actionSettings"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <widget class="QMenu" name="menuDevices">
+ <property name="title">
+ <string>Devices</string>
+ </property>
+ </widget>
+ <addaction name="menuFile"/>
+ <addaction name="menuDevices"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionExit">
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </action>
+ <action name="actionStartCamera">
+ <property name="text">
+ <string>Start Camera</string>
+ </property>
+ </action>
+ <action name="actionStopCamera">
+ <property name="text">
+ <string>Stop Camera</string>
+ </property>
+ </action>
+ <action name="actionSettings">
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCameraViewfinder</class>
+ <extends>QWidget</extends>
+ <header>qcameraviewfinder.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>recordButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Camera</receiver>
+ <slot>record()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>647</x>
+ <y>149</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>61</x>
+ <y>238</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>stopButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Camera</receiver>
+ <slot>stop()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>647</x>
+ <y>225</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>140</x>
+ <y>236</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pauseButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Camera</receiver>
+ <slot>pause()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>647</x>
+ <y>187</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>234</x>
+ <y>237</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>actionExit</sender>
+ <signal>triggered()</signal>
+ <receiver>Camera</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>154</x>
+ <y>130</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>takeImageButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Camera</receiver>
+ <slot>takeImage()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>625</x>
+ <y>132</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>603</x>
+ <y>169</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>lockButton</sender>
+ <signal>clicked()</signal>
+ <receiver>Camera</receiver>
+ <slot>toggleLock()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>658</x>
+ <y>75</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>453</x>
+ <y>119</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>muteButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>Camera</receiver>
+ <slot>setMuted(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>647</x>
+ <y>377</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>5</x>
+ <y>280</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>exposureCompensation</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>Camera</receiver>
+ <slot>setExposureCompensation(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>559</x>
+ <y>367</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>665</x>
+ <y>365</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>actionSettings</sender>
+ <signal>triggered()</signal>
+ <receiver>Camera</receiver>
+ <slot>configureCaptureSettings()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>333</x>
+ <y>210</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>actionStartCamera</sender>
+ <signal>triggered()</signal>
+ <receiver>Camera</receiver>
+ <slot>startCamera()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>333</x>
+ <y>210</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>actionStopCamera</sender>
+ <signal>triggered()</signal>
+ <receiver>Camera</receiver>
+ <slot>stopCamera()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>333</x>
+ <y>210</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>record()</slot>
+ <slot>pause()</slot>
+ <slot>stop()</slot>
+ <slot>enablePreview(bool)</slot>
+ <slot>configureCaptureSettings()</slot>
+ <slot>takeImage()</slot>
+ <slot>startCamera()</slot>
+ <slot>toggleLock()</slot>
+ <slot>setMuted(bool)</slot>
+ <slot>stopCamera()</slot>
+ <slot>setExposureCompensation(int)</slot>
+ </slots>
+</ui>
diff --git a/examples/multimediawidgets/camera/doc/images/camera-example.png b/examples/multimediawidgets/camera/doc/images/camera-example.png
new file mode 100644
index 000000000..12e1b5728
--- /dev/null
+++ b/examples/multimediawidgets/camera/doc/images/camera-example.png
Binary files differ
diff --git a/examples/multimediawidgets/camera/doc/src/camera.qdoc b/examples/multimediawidgets/camera/doc/src/camera.qdoc
new file mode 100644
index 000000000..c40c25135
--- /dev/null
+++ b/examples/multimediawidgets/camera/doc/src/camera.qdoc
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+/*!
+
+\example camera
+\title Camera Example
+\ingroup camera_examples
+\brief The Camera Example shows how to use the API to capture a still image
+or video.
+
+
+
+The Camera Example demonstrates how you can use QtMultimedia to implement
+some basic Camera functionality to take still images and record video clips
+with audio.
+
+A Camera class is created that will act as our Camera. It has a user interface,
+control functions, setting values and a means of defining the location where
+the image or video clip is to be saved. It will also store the image and video
+settings.
+
+The Camera class contains an instance of \l {QCamera}, the API class interface to
+the hardware. It also has an instance of \l {QCameraImageCapture} to take still images
+and an instance of \l {QMediaRecorder} to record video. It also contains the user
+interface object.
+
+The Camera constructor does some basic initialization. The camera object is
+set to '0', the user interface is initialized and UI signal are connected to
+slots that react to the triggering event. However, most of the work is done when
+the \e{setCamera()} function is called, passing in a \l {QByteArray}.
+
+\e{setCamera()} sets up various connections between the user interface and the functionality
+of the Camera class using signals and slots. It also instantiates and initializes the \l {QCamera},
+\l {QCameraImageCapture} and \l {QMediaRecorder} objects mentioned above. The still
+and video recording visual tabs are enabled and finally the
+\l {QCamera::start()}{start()} function of the \l{QCamera} object is called.
+
+Now that the camera is ready for user commands it waits for a suitable event.
+Such an event will be the key press of either the \l {Qt::Key_CameraFocus} or
+\l {Qt::Key_Camera} buttons on the application window. Camera focus will
+simply display the viewfinder and lock the camera settings. Key_Camera will
+either call \e{takeImage()} if the \l {QCamera::captureMode()}{captureMode()}
+is QCamera::CaptureStillImage, or if the capture mode is for video then one
+of two actions will occur. If the recording state shows that we are currently
+recording then the \e{stop()} function is called resulting in a call to
+\l {QCamera::stop()}, whereas if we are not recording then a video recording
+is started with a call to \l {QMediaRecorder::record()}.
+
+\image camera-example.png
+
+*/
+
+
diff --git a/examples/multimediawidgets/camera/imagesettings.cpp b/examples/multimediawidgets/camera/imagesettings.cpp
new file mode 100644
index 000000000..566a1260b
--- /dev/null
+++ b/examples/multimediawidgets/camera/imagesettings.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "imagesettings.h"
+#include "ui_imagesettings.h"
+
+#include <QComboBox>
+#include <QDebug>
+#include <QCameraImageCapture>
+#include <QMediaService>
+
+
+ImageSettings::ImageSettings(QCameraImageCapture *imageCapture, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ImageSettingsUi),
+ imagecapture(imageCapture)
+{
+ ui->setupUi(this);
+
+ //image codecs
+ ui->imageCodecBox->addItem(tr("Default image format"), QVariant(QString()));
+ foreach(const QString &codecName, imagecapture->supportedImageCodecs()) {
+ QString description = imagecapture->imageCodecDescription(codecName);
+ ui->imageCodecBox->addItem(codecName+": "+description, QVariant(codecName));
+ }
+
+ ui->imageQualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
+
+ ui->imageResolutionBox->addItem(tr("Default Resolution"));
+ QList<QSize> supportedResolutions = imagecapture->supportedResolutions();
+ foreach(const QSize &resolution, supportedResolutions) {
+ ui->imageResolutionBox->addItem(QString("%1x%2").arg(resolution.width()).arg(resolution.height()),
+ QVariant(resolution));
+ }
+}
+
+ImageSettings::~ImageSettings()
+{
+ delete ui;
+}
+
+void ImageSettings::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+QImageEncoderSettings ImageSettings::imageSettings() const
+{
+ QImageEncoderSettings settings = imagecapture->encodingSettings();
+ settings.setCodec(boxValue(ui->imageCodecBox).toString());
+ settings.setQuality(QMultimedia::EncodingQuality(ui->imageQualitySlider->value()));
+ settings.setResolution(boxValue(ui->imageResolutionBox).toSize());
+
+ return settings;
+}
+
+void ImageSettings::setImageSettings(const QImageEncoderSettings &imageSettings)
+{
+ selectComboBoxItem(ui->imageCodecBox, QVariant(imageSettings.codec()));
+ selectComboBoxItem(ui->imageResolutionBox, QVariant(imageSettings.resolution()));
+ ui->imageQualitySlider->setValue(imageSettings.quality());
+}
+
+QVariant ImageSettings::boxValue(const QComboBox *box) const
+{
+ int idx = box->currentIndex();
+ if (idx == -1)
+ return QVariant();
+
+ return box->itemData(idx);
+}
+
+void ImageSettings::selectComboBoxItem(QComboBox *box, const QVariant &value)
+{
+ for (int i = 0; i < box->count(); ++i) {
+ if (box->itemData(i) == value) {
+ box->setCurrentIndex(i);
+ break;
+ }
+ }
+}
diff --git a/examples/multimediawidgets/camera/imagesettings.h b/examples/multimediawidgets/camera/imagesettings.h
new file mode 100644
index 000000000..5c3e69461
--- /dev/null
+++ b/examples/multimediawidgets/camera/imagesettings.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 IMAGESETTINGS_H
+#define IMAGESETTINGS_H
+
+#include <QDialog>
+#include <QAudioEncoderSettings>
+#include <QVideoEncoderSettings>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QCameraImageCapture;
+namespace Ui { class ImageSettingsUi; }
+QT_END_NAMESPACE
+
+class ImageSettings : public QDialog
+{
+ Q_OBJECT
+
+public:
+ ImageSettings(QCameraImageCapture *imageCapture, QWidget *parent = 0);
+ ~ImageSettings();
+
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings &settings);
+
+ QImageEncoderSettings imageSettings() const;
+ void setImageSettings(const QImageEncoderSettings &settings);
+
+ QString format() const;
+ void setFormat(const QString &format);
+
+protected:
+ void changeEvent(QEvent *e);
+
+private:
+ QVariant boxValue(const QComboBox *box) const;
+ void selectComboBoxItem(QComboBox *box, const QVariant &value);
+
+ Ui::ImageSettingsUi *ui;
+ QCameraImageCapture *imagecapture;
+};
+
+#endif // IMAGESETTINGS_H
diff --git a/examples/multimediawidgets/camera/imagesettings.ui b/examples/multimediawidgets/camera/imagesettings.ui
new file mode 100644
index 000000000..f790c770d
--- /dev/null
+++ b/examples/multimediawidgets/camera/imagesettings.ui
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ImageSettingsUi</class>
+ <widget class="QDialog" name="ImageSettingsUi">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>332</width>
+ <height>270</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Image</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Resolution:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="imageResolutionBox"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Image Format:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QComboBox" name="imageCodecBox"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Quality:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSlider" name="imageQualitySlider">
+ <property name="maximum">
+ <number>4</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>14</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ImageSettingsUi</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>322</x>
+ <y>272</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>44</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ImageSettingsUi</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>405</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>364</x>
+ <y>227</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/multimediawidgets/camera/main.cpp b/examples/multimediawidgets/camera/main.cpp
new file mode 100644
index 000000000..aa5fbdb84
--- /dev/null
+++ b/examples/multimediawidgets/camera/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "camera.h"
+
+#include <QtWidgets>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ Camera camera;
+ camera.show();
+
+ return app.exec();
+};
diff --git a/examples/multimediawidgets/camera/videosettings.cpp b/examples/multimediawidgets/camera/videosettings.cpp
new file mode 100644
index 000000000..2ec880801
--- /dev/null
+++ b/examples/multimediawidgets/camera/videosettings.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videosettings.h"
+#include "ui_videosettings.h"
+
+#include <QComboBox>
+#include <QDebug>
+#include <QMediaRecorder>
+#include <QMediaService>
+
+
+VideoSettings::VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::VideoSettingsUi),
+ mediaRecorder(mediaRecorder)
+{
+ ui->setupUi(this);
+
+ //audio codecs
+ ui->audioCodecBox->addItem(tr("Default audio codec"), QVariant(QString()));
+ foreach (const QString &codecName, mediaRecorder->supportedAudioCodecs()) {
+ QString description = mediaRecorder->audioCodecDescription(codecName);
+ ui->audioCodecBox->addItem(codecName+": "+description, QVariant(codecName));
+ }
+
+ //sample rate:
+ foreach (int sampleRate, mediaRecorder->supportedAudioSampleRates()) {
+ ui->audioSampleRateBox->addItem(QString::number(sampleRate), QVariant(sampleRate));
+ }
+
+ ui->audioQualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
+
+ //video codecs
+ ui->videoCodecBox->addItem(tr("Default video codec"), QVariant(QString()));
+ foreach (const QString &codecName, mediaRecorder->supportedVideoCodecs()) {
+ QString description = mediaRecorder->videoCodecDescription(codecName);
+ ui->videoCodecBox->addItem(codecName+": "+description, QVariant(codecName));
+ }
+
+ ui->videoQualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
+
+
+ ui->videoResolutionBox->addItem(tr("Default"));
+ QList<QSize> supportedResolutions = mediaRecorder->supportedResolutions();
+ foreach (const QSize &resolution, supportedResolutions) {
+ ui->videoResolutionBox->addItem(QString("%1x%2").arg(resolution.width()).arg(resolution.height()),
+ QVariant(resolution));
+ }
+
+ ui->videoFramerateBox->addItem(tr("Default"));
+ QList<qreal> supportedFrameRates = mediaRecorder->supportedFrameRates();
+ qreal rate;
+ foreach (rate, supportedFrameRates) {
+ QString rateString = QString("%1").arg(rate, 0, 'f', 2);
+ ui->videoFramerateBox->addItem(rateString, QVariant(rate));
+ }
+
+ //containers
+ ui->containerFormatBox->addItem(tr("Default container"), QVariant(QString()));
+ foreach (const QString &format, mediaRecorder->supportedContainers()) {
+ ui->containerFormatBox->addItem(format+":"+mediaRecorder->containerDescription(format),
+ QVariant(format));
+ }
+}
+
+VideoSettings::~VideoSettings()
+{
+ delete ui;
+}
+
+void VideoSettings::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+QAudioEncoderSettings VideoSettings::audioSettings() const
+{
+ QAudioEncoderSettings settings = mediaRecorder->audioSettings();
+ settings.setCodec(boxValue(ui->audioCodecBox).toString());
+ settings.setQuality(QMultimedia::EncodingQuality(ui->audioQualitySlider->value()));
+ settings.setSampleRate(boxValue(ui->audioSampleRateBox).toInt());
+ return settings;
+}
+
+void VideoSettings::setAudioSettings(const QAudioEncoderSettings &audioSettings)
+{
+ selectComboBoxItem(ui->audioCodecBox, QVariant(audioSettings.codec()));
+ selectComboBoxItem(ui->audioSampleRateBox, QVariant(audioSettings.sampleRate()));
+ ui->audioQualitySlider->setValue(audioSettings.quality());
+}
+
+QVideoEncoderSettings VideoSettings::videoSettings() const
+{
+ QVideoEncoderSettings settings = mediaRecorder->videoSettings();
+ settings.setCodec(boxValue(ui->videoCodecBox).toString());
+ settings.setQuality(QMultimedia::EncodingQuality(ui->videoQualitySlider->value()));
+ settings.setResolution(boxValue(ui->videoResolutionBox).toSize());
+ settings.setFrameRate(boxValue(ui->videoFramerateBox).value<qreal>());
+
+ return settings;
+}
+
+void VideoSettings::setVideoSettings(const QVideoEncoderSettings &videoSettings)
+{
+ selectComboBoxItem(ui->videoCodecBox, QVariant(videoSettings.codec()));
+ selectComboBoxItem(ui->videoResolutionBox, QVariant(videoSettings.resolution()));
+ ui->videoQualitySlider->setValue(videoSettings.quality());
+
+ //special case for frame rate
+ for (int i = 0; i < ui->videoFramerateBox->count(); ++i) {
+ qreal itemRate = ui->videoFramerateBox->itemData(i).value<qreal>();
+ if (qFuzzyCompare(itemRate, videoSettings.frameRate())) {
+ ui->videoFramerateBox->setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
+QString VideoSettings::format() const
+{
+ return boxValue(ui->containerFormatBox).toString();
+}
+
+void VideoSettings::setFormat(const QString &format)
+{
+ selectComboBoxItem(ui->containerFormatBox, QVariant(format));
+}
+
+QVariant VideoSettings::boxValue(const QComboBox *box) const
+{
+ int idx = box->currentIndex();
+ if (idx == -1)
+ return QVariant();
+
+ return box->itemData(idx);
+}
+
+void VideoSettings::selectComboBoxItem(QComboBox *box, const QVariant &value)
+{
+ for (int i = 0; i < box->count(); ++i) {
+ if (box->itemData(i) == value) {
+ box->setCurrentIndex(i);
+ break;
+ }
+ }
+}
diff --git a/examples/multimediawidgets/camera/videosettings.h b/examples/multimediawidgets/camera/videosettings.h
new file mode 100644
index 000000000..32b519064
--- /dev/null
+++ b/examples/multimediawidgets/camera/videosettings.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 VIDEOSETTINGS_H
+#define VIDEOSETTINGS_H
+
+#include <QDialog>
+#include <QAudioEncoderSettings>
+#include <QVideoEncoderSettings>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QMediaRecorder;
+namespace Ui { class VideoSettingsUi; }
+QT_END_NAMESPACE
+
+class VideoSettings : public QDialog
+{
+ Q_OBJECT
+
+public:
+ VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent = 0);
+ ~VideoSettings();
+
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings&);
+
+ QVideoEncoderSettings videoSettings() const;
+ void setVideoSettings(const QVideoEncoderSettings&);
+
+ QString format() const;
+ void setFormat(const QString &format);
+
+protected:
+ void changeEvent(QEvent *e);
+
+private:
+ QVariant boxValue(const QComboBox*) const;
+ void selectComboBoxItem(QComboBox *box, const QVariant &value);
+
+ Ui::VideoSettingsUi *ui;
+ QMediaRecorder *mediaRecorder;
+};
+
+#endif // VIDEOSETTINGS_H
diff --git a/examples/multimediawidgets/camera/videosettings.ui b/examples/multimediawidgets/camera/videosettings.ui
new file mode 100644
index 000000000..f6aa004c5
--- /dev/null
+++ b/examples/multimediawidgets/camera/videosettings.ui
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VideoSettingsUi</class>
+ <widget class="QDialog" name="VideoSettingsUi">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>561</width>
+ <height>369</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>543</width>
+ <height>250</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Audio</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Audio Codec:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="audioCodecBox"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Sample Rate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QComboBox" name="audioSampleRateBox"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Quality:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSlider" name="audioQualitySlider">
+ <property name="maximum">
+ <number>4</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" rowspan="3">
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Video</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Resolution:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="videoResolutionBox"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Framerate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QComboBox" name="videoFramerateBox"/>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Video Codec:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <widget class="QComboBox" name="videoCodecBox"/>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Quality:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QSlider" name="videoQualitySlider">
+ <property name="maximum">
+ <number>4</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Container Format:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QComboBox" name="containerFormatBox"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>14</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>VideoSettingsUi</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>322</x>
+ <y>272</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>44</x>
+ <y>230</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>VideoSettingsUi</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>405</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>364</x>
+ <y>227</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/customvideoitem.pro b/examples/multimediawidgets/customvideosurface/customvideoitem/customvideoitem.pro
new file mode 100644
index 000000000..387e494c9
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/customvideoitem.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = customvideoitem
+
+QT += multimedia multimediawidgets widgets
+
+contains(QT_CONFIG, opengl): QT += opengl
+
+HEADERS += videoplayer.h \
+ videoitem.h
+
+SOURCES += main.cpp \
+ videoplayer.cpp \
+ videoitem.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/customvideosurface/customvideoitem
+INSTALLS += target
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/main.cpp b/examples/multimediawidgets/customvideosurface/customvideoitem/main.cpp
new file mode 100644
index 000000000..18f602f88
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ VideoPlayer player;
+ player.show();
+
+ return app.exec();
+}
+
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.cpp b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.cpp
new file mode 100644
index 000000000..db6651efd
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoitem.h"
+
+#include <QPainter>
+#include <QTransform>
+#include <QVideoSurfaceFormat>
+
+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::imageFormatFromPixelFormat(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 (!QAbstractVideoSurface::isActive())
+ setError(StoppedError);
+
+ return false;
+ } else {
+ currentFrame = frame;
+ framePainted = false;
+
+ update();
+
+ return true;
+ }
+}
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h
new file mode 100644
index 000000000..28360577b
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoitem.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 VIDEOITEM_H
+#define VIDEOITEM_H
+
+#include <QAbstractVideoSurface>
+#include <QGraphicsItem>
+
+class VideoItem
+ : public QAbstractVideoSurface,
+ public QGraphicsItem
+{
+ Q_OBJECT
+ Q_INTERFACES(QGraphicsItem)
+
+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 // VIDEOITEM_H
+
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp
new file mode 100644
index 000000000..c76160da3
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+#include "videoitem.h"
+
+#include <QtWidgets>
+#include <QVideoSurfaceFormat>
+
+#if !defined(QT_NO_OPENGL)
+# include <QGLWidget>
+#endif
+
+VideoPlayer::VideoPlayer(QWidget *parent)
+ : QWidget(parent)
+ , mediaPlayer(0, QMediaPlayer::VideoSurface)
+ , videoItem(0)
+ , playButton(0)
+ , positionSlider(0)
+{
+ videoItem = new VideoItem;
+
+ QGraphicsScene *scene = new QGraphicsScene(this);
+ QGraphicsView *graphicsView = new QGraphicsView(scene);
+
+#if !defined(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)));
+
+ 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);
+
+ mediaPlayer.setVideoOutput(videoItem);
+ connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SLOT(mediaStateChanged(QMediaPlayer::State)));
+ connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
+ connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)));
+}
+
+VideoPlayer::~VideoPlayer()
+{
+}
+
+
+void VideoPlayer::openFile()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath());
+
+ if (!fileName.isEmpty()) {
+ mediaPlayer.setMedia(QUrl::fromLocalFile(fileName));
+
+ playButton->setEnabled(true);
+ }
+}
+
+void VideoPlayer::play()
+{
+ switch(mediaPlayer.state()) {
+ case QMediaPlayer::PlayingState:
+ mediaPlayer.pause();
+ break;
+ default:
+ mediaPlayer.play();
+ break;
+ }
+}
+
+void VideoPlayer::mediaStateChanged(QMediaPlayer::State state)
+{
+ switch(state) {
+ case QMediaPlayer::PlayingState:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ break;
+ default:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ }
+}
+
+void VideoPlayer::positionChanged(qint64 position)
+{
+ positionSlider->setValue(position);
+}
+
+void VideoPlayer::durationChanged(qint64 duration)
+{
+ positionSlider->setRange(0, duration);
+}
+
+void VideoPlayer::setPosition(int position)
+{
+ mediaPlayer.setPosition(position);
+}
+
+
+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));
+}
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h
new file mode 100644
index 000000000..5b4db4e4d
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QMediaPlayer>
+#include <QMovie>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+class QSlider;
+QT_END_NAMESPACE
+
+class VideoItem;
+
+class VideoPlayer : public QWidget
+{
+ Q_OBJECT
+
+public:
+ VideoPlayer(QWidget *parent = 0);
+ ~VideoPlayer();
+
+ QSize sizeHint() const { return QSize(800, 600); }
+
+public slots:
+ void openFile();
+ void play();
+
+private slots:
+ void mediaStateChanged(QMediaPlayer::State state);
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void setPosition(int position);
+ void rotateVideo(int angle);
+
+private:
+ QMediaPlayer mediaPlayer;
+ VideoItem *videoItem;
+ QAbstractButton *playButton;
+ QSlider *positionSlider;
+};
+
+#endif // VIDEOPLAYER_H
+
diff --git a/examples/multimediawidgets/customvideosurface/customvideosurface.pro b/examples/multimediawidgets/customvideosurface/customvideosurface.pro
new file mode 100644
index 000000000..baffdaba7
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideosurface.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += customvideoitem customvideowidget
+
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/customvideowidget.pro b/examples/multimediawidgets/customvideosurface/customvideowidget/customvideowidget.pro
new file mode 100644
index 000000000..b4476dfb7
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/customvideowidget.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+TARGET = customvideowidget
+
+QT += multimedia multimediawidgets widgets
+
+HEADERS = \
+ videoplayer.h \
+ videowidget.h \
+ videowidgetsurface.h
+
+SOURCES = \
+ main.cpp \
+ videoplayer.cpp \
+ videowidget.cpp \
+ videowidgetsurface.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/customvideosurface/customvideowidget
+INSTALLS += target
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/main.cpp b/examples/multimediawidgets/customvideosurface/customvideowidget/main.cpp
new file mode 100644
index 000000000..8b7aba641
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ VideoPlayer player;
+ player.show();
+
+ return app.exec();
+}
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp
new file mode 100644
index 000000000..639c32461
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include "videowidget.h"
+
+#include <QtWidgets>
+#include <qvideosurfaceformat.h>
+
+VideoPlayer::VideoPlayer(QWidget *parent)
+ : QWidget(parent)
+ , mediaPlayer(0, QMediaPlayer::VideoSurface)
+ , playButton(0)
+ , positionSlider(0)
+{
+ VideoWidget *videoWidget = new VideoWidget;
+
+ 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)));
+
+ 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);
+
+ mediaPlayer.setVideoOutput(videoWidget->videoSurface());
+ connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SLOT(mediaStateChanged(QMediaPlayer::State)));
+ connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
+ connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)));
+}
+
+VideoPlayer::~VideoPlayer()
+{
+}
+
+void VideoPlayer::openFile()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath());
+
+ if (!fileName.isEmpty()) {
+ mediaPlayer.setMedia(QUrl::fromLocalFile(fileName));
+
+ playButton->setEnabled(true);
+ }
+}
+
+void VideoPlayer::play()
+{
+ switch(mediaPlayer.state()) {
+ case QMediaPlayer::PlayingState:
+ mediaPlayer.pause();
+ break;
+ default:
+ mediaPlayer.play();
+ break;
+ }
+}
+
+void VideoPlayer::mediaStateChanged(QMediaPlayer::State state)
+{
+ switch(state) {
+ case QMediaPlayer::PlayingState:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ break;
+ default:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ }
+}
+
+void VideoPlayer::positionChanged(qint64 position)
+{
+ positionSlider->setValue(position);
+}
+
+void VideoPlayer::durationChanged(qint64 duration)
+{
+ positionSlider->setRange(0, duration);
+}
+
+void VideoPlayer::setPosition(int position)
+{
+ mediaPlayer.setPosition(position);
+}
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.h b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.h
new file mode 100644
index 000000000..7aff44fbb
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QMediaPlayer>
+#include <QMovie>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+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 mediaStateChanged(QMediaPlayer::State state);
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void setPosition(int position);
+
+private:
+ QMediaPlayer mediaPlayer;
+ QAbstractButton *playButton;
+ QSlider *positionSlider;
+};
+
+#endif // VIDEOPLAYER_H
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.cpp b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.cpp
new file mode 100644
index 000000000..38c386e6e
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videowidget.h"
+
+#include "videowidgetsurface.h"
+
+#include <QtWidgets>
+#include <qvideosurfaceformat.h>
+
+//! [0]
+VideoWidget::VideoWidget(QWidget *parent)
+ : QWidget(parent)
+ , surface(0)
+{
+ setAutoFillBackground(false);
+ setAttribute(Qt::WA_NoSystemBackground, 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->isActive()) {
+ const QRect videoRect = surface->videoRect();
+
+ if (!videoRect.contains(event->rect())) {
+ QRegion region = event->region();
+ region = region.subtracted(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/multimediawidgets/customvideosurface/customvideowidget/videowidget.h b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h
new file mode 100644
index 000000000..9b9bd0f38
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidget.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QWidget>
+
+//! [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 // VIDEOWIDGET_H
diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.cpp b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.cpp
new file mode 100644
index 000000000..df157206b
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videowidgetsurface.h"
+
+#include <QtWidgets>
+#include <qabstractvideosurface.h>
+#include <qvideosurfaceformat.h>
+
+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) const
+{
+ const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(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::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;
+ }
+}
+//! [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/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h
new file mode 100644
index 000000000..3e9c40bd2
--- /dev/null
+++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videowidgetsurface.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QAbstractVideoSurface>
+#include <QImage>
+#include <QRect>
+#include <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) 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
diff --git a/examples/multimediawidgets/declarative-camera/CameraButton.qml b/examples/multimediawidgets/declarative-camera/CameraButton.qml
new file mode 100644
index 000000000..b4e399a49
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/CameraButton.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: button
+
+ signal clicked
+
+ property string text
+ property color color: "white"
+
+ width : 144
+ height: 70
+
+ BorderImage {
+ id: buttonImage
+ source: "images/toolbutton.sci"
+ width: button.width; height: button.height
+ }
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: buttonImage
+ onClicked: { button.clicked(); }
+ }
+ Text {
+ id: btnText
+ color: button.color
+ anchors.centerIn: buttonImage; font.bold: true
+ text: button.text; style: Text.Raised; styleColor: "black"
+ font.pixelSize: 14
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/CameraPropertyButton.qml b/examples/multimediawidgets/declarative-camera/CameraPropertyButton.qml
new file mode 100644
index 000000000..75df17c8d
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/CameraPropertyButton.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Item {
+ id: propertyButton
+ property alias value : popup.currentValue
+ property alias model : popup.model
+
+ width : 144
+ height: 70
+
+ BorderImage {
+ id: buttonImage
+ source: "images/toolbutton.sci"
+ width: propertyButton.width; height: propertyButton.height
+ }
+
+ CameraButton {
+ anchors.fill: parent
+ Image {
+ anchors.centerIn: parent
+ source: popup.currentItem.icon
+ }
+
+ onClicked: popup.toggle()
+ }
+
+ CameraPropertyPopup {
+ id: popup
+ anchors.right: parent.left
+ anchors.rightMargin: 16
+ anchors.top: parent.top
+ state: "invisible"
+ visible: opacity > 0
+
+ currentValue: propertyButton.value
+
+ states: [
+ State {
+ name: "invisible"
+ PropertyChanges { target: popup; opacity: 0 }
+ },
+
+ State {
+ name: "visible"
+ PropertyChanges { target: popup; opacity: 1.0 }
+ }
+ ]
+
+ transitions: Transition {
+ NumberAnimation { properties: "opacity"; duration: 100 }
+ }
+
+ function toggle() {
+ if (state == "visible")
+ state = "invisible";
+ else
+ state = "visible";
+ }
+
+ onSelected: {
+ popup.state = "invisible"
+ }
+ }
+}
+
diff --git a/examples/multimediawidgets/declarative-camera/CameraPropertyPopup.qml b/examples/multimediawidgets/declarative-camera/CameraPropertyPopup.qml
new file mode 100644
index 000000000..ae78b7f6a
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/CameraPropertyPopup.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: propertyPopup
+
+ property alias model : view.model
+ property variant currentValue
+ property variant currentItem : model.get(view.currentIndex)
+
+ property int itemWidth : 100
+ property int itemHeight : 70
+ property int columns : 2
+
+ width: columns*itemWidth + view.anchors.margins*2
+ height: Math.ceil(model.count/columns)*itemHeight + view.anchors.margins*2 + 25
+
+ radius: 5
+ border.color: "#000000"
+ border.width: 2
+ smooth: true
+ color: "#5e5e5e"
+
+ signal selected
+
+ function indexForValue(value) {
+ for (var i = 0; i < view.count; i++) {
+ if (model.get(i).value == value) {
+ return i;
+ }
+ }
+
+ return 0;
+ }
+
+ GridView {
+ id: view
+ anchors.fill: parent
+ anchors.margins: 5
+ cellWidth: propertyPopup.itemWidth
+ cellHeight: propertyPopup.itemHeight
+ snapMode: ListView.SnapOneItem
+ highlightFollowsCurrentItem: true
+ highlight: Rectangle { color: "gray"; radius: 5 }
+ currentIndex: indexForValue(propertyPopup.currentValue)
+
+ onCurrentIndexChanged: {
+ propertyPopup.currentValue = model.get(view.currentIndex).value
+ }
+
+ delegate: Item {
+ width: propertyPopup.itemWidth
+ height: 70
+
+ Image {
+ anchors.centerIn: parent
+ source: icon
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ propertyPopup.currentValue = value
+ propertyPopup.selected(value)
+ }
+ }
+ }
+ }
+
+ Text {
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 8
+ anchors.left: parent.left
+ anchors.leftMargin: 16
+
+ color: "#ffffff"
+ font.bold: true
+ style: Text.Raised;
+ styleColor: "black"
+ font.pixelSize: 14
+
+ text: view.model.get(view.currentIndex).text
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/FocusButton.qml b/examples/multimediawidgets/declarative-camera/FocusButton.qml
new file mode 100644
index 000000000..7f588826b
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/FocusButton.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+CameraButton {
+ property Camera camera
+
+ onClicked: {
+ if (camera.lockStatus == Camera.Unlocked)
+ camera.searchAndLock();
+ else
+ camera.unlock();
+ }
+
+ text: {
+ if (camera.lockStatus == Camera.Unlocked)
+ "Focus";
+ else if (camera.lockStatus == Camera.Searching)
+ "Focusing"
+ else
+ "Unlock"
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/PhotoCaptureControls.qml b/examples/multimediawidgets/declarative-camera/PhotoCaptureControls.qml
new file mode 100644
index 000000000..ccd14a084
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/PhotoCaptureControls.qml
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+FocusScope {
+ property Camera camera
+ property bool previewAvailable : false
+
+ property int buttonsPanelWidth: buttonPaneShadow.width
+
+ signal previewSelected
+ signal videoModeSelected
+ id : captureControls
+
+ Rectangle {
+ id: buttonPaneShadow
+ width: buttonsColumn.width + 16
+ height: parent.height
+ anchors.top: parent.top
+ anchors.right: parent.right
+ color: Qt.rgba(0.08, 0.08, 0.08, 1)
+
+ Column {
+ anchors {
+ right: parent.right
+ top: parent.top
+ margins: 8
+ }
+
+ id: buttonsColumn
+ spacing: 8
+
+ FocusButton {
+ camera: captureControls.camera
+ visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
+ }
+
+ CameraButton {
+ text: "Capture"
+ visible: camera.imageCapture.ready
+ onClicked: camera.imageCapture.capture()
+ }
+
+ CameraPropertyButton {
+ id : wbModesButton
+ value: CameraImageProcessing.WhiteBalanceAuto
+ model: ListModel {
+ ListElement {
+ icon: "images/camera_auto_mode.png"
+ value: CameraImageProcessing.WhiteBalanceAuto
+ text: "Auto"
+ }
+ ListElement {
+ icon: "images/camera_white_balance_sunny.png"
+ value: CameraImageProcessing.WhiteBalanceSunlight
+ text: "Sunlight"
+ }
+ ListElement {
+ icon: "images/camera_white_balance_cloudy.png"
+ value: CameraImageProcessing.WhiteBalanceCloudy
+ text: "Cloudy"
+ }
+ ListElement {
+ icon: "images/camera_white_balance_incandescent.png"
+ value: CameraImageProcessing.WhiteBalanceTungsten
+ text: "Tungsten"
+ }
+ ListElement {
+ icon: "images/camera_white_balance_flourescent.png"
+ value: CameraImageProcessing.WhiteBalanceFluorescent
+ text: "Fluorescent"
+ }
+ }
+ }
+
+ CameraButton {
+ text: "View"
+ onClicked: captureControls.previewSelected()
+ visible: captureControls.previewAvailable
+ }
+ }
+
+ Column {
+ anchors {
+ bottom: parent.bottom
+ right: parent.right
+ margins: 8
+ }
+
+ id: bottomColumn
+ spacing: 8
+
+ CameraButton {
+ text: "Switch to Video"
+ onClicked: captureControls.videoModeSelected()
+ }
+
+
+ CameraButton {
+ id: quitButton
+ text: "Quit"
+ onClicked: Qt.quit()
+ }
+ }
+
+
+ }
+
+
+ ZoomControl {
+ x : 0
+ y : 0
+ width : 100
+ height: parent.height
+
+ currentZoom: camera.digitalZoom
+ maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
+ onZoomTo: camera.setDigitalZoom(value)
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/PhotoPreview.qml b/examples/multimediawidgets/declarative-camera/PhotoPreview.qml
new file mode 100644
index 000000000..f392d3b9f
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/PhotoPreview.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Item {
+ property alias source : preview.source
+ signal closed
+
+ Image {
+ id: preview
+ anchors.fill : parent
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ parent.closed();
+ }
+ }
+}
+
diff --git a/examples/multimediawidgets/declarative-camera/VideoCaptureControls.qml b/examples/multimediawidgets/declarative-camera/VideoCaptureControls.qml
new file mode 100644
index 000000000..c40365e47
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/VideoCaptureControls.qml
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+FocusScope {
+ property Camera camera
+ property bool previewAvailable : false
+
+ property int buttonsPanelWidth: buttonPaneShadow.width
+
+ signal previewSelected
+ signal photoModeSelected
+ id : captureControls
+
+ Rectangle {
+ id: buttonPaneShadow
+ width: buttonsColumn.width + 16
+ height: parent.height
+ anchors.top: parent.top
+ anchors.right: parent.right
+ color: Qt.rgba(0.08, 0.08, 0.08, 1)
+
+ Column {
+ anchors {
+ right: parent.right
+ top: parent.top
+ margins: 8
+ }
+
+ id: buttonsColumn
+ spacing: 8
+
+ FocusButton {
+ camera: captureControls.camera
+ visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
+ }
+
+ CameraButton {
+ text: "Record"
+ visible: camera.videoRecorder.recorderStatus == CameraRecorder.LoadedStatus
+ onClicked: camera.videoRecorder.record()
+ }
+
+ CameraButton {
+ id: stopButton
+ text: "Stop"
+ visible: camera.videoRecorder.recorderStatus == CameraRecorder.RecordingStatus
+ onClicked: camera.videoRecorder.stop()
+ }
+
+ CameraButton {
+ text: "View"
+ onClicked: captureControls.previewSelected()
+ //don't show View button during recording
+ visible: camera.videoRecorder.actualLocation && !stopButton.visible
+ }
+ }
+
+ Column {
+ anchors {
+ bottom: parent.bottom
+ right: parent.right
+ margins: 8
+ }
+
+ id: bottomColumn
+ spacing: 8
+
+ CameraButton {
+ text: "Switch to Photo"
+ onClicked: captureControls.photoModeSelected()
+ }
+
+ CameraButton {
+ id: quitButton
+ text: "Quit"
+ onClicked: Qt.quit()
+ }
+ }
+ }
+
+
+ ZoomControl {
+ x : 0
+ y : 0
+ width : 100
+ height: parent.height
+
+ currentZoom: camera.digitalZoom
+ maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
+ onZoomTo: camera.setDigitalZoom(value)
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/VideoPreview.qml b/examples/multimediawidgets/declarative-camera/VideoPreview.qml
new file mode 100644
index 000000000..dc9eb0b55
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/VideoPreview.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Item {
+ id: videoPreview
+ property alias source : player.source
+ signal closed
+
+ MediaPlayer {
+ id: player
+ autoPlay: true
+
+ //switch back to viewfinder after playback finished
+ onStatusChanged: {
+ if (status == MediaPlayer.EndOfMedia)
+ videoPreview.closed();
+ }
+ }
+
+ VideoOutput {
+ source: player
+ anchors.fill : parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ videoPreview.closed();
+ }
+ }
+}
+
diff --git a/examples/multimediawidgets/declarative-camera/ZoomControl.qml b/examples/multimediawidgets/declarative-camera/ZoomControl.qml
new file mode 100644
index 000000000..a4847baa6
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/ZoomControl.qml
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Item {
+ id : zoomControl
+ property real currentZoom : 1
+ property real maximumZoom : 1
+ signal zoomTo(real value)
+
+ MouseArea {
+ id : mouseArea
+ anchors.fill: parent
+
+ property real initialZoom : 0
+ property real initialPos : 0
+
+ onPressed: {
+ initialPos = mouseY
+ initialZoom = zoomControl.currentZoom
+ }
+
+ onPositionChanged: {
+ if (pressed) {
+ var target = initialZoom * Math.pow(2, (initialPos-mouseY)/zoomControl.height);
+ target = Math.max(1, Math.min(target, zoomControl.maximumZoom))
+ zoomControl.zoomTo(target)
+ }
+ }
+ }
+
+ Item {
+ id : bar
+ x : 16
+ y : parent.height/4
+ width : 24
+ height : parent.height/2
+ opacity : 0
+
+ Rectangle {
+ anchors.fill: parent
+
+ smooth: true
+ radius: 8
+ border.color: "black"
+ border.width: 2
+ color: "white"
+ opacity: 0.3
+ }
+
+ Rectangle {
+ x : 0
+ y : parent.height * (1.0 - (zoomControl.currentZoom-1.0) / (zoomControl.maximumZoom-1.0))
+ width: parent.width
+ height: parent.height - y
+ smooth: true
+ radius: 8
+ color: "black"
+ opacity: 0.5
+ }
+
+ states: State {
+ name: "ShowBar"
+ when: mouseArea.pressed || zoomControl.currentZoom > 1.0
+ PropertyChanges { target: bar; opacity: 1 }
+ }
+
+ transitions: [
+ Transition {
+ to : "ShowBar"
+ NumberAnimation { properties: "opacity"; duration: 100 }
+ },
+ Transition {
+ from : "ShowBar"
+ NumberAnimation { properties: "opacity"; duration: 500 }
+ }
+ ]
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/declarative-camera.pro b/examples/multimediawidgets/declarative-camera/declarative-camera.pro
new file mode 100644
index 000000000..c52a1d1e6
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/declarative-camera.pro
@@ -0,0 +1,10 @@
+TEMPLATE=app
+TARGET=declarative-camera
+
+QT += quick qml multimedia
+
+SOURCES += qmlcamera.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/declarative-camera
+INSTALLS += target
+
diff --git a/examples/multimediawidgets/declarative-camera/declarative-camera.qml b/examples/multimediawidgets/declarative-camera/declarative-camera.qml
new file mode 100644
index 000000000..7f0f21900
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/declarative-camera.qml
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ id : cameraUI
+
+ width: 800
+ height: 480
+
+ color: "black"
+ state: "PhotoCapture"
+
+ states: [
+ State {
+ name: "PhotoCapture"
+ StateChangeScript {
+ script: {
+ camera.captureMode = Camera.CaptureStillImage
+ camera.start()
+ }
+ }
+ },
+ State {
+ name: "PhotoPreview"
+ },
+ State {
+ name: "VideoCapture"
+ StateChangeScript {
+ script: {
+ camera.captureMode = Camera.CaptureVideo
+ camera.start()
+ }
+ }
+ },
+ State {
+ name: "VideoPreview"
+ StateChangeScript {
+ script: {
+ camera.stop()
+ }
+ }
+ }
+ ]
+
+ Camera {
+ id: camera
+ captureMode: Camera.CaptureStillImage
+
+ imageCapture {
+ onImageCaptured: {
+ photoPreview.source = preview
+ stillControls.previewAvailable = true
+ cameraUI.state = "PhotoPreview"
+ }
+ }
+
+ videoRecorder {
+ resolution: "640x480"
+ frameRate: 15
+ }
+ }
+
+ PhotoPreview {
+ id : photoPreview
+ anchors.fill : parent
+ onClosed: cameraUI.state = "PhotoCapture"
+ visible: cameraUI.state == "PhotoPreview"
+ focus: visible
+ }
+
+ VideoPreview {
+ id : videoPreview
+ anchors.fill : parent
+ onClosed: cameraUI.state = "VideoCapture"
+ visible: cameraUI.state == "VideoPreview"
+ focus: visible
+
+ //don't load recorded video if preview is invisible
+ source: visible ? camera.videoRecorder.actualLocation : ""
+ }
+
+ VideoOutput {
+ id: viewfinder
+ visible: cameraUI.state == "PhotoCapture" || cameraUI.state == "VideoCapture"
+
+ x: 0
+ y: 0
+ width: parent.width - stillControls.buttonsPanelWidth
+ height: parent.height
+
+ source: camera
+ }
+
+ PhotoCaptureControls {
+ id: stillControls
+ anchors.fill: parent
+ camera: camera
+ visible: cameraUI.state == "PhotoCapture"
+ onPreviewSelected: cameraUI.state = "PhotoPreview"
+ onVideoModeSelected: cameraUI.state = "VideoCapture"
+ }
+
+ VideoCaptureControls {
+ id: videoControls
+ anchors.fill: parent
+ camera: camera
+ visible: cameraUI.state == "VideoCapture"
+ onPreviewSelected: cameraUI.state = "VideoPreview"
+ onPhotoModeSelected: cameraUI.state = "PhotoCapture"
+ }
+}
diff --git a/examples/multimediawidgets/declarative-camera/declarative-camera.qmlproject b/examples/multimediawidgets/declarative-camera/declarative-camera.qmlproject
new file mode 100644
index 000000000..53f5ecb8d
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/declarative-camera.qmlproject
@@ -0,0 +1,18 @@
+/* File generated by QtCreator */
+
+import QmlProject 1.0
+
+Project {
+ /* Include .qml, .js, and image files from current directory and subdirectories */
+ QmlFiles {
+ directory: "."
+ }
+ JavaScriptFiles {
+ directory: "."
+ }
+ ImageFiles {
+ directory: "."
+ }
+ /* List of plugin directories passed to QML runtime */
+ // importPaths: [ "../exampleplugin" ]
+}
diff --git a/examples/multimediawidgets/declarative-camera/doc/images/qml-camera.png b/examples/multimediawidgets/declarative-camera/doc/images/qml-camera.png
new file mode 100644
index 000000000..0cd61f0a0
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/doc/images/qml-camera.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/doc/src/declarative-camera.qdoc b/examples/multimediawidgets/declarative-camera/doc/src/declarative-camera.qdoc
new file mode 100644
index 000000000..37f35ea26
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/doc/src/declarative-camera.qdoc
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example declarative-camera
+\title QML Camera Example
+\ingroup camera_examples_qml
+
+\brief The Camera Example shows how to use the API to capture a still image
+or video.
+
+\image qml-camera.png
+
+This example demonstrates how to use the Qt Multimedia QML API to access
+camera functions. It shows how to change settings and to capture images.
+
+Most of the QML code supports the user interface for this application with the
+camera types being mostly found in \e {declarative-camera.qml} and
+\e {CaptureControls.qml}.
+
+In \e {declarative-camera.qml} the \l Camera is initialized with an id
+of \e {camera}, a photo preview is setup, states are implemented for image
+preview or capture and \l CaptureControls is initialized. The initial
+\e state is \e PhotoCapture. \l CameraCapture includes a handler, \e onImageCaptured,
+for the \l {imageCaptured} signal. The handler sets up the application to process
+the preview including a change in the user interface state. The \l PhotoPreview
+becomes visible with any key press being picked up by the handler
+in PhotoPreview and returning the state to \e PhotoCapture.
+
+\e CaptureControls, which is implemented in \e {CaptureControls.qml},
+generates a column on the right hand side of the screen which includes control
+buttons for \e focus (not initially visible), \e {capture}, \e {flash modes},
+\e {white balance}, \e {exposure compensation}, and if a preview is
+available a \e {preview} button. The last button exits from the application.
+
+When the Capture button is pressed the \e onClicked handler calls
+\l {Camera::captureImage()}{captureImage()}
+
+
+
+
+
+
+
+*/
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_auto_mode.png b/examples/multimediawidgets/declarative-camera/images/camera_auto_mode.png
new file mode 100644
index 000000000..f168296cf
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_auto_mode.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_camera_setting.png b/examples/multimediawidgets/declarative-camera/images/camera_camera_setting.png
new file mode 100644
index 000000000..7b993eee9
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_camera_setting.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_flash_auto.png b/examples/multimediawidgets/declarative-camera/images/camera_flash_auto.png
new file mode 100644
index 000000000..fb5cc40ec
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_flash_auto.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_flash_fill.png b/examples/multimediawidgets/declarative-camera/images/camera_flash_fill.png
new file mode 100644
index 000000000..7bc5949ac
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_flash_fill.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_flash_off.png b/examples/multimediawidgets/declarative-camera/images/camera_flash_off.png
new file mode 100644
index 000000000..3c5db10cc
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_flash_off.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_flash_redeye.png b/examples/multimediawidgets/declarative-camera/images/camera_flash_redeye.png
new file mode 100644
index 000000000..534a087df
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_flash_redeye.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_white_balance_cloudy.png b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_cloudy.png
new file mode 100644
index 000000000..243b699e7
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_cloudy.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_white_balance_flourescent.png b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_flourescent.png
new file mode 100644
index 000000000..032efe1d1
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_flourescent.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_white_balance_incandescent.png b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_incandescent.png
new file mode 100644
index 000000000..98f906741
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_incandescent.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/camera_white_balance_sunny.png b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_sunny.png
new file mode 100644
index 000000000..d7d5c9a36
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/camera_white_balance_sunny.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/toolbutton.png b/examples/multimediawidgets/declarative-camera/images/toolbutton.png
new file mode 100644
index 000000000..11310013e
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/toolbutton.png
Binary files differ
diff --git a/examples/multimediawidgets/declarative-camera/images/toolbutton.sci b/examples/multimediawidgets/declarative-camera/images/toolbutton.sci
new file mode 100644
index 000000000..9e4f96530
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/images/toolbutton.sci
@@ -0,0 +1,5 @@
+border.left: 15
+border.top: 4
+border.bottom: 4
+border.right: 15
+source: toolbutton.png
diff --git a/examples/multimediawidgets/declarative-camera/qmlcamera.cpp b/examples/multimediawidgets/declarative-camera/qmlcamera.cpp
new file mode 100644
index 000000000..0d8dbc462
--- /dev/null
+++ b/examples/multimediawidgets/declarative-camera/qmlcamera.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QGuiApplication>
+#include <QQuickView>
+#include <QQmlEngine>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc,argv);
+ QQuickView view;
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ // Qt.quit() called in embedded .qml by default only emits
+ // quit() signal, so do this (optionally use Qt.exit()).
+ QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));
+ view.setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() +
+ QLatin1String("/declarative-camera.qml")));
+ view.resize(800, 480);
+ view.show();
+ return app.exec();
+}
diff --git a/examples/multimediawidgets/multimediawidgets.pro b/examples/multimediawidgets/multimediawidgets.pro
new file mode 100644
index 000000000..29d07bb30
--- /dev/null
+++ b/examples/multimediawidgets/multimediawidgets.pro
@@ -0,0 +1,18 @@
+TEMPLATE = subdirs
+
+# These examples all need widgets for now (using creator templates that use widgets)
+!isEmpty(QT.widgets.name) {
+ SUBDIRS += \
+ camera \
+ videographicsitem \
+ videowidget \
+ player \
+ customvideosurface
+
+ QT += widgets
+}
+
+!isEmpty(QT.gui.name):!isEmpty(QT.qml.name) {
+ disabled:SUBDIRS += declarative-camera
+}
+
diff --git a/examples/multimediawidgets/player/doc/src/player.qdoc b/examples/multimediawidgets/player/doc/src/player.qdoc
new file mode 100644
index 000000000..5e98b912c
--- /dev/null
+++ b/examples/multimediawidgets/player/doc/src/player.qdoc
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example player
+ \title Media Player Example
+ \ingroup video_examples
+
+
+ This example creates a simple multimedia player. We can play audio and
+ or video files using various codecs.
+
+ The example uses a QMediaPlayer object passed into a QVideoWidget to
+ control the video output. To give the application playlist capability
+ we also use a QPlayList object.
+
+ To activate the various functions such as play and stop on the dialog
+ we connect clicked() signals to slots that emit the play() and stop()
+ signals and in turn which we connect to the play() and stop() slots in
+ QMediaPlayer.
+
+ \code
+ connect(controls, SIGNAL(play()), player, SLOT(play()));
+ connect(controls, SIGNAL(pause()), player, SLOT(pause()));
+ connect(controls, SIGNAL(stop()), player, SLOT(stop()));
+ \endcode
+
+ We can get the volume (and set our user interface representation)
+
+ \code
+ controls->setVolume(player->volume());
+ \endcode
+
+ and we can make widget 'volume' changes change the volume
+
+ \code
+ connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int)));
+ \endcode
+
+ The example also allows us to change various video properties by means
+ of the QVideoWidget object. We can go to Full Screen mode with a single
+ button click, and back again. Or if we press the "Color Options" dialog
+ button we can have access to more subtle influences. The dialog has a
+ set of sliders so that we can change the brightness, contrast, hue and
+ saturation of the video being watched. The connect() statements are in
+ pairs so that changes to either the user interface widget (the relevant
+ slider) or the QVideoWidget object will update the other object.
+
+ \code
+ connect(brightnessSlider, SIGNAL(sliderMoved(int)), videoWidget,
+ SLOT(setBrightness(int)));
+ connect(videoWidget, SIGNAL(brightnessChanged(int)),
+ brightnessSlider, SLOT(setValue(int)));
+
+ connect(contrastSlider, SIGNAL(sliderMoved(int)), videoWidget,
+ SLOT(setContrast(int)));
+ connect(videoWidget, SIGNAL(contrastChanged(int)), contrastSlider,
+ SLOT(setValue(int)));
+
+ connect(hueSlider, SIGNAL(sliderMoved(int)), videoWidget,
+ SLOT(setHue(int)));
+ connect(videoWidget, SIGNAL(hueChanged(int)), hueSlider,
+ SLOT(setValue(int)));
+
+ connect(saturationSlider, SIGNAL(sliderMoved(int)), videoWidget,
+ SLOT(setSaturation(int)));
+ connect(videoWidget, SIGNAL(saturationChanged(int)),
+ saturationSlider, SLOT(setValue(int)));
+ \endcode
+
+*/
+
diff --git a/examples/multimediawidgets/player/histogramwidget.cpp b/examples/multimediawidgets/player/histogramwidget.cpp
new file mode 100644
index 000000000..7d4e63a58
--- /dev/null
+++ b/examples/multimediawidgets/player/histogramwidget.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "histogramwidget.h"
+#include <QPainter>
+
+HistogramWidget::HistogramWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_levels(128)
+ , m_isBusy(false)
+{
+ m_processor.moveToThread(&m_processorThread);
+ qRegisterMetaType<QVector<qreal> >("QVector<qreal>");
+ connect(&m_processor, SIGNAL(histogramReady(QVector<qreal>)), SLOT(setHistogram(QVector<qreal>)));
+ m_processorThread.start(QThread::LowestPriority);
+}
+
+HistogramWidget::~HistogramWidget()
+{
+ m_processorThread.quit();
+ m_processorThread.wait(10000);
+}
+
+void HistogramWidget::processFrame(QVideoFrame frame)
+{
+ if (m_isBusy)
+ return; //drop frame
+
+ m_isBusy = true;
+ QMetaObject::invokeMethod(&m_processor, "processFrame",
+ Qt::QueuedConnection, Q_ARG(QVideoFrame, frame), Q_ARG(int, m_levels));
+}
+
+void HistogramWidget::setHistogram(QVector<qreal> histogram)
+{
+ m_isBusy = false;
+ m_histogram = histogram;
+ update();
+}
+
+void HistogramWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ QPainter painter(this);
+
+ if (m_histogram.isEmpty()) {
+ painter.fillRect(0, 0, width(), height(), QColor::fromRgb(0, 0, 0));
+ return;
+ }
+
+ qreal barWidth = width() / (qreal)m_histogram.size();
+
+ for (int i = 0; i < m_histogram.size(); i++) {
+ qreal h = m_histogram[i] * height();
+ // draw level
+ painter.fillRect(barWidth * i, height() - h, barWidth * (i + 1), height(), Qt::red);
+ // clear the rest of the control
+ painter.fillRect(barWidth * i, 0, barWidth * (i + 1), height() - h, Qt::black);
+ }
+}
+
+void FrameProcessor::processFrame(QVideoFrame frame, int levels)
+{
+ QVector<qreal> histogram(levels);
+
+ do {
+ if (!levels)
+ break;
+
+ if (!frame.map(QAbstractVideoBuffer::ReadOnly))
+ break;
+
+ if (frame.pixelFormat() == QVideoFrame::Format_YUV420P ||
+ frame.pixelFormat() == QVideoFrame::Format_NV12) {
+ // Process YUV data
+ uchar *b = frame.bits();
+ for (int y = 0; y < frame.height(); y++) {
+ uchar *lastPixel = b + frame.width();
+ for (uchar *curPixel = b; curPixel < lastPixel; curPixel++)
+ histogram[(*curPixel * levels) >> 8] += 1.0;
+ b += frame.bytesPerLine();
+ }
+ } else {
+ QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat());
+ if (imageFormat != QImage::Format_Invalid) {
+ // Process RGB data
+ QImage image(frame.bits(), frame.width(), frame.height(), imageFormat);
+ image = image.convertToFormat(QImage::Format_RGB32);
+
+ const QRgb* b = (const QRgb*)image.bits();
+ for (int y = 0; y < image.height(); y++) {
+ const QRgb *lastPixel = b + frame.width();
+ for (const QRgb *curPixel = b; curPixel < lastPixel; curPixel++)
+ histogram[(qGray(*curPixel) * levels) >> 8] += 1.0;
+ b = (const QRgb*)((uchar*)b + image.bytesPerLine());
+ }
+ }
+ }
+
+ // find maximum value
+ qreal maxValue = 0.0;
+ for (int i = 0; i < histogram.size(); i++) {
+ if (histogram[i] > maxValue)
+ maxValue = histogram[i];
+ }
+
+ if (maxValue > 0.0) {
+ for (int i = 0; i < histogram.size(); i++)
+ histogram[i] /= maxValue;
+ }
+
+ frame.unmap();
+ } while (false);
+
+ emit histogramReady(histogram);
+}
diff --git a/examples/multimediawidgets/player/histogramwidget.h b/examples/multimediawidgets/player/histogramwidget.h
new file mode 100644
index 000000000..6a8aa16fe
--- /dev/null
+++ b/examples/multimediawidgets/player/histogramwidget.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 HISTOGRAMWIDGET_H
+#define HISTOGRAMWIDGET_H
+
+#include <QThread>
+#include <QVideoFrame>
+#include <QWidget>
+
+class FrameProcessor: public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void processFrame(QVideoFrame frame, int levels);
+
+signals:
+ void histogramReady(QVector<qreal> histogram);
+};
+
+class HistogramWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit HistogramWidget(QWidget *parent = 0);
+ ~HistogramWidget();
+ void setLevels(int levels) { m_levels = levels; }
+
+public slots:
+ void processFrame(QVideoFrame frame);
+ void setHistogram(QVector<qreal> histogram);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ QVector<qreal> m_histogram;
+ int m_levels;
+ FrameProcessor m_processor;
+ QThread m_processorThread;
+ bool m_isBusy;
+};
+
+#endif // HISTOGRAMWIDGET_H
diff --git a/examples/multimediawidgets/player/main.cpp b/examples/multimediawidgets/player/main.cpp
new file mode 100644
index 000000000..4754a03e2
--- /dev/null
+++ b/examples/multimediawidgets/player/main.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "player.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+#ifdef Q_WS_MAEMO_6
+ //Meego graphics system conflicts with xvideo during fullscreen transition
+ QApplication::setGraphicsSystem("raster");
+#endif
+ QApplication app(argc, argv);
+
+ Player player;
+
+#if defined(Q_WS_SIMULATOR)
+ player.setAttribute(Qt::WA_LockLandscapeOrientation);
+ player.showMaximized();
+#else
+ player.show();
+#endif
+ return app.exec();
+}
diff --git a/examples/multimediawidgets/player/player.cpp b/examples/multimediawidgets/player/player.cpp
new file mode 100644
index 000000000..fbc3e575e
--- /dev/null
+++ b/examples/multimediawidgets/player/player.cpp
@@ -0,0 +1,428 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "player.h"
+
+#include "playercontrols.h"
+#include "playlistmodel.h"
+#include "histogramwidget.h"
+
+#include <QMediaService>
+#include <QMediaPlaylist>
+#include <QVideoProbe>
+#include <QtWidgets>
+
+
+Player::Player(QWidget *parent)
+ : QWidget(parent)
+ , videoWidget(0)
+ , coverLabel(0)
+ , slider(0)
+#ifndef PLAYER_NO_COLOROPTIONS
+ , colorDialog(0)
+#endif
+{
+//! [create-objs]
+ player = new QMediaPlayer(this);
+ // owned by PlaylistModel
+ playlist = new QMediaPlaylist();
+ player->setPlaylist(playlist);
+//! [create-objs]
+
+ connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
+ connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
+ connect(player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
+ connect(playlist, SIGNAL(currentIndexChanged(int)), SLOT(playlistPositionChanged(int)));
+ connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
+ connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int)));
+ connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
+ connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
+
+//! [2]
+ videoWidget = new VideoWidget(this);
+ player->setVideoOutput(videoWidget);
+
+ playlistModel = new PlaylistModel(this);
+ playlistModel->setPlaylist(playlist);
+//! [2]
+
+ playlistView = new QListView(this);
+ playlistView->setModel(playlistModel);
+ playlistView->setCurrentIndex(playlistModel->index(playlist->currentIndex(), 0));
+
+ connect(playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(jump(QModelIndex)));
+
+ slider = new QSlider(Qt::Horizontal, this);
+ slider->setRange(0, player->duration() / 1000);
+
+ labelDuration = new QLabel(this);
+ connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int)));
+
+ labelHistogram = new QLabel(this);
+ labelHistogram->setText("Histogram:");
+ histogram = new HistogramWidget(this);
+ QHBoxLayout *histogramLayout = new QHBoxLayout;
+ histogramLayout->addWidget(labelHistogram);
+ histogramLayout->addWidget(histogram, 1);
+
+ probe = new QVideoProbe(this);
+ connect(probe, SIGNAL(videoFrameProbed(const QVideoFrame&)), histogram, SLOT(processFrame(QVideoFrame)));
+ probe->setSource(player);
+
+ QPushButton *openButton = new QPushButton(tr("Open"), this);
+
+ connect(openButton, SIGNAL(clicked()), this, SLOT(open()));
+
+ PlayerControls *controls = new PlayerControls(this);
+ controls->setState(player->state());
+ controls->setVolume(player->volume());
+ controls->setMuted(controls->isMuted());
+
+ connect(controls, SIGNAL(play()), player, SLOT(play()));
+ connect(controls, SIGNAL(pause()), player, SLOT(pause()));
+ connect(controls, SIGNAL(stop()), player, SLOT(stop()));
+ connect(controls, SIGNAL(next()), playlist, SLOT(next()));
+ connect(controls, SIGNAL(previous()), this, SLOT(previousClicked()));
+ connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int)));
+ connect(controls, SIGNAL(changeMuting(bool)), player, SLOT(setMuted(bool)));
+ connect(controls, SIGNAL(changeRate(qreal)), player, SLOT(setPlaybackRate(qreal)));
+
+ connect(controls, SIGNAL(stop()), videoWidget, SLOT(update()));
+
+ connect(player, SIGNAL(stateChanged(QMediaPlayer::State)),
+ controls, SLOT(setState(QMediaPlayer::State)));
+ connect(player, SIGNAL(volumeChanged(int)), controls, SLOT(setVolume(int)));
+ connect(player, SIGNAL(mutedChanged(bool)), controls, SLOT(setMuted(bool)));
+
+ fullScreenButton = new QPushButton(tr("FullScreen"), this);
+ fullScreenButton->setCheckable(true);
+
+#ifndef PLAYER_NO_COLOROPTIONS
+ colorButton = new QPushButton(tr("Color Options..."), this);
+ colorButton->setEnabled(false);
+ connect(colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
+#endif
+
+ QBoxLayout *displayLayout = new QHBoxLayout;
+ displayLayout->addWidget(videoWidget, 2);
+ displayLayout->addWidget(playlistView);
+
+ QBoxLayout *controlLayout = new QHBoxLayout;
+ controlLayout->setMargin(0);
+ controlLayout->addWidget(openButton);
+ controlLayout->addStretch(1);
+ controlLayout->addWidget(controls);
+ controlLayout->addStretch(1);
+ controlLayout->addWidget(fullScreenButton);
+#ifndef PLAYER_NO_COLOROPTIONS
+ controlLayout->addWidget(colorButton);
+#endif
+
+ QBoxLayout *layout = new QVBoxLayout;
+ layout->addLayout(displayLayout);
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->addWidget(slider);
+ hLayout->addWidget(labelDuration);
+ layout->addLayout(hLayout);
+ layout->addLayout(controlLayout);
+ layout->addLayout(histogramLayout);
+
+ setLayout(layout);
+
+ if (!player->isAvailable()) {
+ QMessageBox::warning(this, tr("Service not available"),
+ tr("The QMediaPlayer object does not have a valid service.\n"\
+ "Please check the media service plugins are installed."));
+
+ controls->setEnabled(false);
+ playlistView->setEnabled(false);
+ openButton->setEnabled(false);
+#ifndef PLAYER_NO_COLOROPTIONS
+ colorButton->setEnabled(false);
+#endif
+ fullScreenButton->setEnabled(false);
+ }
+
+ metaDataChanged();
+
+ QStringList arguments = qApp->arguments();
+ arguments.removeAt(0);
+ addToPlaylist(arguments);
+}
+
+Player::~Player()
+{
+}
+
+void Player::open()
+{
+ QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"));
+ addToPlaylist(fileNames);
+}
+
+void Player::addToPlaylist(const QStringList& fileNames)
+{
+ foreach (QString const &argument, fileNames) {
+ QFileInfo fileInfo(argument);
+ if (fileInfo.exists()) {
+ QUrl url = QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ if (fileInfo.suffix().toLower() == QLatin1String("m3u")) {
+ playlist->load(url);
+ } else
+ playlist->addMedia(url);
+ } else {
+ QUrl url(argument);
+ if (url.isValid()) {
+ playlist->addMedia(url);
+ }
+ }
+ }
+}
+
+void Player::durationChanged(qint64 duration)
+{
+ this->duration = duration/1000;
+ slider->setMaximum(duration / 1000);
+}
+
+void Player::positionChanged(qint64 progress)
+{
+ if (!slider->isSliderDown()) {
+ slider->setValue(progress / 1000);
+ }
+ updateDurationInfo(progress / 1000);
+}
+
+void Player::metaDataChanged()
+{
+ if (player->isMetaDataAvailable()) {
+ setTrackInfo(QString("%1 - %2")
+ .arg(player->metaData(QMediaMetaData::AlbumArtist).toString())
+ .arg(player->metaData(QMediaMetaData::Title).toString()));
+
+ if (coverLabel) {
+ QUrl url = player->metaData(QMediaMetaData::CoverArtUrlLarge).value<QUrl>();
+
+ coverLabel->setPixmap(!url.isEmpty()
+ ? QPixmap(url.toString())
+ : QPixmap());
+ }
+ }
+}
+
+void Player::previousClicked()
+{
+ // Go to previous track if we are within the first 5 seconds of playback
+ // Otherwise, seek to the beginning.
+ if(player->position() <= 5000)
+ playlist->previous();
+ else
+ player->setPosition(0);
+}
+
+void Player::jump(const QModelIndex &index)
+{
+ if (index.isValid()) {
+ playlist->setCurrentIndex(index.row());
+ player->play();
+ }
+}
+
+void Player::playlistPositionChanged(int currentItem)
+{
+ playlistView->setCurrentIndex(playlistModel->index(currentItem, 0));
+}
+
+void Player::seek(int seconds)
+{
+ player->setPosition(seconds * 1000);
+}
+
+void Player::statusChanged(QMediaPlayer::MediaStatus status)
+{
+ handleCursor(status);
+
+ // handle status message
+ switch (status) {
+ case QMediaPlayer::UnknownMediaStatus:
+ case QMediaPlayer::NoMedia:
+ case QMediaPlayer::LoadedMedia:
+ case QMediaPlayer::BufferingMedia:
+ case QMediaPlayer::BufferedMedia:
+ setStatusInfo(QString());
+ break;
+ case QMediaPlayer::LoadingMedia:
+ setStatusInfo(tr("Loading..."));
+ break;
+ case QMediaPlayer::StalledMedia:
+ setStatusInfo(tr("Media Stalled"));
+ break;
+ case QMediaPlayer::EndOfMedia:
+ QApplication::alert(this);
+ break;
+ case QMediaPlayer::InvalidMedia:
+ displayErrorMessage();
+ break;
+ }
+}
+
+void Player::handleCursor(QMediaPlayer::MediaStatus status)
+{
+#ifndef QT_NO_CURSOR
+ if (status == QMediaPlayer::LoadingMedia ||
+ status == QMediaPlayer::BufferingMedia ||
+ status == QMediaPlayer::StalledMedia)
+ setCursor(QCursor(Qt::BusyCursor));
+ else
+ unsetCursor();
+#endif
+}
+
+void Player::bufferingProgress(int progress)
+{
+ setStatusInfo(tr("Buffering %4%").arg(progress));
+}
+
+void Player::videoAvailableChanged(bool available)
+{
+ if (!available) {
+ disconnect(fullScreenButton, SIGNAL(clicked(bool)),
+ videoWidget, SLOT(setFullScreen(bool)));
+ disconnect(videoWidget, SIGNAL(fullScreenChanged(bool)),
+ fullScreenButton, SLOT(setChecked(bool)));
+ videoWidget->setFullScreen(false);
+ } else {
+ connect(fullScreenButton, SIGNAL(clicked(bool)),
+ videoWidget, SLOT(setFullScreen(bool)));
+ connect(videoWidget, SIGNAL(fullScreenChanged(bool)),
+ fullScreenButton, SLOT(setChecked(bool)));
+
+ if (fullScreenButton->isChecked())
+ videoWidget->setFullScreen(true);
+ }
+#ifndef PLAYER_NO_COLOROPTIONS
+ colorButton->setEnabled(available);
+#endif
+}
+
+void Player::setTrackInfo(const QString &info)
+{
+ trackInfo = info;
+ if (!statusInfo.isEmpty())
+ setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
+ else
+ setWindowTitle(trackInfo);
+}
+
+void Player::setStatusInfo(const QString &info)
+{
+ statusInfo = info;
+ if (!statusInfo.isEmpty())
+ setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
+ else
+ setWindowTitle(trackInfo);
+}
+
+void Player::displayErrorMessage()
+{
+ setStatusInfo(player->errorString());
+}
+
+void Player::updateDurationInfo(qint64 currentInfo)
+{
+ QString tStr;
+ if (currentInfo || duration) {
+ QTime currentTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000);
+ QTime totalTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000);
+ QString format = "mm:ss";
+ if (duration > 3600)
+ format = "hh:mm:ss";
+ tStr = currentTime.toString(format) + " / " + totalTime.toString(format);
+ }
+ labelDuration->setText(tStr);
+}
+
+#ifndef PLAYER_NO_COLOROPTIONS
+void Player::showColorDialog()
+{
+ if (!colorDialog) {
+ QSlider *brightnessSlider = new QSlider(Qt::Horizontal);
+ brightnessSlider->setRange(-100, 100);
+ brightnessSlider->setValue(videoWidget->brightness());
+ connect(brightnessSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setBrightness(int)));
+ connect(videoWidget, SIGNAL(brightnessChanged(int)), brightnessSlider, SLOT(setValue(int)));
+
+ QSlider *contrastSlider = new QSlider(Qt::Horizontal);
+ contrastSlider->setRange(-100, 100);
+ contrastSlider->setValue(videoWidget->contrast());
+ connect(contrastSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setContrast(int)));
+ connect(videoWidget, SIGNAL(contrastChanged(int)), contrastSlider, SLOT(setValue(int)));
+
+ QSlider *hueSlider = new QSlider(Qt::Horizontal);
+ hueSlider->setRange(-100, 100);
+ hueSlider->setValue(videoWidget->hue());
+ connect(hueSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setHue(int)));
+ connect(videoWidget, SIGNAL(hueChanged(int)), hueSlider, SLOT(setValue(int)));
+
+ QSlider *saturationSlider = new QSlider(Qt::Horizontal);
+ saturationSlider->setRange(-100, 100);
+ saturationSlider->setValue(videoWidget->saturation());
+ connect(saturationSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setSaturation(int)));
+ connect(videoWidget, SIGNAL(saturationChanged(int)), saturationSlider, SLOT(setValue(int)));
+
+ QFormLayout *layout = new QFormLayout;
+ layout->addRow(tr("Brightness"), brightnessSlider);
+ layout->addRow(tr("Contrast"), contrastSlider);
+ layout->addRow(tr("Hue"), hueSlider);
+ layout->addRow(tr("Saturation"), saturationSlider);
+
+ QPushButton *button = new QPushButton(tr("Close"));
+ layout->addRow(button);
+
+ colorDialog = new QDialog(this);
+ colorDialog->setWindowTitle(tr("Color Options"));
+ colorDialog->setLayout(layout);
+
+ connect(button, SIGNAL(clicked()), colorDialog, SLOT(close()));
+ }
+ colorDialog->show();
+}
+#endif
diff --git a/examples/multimediawidgets/player/player.h b/examples/multimediawidgets/player/player.h
new file mode 100644
index 000000000..66f1b1679
--- /dev/null
+++ b/examples/multimediawidgets/player/player.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 PLAYER_H
+#define PLAYER_H
+
+#include "videowidget.h"
+
+#include <QWidget>
+#include <QMediaPlayer>
+#include <QMediaPlaylist>
+
+QT_BEGIN_NAMESPACE
+class QAbstractItemView;
+class QLabel;
+class QMediaPlayer;
+class QModelIndex;
+class QPushButton;
+class QSlider;
+class QVideoProbe;
+class QVideoWidget;
+QT_END_NAMESPACE
+
+class PlaylistModel;
+class HistogramWidget;
+
+class Player : public QWidget
+{
+ Q_OBJECT
+
+public:
+ Player(QWidget *parent = 0);
+ ~Player();
+
+signals:
+ void fullScreenChanged(bool fullScreen);
+
+private slots:
+ void open();
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 progress);
+ void metaDataChanged();
+
+ void previousClicked();
+
+ void seek(int seconds);
+ void jump(const QModelIndex &index);
+ void playlistPositionChanged(int);
+
+ void statusChanged(QMediaPlayer::MediaStatus status);
+ void bufferingProgress(int progress);
+ void videoAvailableChanged(bool available);
+
+ void displayErrorMessage();
+
+#ifndef PLAYER_NO_COLOROPTIONS
+ void showColorDialog();
+#endif
+ void addToPlaylist(const QStringList &fileNames);
+
+private:
+ void setTrackInfo(const QString &info);
+ void setStatusInfo(const QString &info);
+ void handleCursor(QMediaPlayer::MediaStatus status);
+ void updateDurationInfo(qint64 currentInfo);
+
+ QMediaPlayer *player;
+ QMediaPlaylist *playlist;
+ VideoWidget *videoWidget;
+ QLabel *coverLabel;
+ QSlider *slider;
+ QLabel *labelDuration;
+ QPushButton *fullScreenButton;
+#ifndef PLAYER_NO_COLOROPTIONS
+ QPushButton *colorButton;
+ QDialog *colorDialog;
+#endif
+
+ QLabel *labelHistogram;
+ HistogramWidget *histogram;
+ QVideoProbe *probe;
+
+ PlaylistModel *playlistModel;
+ QAbstractItemView *playlistView;
+ QString trackInfo;
+ QString statusInfo;
+ qint64 duration;
+};
+
+#endif // PLAYER_H
diff --git a/examples/multimediawidgets/player/player.pro b/examples/multimediawidgets/player/player.pro
new file mode 100644
index 000000000..067b31b11
--- /dev/null
+++ b/examples/multimediawidgets/player/player.pro
@@ -0,0 +1,28 @@
+TEMPLATE = app
+TARGET = player
+
+QT += network \
+ xml \
+ multimedia \
+ multimediawidgets \
+ widgets
+
+HEADERS = \
+ player.h \
+ playercontrols.h \
+ playlistmodel.h \
+ videowidget.h \
+ histogramwidget.h
+SOURCES = main.cpp \
+ player.cpp \
+ playercontrols.cpp \
+ playlistmodel.cpp \
+ videowidget.cpp \
+ histogramwidget.cpp
+
+maemo* {
+ DEFINES += PLAYER_NO_COLOROPTIONS
+}
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/player
+INSTALLS += target
diff --git a/examples/multimediawidgets/player/playercontrols.cpp b/examples/multimediawidgets/player/playercontrols.cpp
new file mode 100644
index 000000000..1f18fc0cd
--- /dev/null
+++ b/examples/multimediawidgets/player/playercontrols.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "playercontrols.h"
+
+#include <QBoxLayout>
+#include <QSlider>
+#include <QStyle>
+#include <QToolButton>
+#include <QComboBox>
+
+PlayerControls::PlayerControls(QWidget *parent)
+ : QWidget(parent)
+ , playerState(QMediaPlayer::StoppedState)
+ , playerMuted(false)
+ , playButton(0)
+ , stopButton(0)
+ , nextButton(0)
+ , previousButton(0)
+ , muteButton(0)
+ , volumeSlider(0)
+ , rateBox(0)
+{
+ playButton = new QToolButton(this);
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+
+ connect(playButton, SIGNAL(clicked()), this, SLOT(playClicked()));
+
+ stopButton = new QToolButton(this);
+ stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
+ stopButton->setEnabled(false);
+
+ connect(stopButton, SIGNAL(clicked()), this, SIGNAL(stop()));
+
+ nextButton = new QToolButton(this);
+ nextButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward));
+
+ connect(nextButton, SIGNAL(clicked()), this, SIGNAL(next()));
+
+ previousButton = new QToolButton(this);
+ previousButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
+
+ connect(previousButton, SIGNAL(clicked()), this, SIGNAL(previous()));
+
+ muteButton = new QToolButton(this);
+ muteButton->setIcon(style()->standardIcon(QStyle::SP_MediaVolume));
+
+ connect(muteButton, SIGNAL(clicked()), this, SLOT(muteClicked()));
+
+ volumeSlider = new QSlider(Qt::Horizontal, this);
+ volumeSlider->setRange(0, 100);
+
+ connect(volumeSlider, SIGNAL(sliderMoved(int)), this, SIGNAL(changeVolume(int)));
+
+ rateBox = new QComboBox(this);
+ rateBox->addItem("0.5x", QVariant(0.5));
+ rateBox->addItem("1.0x", QVariant(1.0));
+ rateBox->addItem("2.0x", QVariant(2.0));
+ rateBox->setCurrentIndex(1);
+
+ connect(rateBox, SIGNAL(activated(int)), SLOT(updateRate()));
+
+ QBoxLayout *layout = new QHBoxLayout;
+ layout->setMargin(0);
+ layout->addWidget(stopButton);
+ layout->addWidget(previousButton);
+ layout->addWidget(playButton);
+ layout->addWidget(nextButton);
+ layout->addWidget(muteButton);
+ layout->addWidget(volumeSlider);
+ layout->addWidget(rateBox);
+ setLayout(layout);
+}
+
+QMediaPlayer::State PlayerControls::state() const
+{
+ return playerState;
+}
+
+void PlayerControls::setState(QMediaPlayer::State state)
+{
+ if (state != playerState) {
+ playerState = state;
+
+ switch (state) {
+ case QMediaPlayer::StoppedState:
+ stopButton->setEnabled(false);
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ case QMediaPlayer::PlayingState:
+ stopButton->setEnabled(true);
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ break;
+ case QMediaPlayer::PausedState:
+ stopButton->setEnabled(true);
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ }
+ }
+}
+
+int PlayerControls::volume() const
+{
+ return volumeSlider ? volumeSlider->value() : 0;
+}
+
+void PlayerControls::setVolume(int volume)
+{
+ if (volumeSlider)
+ volumeSlider->setValue(volume);
+}
+
+bool PlayerControls::isMuted() const
+{
+ return playerMuted;
+}
+
+void PlayerControls::setMuted(bool muted)
+{
+ if (muted != playerMuted) {
+ playerMuted = muted;
+
+ muteButton->setIcon(style()->standardIcon(muted
+ ? QStyle::SP_MediaVolumeMuted
+ : QStyle::SP_MediaVolume));
+ }
+}
+
+void PlayerControls::playClicked()
+{
+ switch (playerState) {
+ case QMediaPlayer::StoppedState:
+ case QMediaPlayer::PausedState:
+ emit play();
+ break;
+ case QMediaPlayer::PlayingState:
+ emit pause();
+ break;
+ }
+}
+
+void PlayerControls::muteClicked()
+{
+ emit changeMuting(!playerMuted);
+}
+
+qreal PlayerControls::playbackRate() const
+{
+ return rateBox->itemData(rateBox->currentIndex()).toDouble();
+}
+
+void PlayerControls::setPlaybackRate(float rate)
+{
+ for (int i = 0; i < rateBox->count(); ++i) {
+ if (qFuzzyCompare(rate, float(rateBox->itemData(i).toDouble()))) {
+ rateBox->setCurrentIndex(i);
+ return;
+ }
+ }
+
+ rateBox->addItem(QString("%1x").arg(rate), QVariant(rate));
+ rateBox->setCurrentIndex(rateBox->count() - 1);
+}
+
+void PlayerControls::updateRate()
+{
+ emit changeRate(playbackRate());
+}
diff --git a/examples/multimediawidgets/player/playercontrols.h b/examples/multimediawidgets/player/playercontrols.h
new file mode 100644
index 000000000..35ae30252
--- /dev/null
+++ b/examples/multimediawidgets/player/playercontrols.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 PLAYERCONTROLS_H
+#define PLAYERCONTROLS_H
+
+#include <QMediaPlayer>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+class QAbstractSlider;
+class QComboBox;
+QT_END_NAMESPACE
+
+class PlayerControls : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PlayerControls(QWidget *parent = 0);
+
+ QMediaPlayer::State state() const;
+ int volume() const;
+ bool isMuted() const;
+ qreal playbackRate() const;
+
+public slots:
+ void setState(QMediaPlayer::State state);
+ void setVolume(int volume);
+ void setMuted(bool muted);
+ void setPlaybackRate(float rate);
+
+signals:
+ void play();
+ void pause();
+ void stop();
+ void next();
+ void previous();
+ void changeVolume(int volume);
+ void changeMuting(bool muting);
+ void changeRate(qreal rate);
+
+private slots:
+ void playClicked();
+ void muteClicked();
+ void updateRate();
+
+private:
+ QMediaPlayer::State playerState;
+ bool playerMuted;
+ QAbstractButton *playButton;
+ QAbstractButton *stopButton;
+ QAbstractButton *nextButton;
+ QAbstractButton *previousButton;
+ QAbstractButton *muteButton;
+ QAbstractSlider *volumeSlider;
+ QComboBox *rateBox;
+};
+
+#endif // PLAYERCONTROLS_H
diff --git a/examples/multimediawidgets/player/playlistmodel.cpp b/examples/multimediawidgets/player/playlistmodel.cpp
new file mode 100644
index 000000000..bf10153e3
--- /dev/null
+++ b/examples/multimediawidgets/player/playlistmodel.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "playlistmodel.h"
+
+#include <QFileInfo>
+#include <QUrl>
+#include <QMediaPlaylist>
+
+PlaylistModel::PlaylistModel(QObject *parent)
+ : QAbstractItemModel(parent)
+ , m_playlist(0)
+{
+}
+
+int PlaylistModel::rowCount(const QModelIndex &parent) const
+{
+ return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0;
+}
+
+int PlaylistModel::columnCount(const QModelIndex &parent) const
+{
+ return !parent.isValid() ? ColumnCount : 0;
+}
+
+QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const
+{
+ return m_playlist && !parent.isValid()
+ && row >= 0 && row < m_playlist->mediaCount()
+ && column >= 0 && column < ColumnCount
+ ? createIndex(row, column)
+ : QModelIndex();
+}
+
+QModelIndex PlaylistModel::parent(const QModelIndex &child) const
+{
+ Q_UNUSED(child);
+
+ return QModelIndex();
+}
+
+QVariant PlaylistModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid() && role == Qt::DisplayRole) {
+ QVariant value = m_data[index];
+ if (!value.isValid() && index.column() == Title) {
+ QUrl location = m_playlist->media(index.row()).canonicalUrl();
+ return QFileInfo(location.path()).fileName();
+ }
+
+ return value;
+ }
+ return QVariant();
+}
+
+QMediaPlaylist *PlaylistModel::playlist() const
+{
+ return m_playlist;
+}
+
+void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
+{
+ if (m_playlist) {
+ disconnect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
+ disconnect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
+ disconnect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
+ disconnect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
+ disconnect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
+ }
+
+ beginResetModel();
+ m_playlist = playlist;
+
+ if (m_playlist) {
+ connect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
+ connect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
+ connect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
+ connect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
+ connect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
+ }
+
+ endResetModel();
+}
+
+bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ Q_UNUSED(role);
+ m_data[index] = value;
+ emit dataChanged(index, index);
+ return true;
+}
+
+void PlaylistModel::beginInsertItems(int start, int end)
+{
+ m_data.clear();
+ beginInsertRows(QModelIndex(), start, end);
+}
+
+void PlaylistModel::endInsertItems()
+{
+ endInsertRows();
+}
+
+void PlaylistModel::beginRemoveItems(int start, int end)
+{
+ m_data.clear();
+ beginRemoveRows(QModelIndex(), start, end);
+}
+
+void PlaylistModel::endRemoveItems()
+{
+ endInsertRows();
+}
+
+void PlaylistModel::changeItems(int start, int end)
+{
+ m_data.clear();
+ emit dataChanged(index(start,0), index(end,ColumnCount));
+}
diff --git a/examples/multimediawidgets/player/playlistmodel.h b/examples/multimediawidgets/player/playlistmodel.h
new file mode 100644
index 000000000..59d202818
--- /dev/null
+++ b/examples/multimediawidgets/player/playlistmodel.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 PLAYLISTMODEL_H
+#define PLAYLISTMODEL_H
+
+#include <QAbstractItemModel>
+
+QT_BEGIN_NAMESPACE
+class QMediaPlaylist;
+QT_END_NAMESPACE
+
+class PlaylistModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ enum Column
+ {
+ Title = 0,
+ ColumnCount
+ };
+
+ PlaylistModel(QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ QMediaPlaylist *playlist() const;
+ void setPlaylist(QMediaPlaylist *playlist);
+
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
+
+private slots:
+ void beginInsertItems(int start, int end);
+ void endInsertItems();
+ void beginRemoveItems(int start, int end);
+ void endRemoveItems();
+ void changeItems(int start, int end);
+
+private:
+ QMediaPlaylist *m_playlist;
+ QMap<QModelIndex, QVariant> m_data;
+};
+
+#endif // PLAYLISTMODEL_H
diff --git a/examples/multimediawidgets/player/videowidget.cpp b/examples/multimediawidgets/player/videowidget.cpp
new file mode 100644
index 000000000..5e07bd398
--- /dev/null
+++ b/examples/multimediawidgets/player/videowidget.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videowidget.h"
+
+#include <QKeyEvent>
+#include <QMouseEvent>
+
+VideoWidget::VideoWidget(QWidget *parent)
+ : QVideoWidget(parent)
+{
+ setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+
+ QPalette p = palette();
+ p.setColor(QPalette::Window, Qt::black);
+ setPalette(p);
+
+ setAttribute(Qt::WA_OpaquePaintEvent);
+}
+
+void VideoWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Escape && isFullScreen()) {
+ setFullScreen(false);
+ event->accept();
+ } else if (event->key() == Qt::Key_Enter && event->modifiers() & Qt::Key_Alt) {
+ setFullScreen(!isFullScreen());
+ event->accept();
+ } else {
+ QVideoWidget::keyPressEvent(event);
+ }
+}
+
+void VideoWidget::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ setFullScreen(!isFullScreen());
+ event->accept();
+}
+
+void VideoWidget::mousePressEvent(QMouseEvent *event)
+{
+ QVideoWidget::mousePressEvent(event);
+}
+
diff --git a/examples/multimediawidgets/player/videowidget.h b/examples/multimediawidgets/player/videowidget.h
new file mode 100644
index 000000000..9a520e7ee
--- /dev/null
+++ b/examples/multimediawidgets/player/videowidget.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QVideoWidget>
+
+class VideoWidget : public QVideoWidget
+{
+ Q_OBJECT
+
+public:
+ VideoWidget(QWidget *parent = 0);
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+};
+
+#endif // VIDEOWIDGET_H
diff --git a/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png b/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png
new file mode 100644
index 000000000..e333c54a2
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/doc/images/video-videographicsitem.png
Binary files differ
diff --git a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc
new file mode 100644
index 000000000..c1eb0ccc7
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example videographicsitem
+\title Video Graphics Item Example
+\ingroup video_examples
+\brief This example demonstrates how to stream video on a graphics scene.
+
+ The Video Graphics Item example shows how to implement a QGraphicsItem that displays video on a
+ graphics scene using QtMultimedia's QAbstractVideoSurface.
+
+ \image video-videographicsitem.png
+
+ \sa {Video Widget Example}
+*/
diff --git a/examples/multimediawidgets/videographicsitem/main.cpp b/examples/multimediawidgets/videographicsitem/main.cpp
new file mode 100644
index 000000000..c8920adce
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ VideoPlayer player;
+ player.show();
+
+ return app.exec();
+}
+
diff --git a/examples/multimediawidgets/videographicsitem/videographicsitem.pro b/examples/multimediawidgets/videographicsitem/videographicsitem.pro
new file mode 100644
index 000000000..30a9b6f21
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/videographicsitem.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = videographicsitem
+
+QT += multimedia multimediawidgets
+
+HEADERS += videoplayer.h
+
+SOURCES += main.cpp \
+ videoplayer.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/videographicsitem
+INSTALLS += target
+
+QT+=widgets
diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.cpp b/examples/multimediawidgets/videographicsitem/videoplayer.cpp
new file mode 100644
index 000000000..caf84cdf5
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/videoplayer.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QtWidgets>
+#include <QVideoSurfaceFormat>
+#include <QGraphicsVideoItem>
+
+VideoPlayer::VideoPlayer(QWidget *parent)
+ : QWidget(parent)
+ , mediaPlayer(0, QMediaPlayer::VideoSurface)
+ , videoItem(0)
+ , playButton(0)
+ , positionSlider(0)
+{
+ videoItem = new QGraphicsVideoItem;
+ videoItem->setSize(QSizeF(640, 480));
+
+ QGraphicsScene *scene = new QGraphicsScene(this);
+ QGraphicsView *graphicsView = new QGraphicsView(scene);
+
+ 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)));
+
+ 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);
+
+ mediaPlayer.setVideoOutput(videoItem);
+ connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SLOT(mediaStateChanged(QMediaPlayer::State)));
+ connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
+ connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)));
+}
+
+VideoPlayer::~VideoPlayer()
+{
+}
+
+
+void VideoPlayer::openFile()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath());
+
+ if (!fileName.isEmpty()) {
+ mediaPlayer.setMedia(QUrl::fromLocalFile(fileName));
+
+ playButton->setEnabled(true);
+ }
+}
+
+void VideoPlayer::play()
+{
+ switch(mediaPlayer.state()) {
+ case QMediaPlayer::PlayingState:
+ mediaPlayer.pause();
+ break;
+ default:
+ mediaPlayer.play();
+ break;
+ }
+}
+
+void VideoPlayer::mediaStateChanged(QMediaPlayer::State state)
+{
+ switch(state) {
+ case QMediaPlayer::PlayingState:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ break;
+ default:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ }
+}
+
+void VideoPlayer::positionChanged(qint64 position)
+{
+ positionSlider->setValue(position);
+}
+
+void VideoPlayer::durationChanged(qint64 duration)
+{
+ positionSlider->setRange(0, duration);
+}
+
+void VideoPlayer::setPosition(int position)
+{
+ mediaPlayer.setPosition(position);
+}
+
+
+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));
+}
diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.h b/examples/multimediawidgets/videographicsitem/videoplayer.h
new file mode 100644
index 000000000..a958b8123
--- /dev/null
+++ b/examples/multimediawidgets/videographicsitem/videoplayer.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QMediaPlayer>
+#include <QMovie>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+class QSlider;
+class QGraphicsVideoItem;
+QT_END_NAMESPACE
+
+class VideoPlayer : public QWidget
+{
+ Q_OBJECT
+
+public:
+ VideoPlayer(QWidget *parent = 0);
+ ~VideoPlayer();
+
+ QSize sizeHint() const { return QSize(800, 600); }
+
+public slots:
+ void openFile();
+ void play();
+
+private slots:
+ void mediaStateChanged(QMediaPlayer::State state);
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void setPosition(int position);
+ void rotateVideo(int angle);
+
+private:
+ QMediaPlayer mediaPlayer;
+ QGraphicsVideoItem *videoItem;
+ QAbstractButton *playButton;
+ QSlider *positionSlider;
+};
+
+#endif
+
diff --git a/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png b/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png
new file mode 100644
index 000000000..a3c7bcb44
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/doc/images/video-videowidget.png
Binary files differ
diff --git a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc
new file mode 100644
index 000000000..860cb7ac5
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example videowidget
+ \title Video Widget Example
+ \ingroup video_examples
+ \brief This example is a simple video player
+
+ The Video Widget example denonstrates how to implement a video widget using
+ QtMultimedia's QAbstractVideoSurface.
+
+ \image video-videowidget.png
+*/
diff --git a/examples/multimediawidgets/videowidget/main.cpp b/examples/multimediawidgets/videowidget/main.cpp
new file mode 100644
index 000000000..b0d83d010
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ VideoPlayer player;
+ player.resize(320, 240);
+ player.show();
+
+ return app.exec();
+}
diff --git a/examples/multimediawidgets/videowidget/videoplayer.cpp b/examples/multimediawidgets/videowidget/videoplayer.cpp
new file mode 100644
index 000000000..d961a63ff
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/videoplayer.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "videoplayer.h"
+
+#include <QtWidgets>
+#include <qvideowidget.h>
+#include <qvideosurfaceformat.h>
+
+VideoPlayer::VideoPlayer(QWidget *parent)
+ : QWidget(parent)
+ , mediaPlayer(0, QMediaPlayer::VideoSurface)
+ , playButton(0)
+ , positionSlider(0)
+{
+ QVideoWidget *videoWidget = new QVideoWidget;
+
+ 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)));
+
+ 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);
+
+ mediaPlayer.setVideoOutput(videoWidget);
+ connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SLOT(mediaStateChanged(QMediaPlayer::State)));
+ connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
+ connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)));
+}
+
+VideoPlayer::~VideoPlayer()
+{
+}
+
+void VideoPlayer::openFile()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath());
+
+ if (!fileName.isEmpty()) {
+ mediaPlayer.setMedia(QUrl::fromLocalFile(fileName));
+
+ playButton->setEnabled(true);
+ }
+}
+
+void VideoPlayer::play()
+{
+ switch(mediaPlayer.state()) {
+ case QMediaPlayer::PlayingState:
+ mediaPlayer.pause();
+ break;
+ default:
+ mediaPlayer.play();
+ break;
+ }
+}
+
+void VideoPlayer::mediaStateChanged(QMediaPlayer::State state)
+{
+ switch(state) {
+ case QMediaPlayer::PlayingState:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ break;
+ default:
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ break;
+ }
+}
+
+void VideoPlayer::positionChanged(qint64 position)
+{
+ positionSlider->setValue(position);
+}
+
+void VideoPlayer::durationChanged(qint64 duration)
+{
+ positionSlider->setRange(0, duration);
+}
+
+void VideoPlayer::setPosition(int position)
+{
+ mediaPlayer.setPosition(position);
+}
diff --git a/examples/multimediawidgets/videowidget/videoplayer.h b/examples/multimediawidgets/videowidget/videoplayer.h
new file mode 100644
index 000000000..ddad18724
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/videoplayer.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <qmediaplayer.h>
+
+#include <QtGui/QMovie>
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+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 mediaStateChanged(QMediaPlayer::State state);
+ void positionChanged(qint64 position);
+ void durationChanged(qint64 duration);
+ void setPosition(int position);
+
+private:
+ QMediaPlayer mediaPlayer;
+ QAbstractButton *playButton;
+ QSlider *positionSlider;
+};
+
+#endif
diff --git a/examples/multimediawidgets/videowidget/videowidget.pro b/examples/multimediawidgets/videowidget/videowidget.pro
new file mode 100644
index 000000000..603996b2e
--- /dev/null
+++ b/examples/multimediawidgets/videowidget/videowidget.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = videowidget
+
+QT += multimedia multimediawidgets
+
+HEADERS = \
+ videoplayer.h
+
+SOURCES = \
+ main.cpp \
+ videoplayer.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/videowidget
+INSTALLS += target
+
+QT+=widgets