diff options
author | Michael Goddard <michael.goddard@nokia.com> | 2011-06-29 13:38:46 +1000 |
---|---|---|
committer | Michael Goddard <michael.goddard@nokia.com> | 2011-06-29 13:38:46 +1000 |
commit | 2a34e88c1e1ced28e75c487cd13402e1c9cf9fa3 (patch) | |
tree | e6c1b770c5c47212792a1f9344fa034ea3e54c44 /examples |
Initial copy of QtMultimediaKit.
Comes from original repo, with SHA1:
2c82d5611655e5967f5c5095af50c0991c4378b2
Diffstat (limited to 'examples')
85 files changed, 8560 insertions, 0 deletions
diff --git a/examples/audiodevices/audiodevices.cpp b/examples/audiodevices/audiodevices.cpp new file mode 100644 index 000000000..d020c9b60 --- /dev/null +++ b/examples/audiodevices/audiodevices.cpp @@ -0,0 +1,312 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <qaudiodeviceinfo.h> + +#include "audiodevices.h" + +// Utility functions for converting QAudioFormat fields into text + +QString toString(QAudioFormat::SampleType sampleType) +{ + QString result("Unknown"); + switch (sampleType) { + case QAudioFormat::SignedInt: + result = "SignedInt"; + break; + case QAudioFormat::UnSignedInt: + result = "UnSignedInt"; + break; + case QAudioFormat::Float: + result = "Float"; + break; + } + return result; +} + +QString toString(QAudioFormat::Endian endian) +{ + QString result("Unknown"); + switch (endian) { + case QAudioFormat::LittleEndian: + result = "LittleEndian"; + break; + case QAudioFormat::BigEndian: + result = "BigEndian"; + break; + } + return result; +} + + +AudioDevicesBase::AudioDevicesBase(QWidget *parent, Qt::WFlags f) + : QMainWindow(parent, f) +{ + setupUi(this); +} + +AudioDevicesBase::~AudioDevicesBase() {} + + +AudioTest::AudioTest(QWidget *parent, Qt::WFlags f) + : AudioDevicesBase(parent, f) +{ + mode = QAudio::AudioOutput; + + connect(testButton, SIGNAL(clicked()), SLOT(test())); + connect(modeBox, SIGNAL(activated(int)), SLOT(modeChanged(int))); + connect(deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int))); + connect(frequencyBox, SIGNAL(activated(int)), SLOT(freqChanged(int))); + connect(channelsBox, SIGNAL(activated(int)), SLOT(channelChanged(int))); + connect(codecsBox, SIGNAL(activated(int)), SLOT(codecChanged(int))); + connect(sampleSizesBox, SIGNAL(activated(int)), SLOT(sampleSizeChanged(int))); + connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int))); + connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int))); + connect(populateTableButton, SIGNAL(clicked()), SLOT(populateTable())); + + modeBox->setCurrentIndex(0); + modeChanged(0); + deviceBox->setCurrentIndex(0); + deviceChanged(0); +} + +AudioTest::~AudioTest() +{ +} + +void AudioTest::test() +{ + // tries to set all the settings picked. + testResult->clear(); + + if (!deviceInfo.isNull()) { + if (deviceInfo.isFormatSupported(settings)) { + testResult->setText(tr("Success")); + nearestFreq->setText(""); + nearestChannel->setText(""); + nearestCodec->setText(""); + nearestSampleSize->setText(""); + nearestSampleType->setText(""); + nearestEndian->setText(""); + } else { + QAudioFormat nearest = deviceInfo.nearestFormat(settings); + testResult->setText(tr("Failed")); + nearestFreq->setText(QString("%1").arg(nearest.frequency())); + nearestChannel->setText(QString("%1").arg(nearest.channels())); + nearestCodec->setText(nearest.codec()); + nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize())); + nearestSampleType->setText(toString(nearest.sampleType())); + nearestEndian->setText(toString(nearest.byteOrder())); + } + } + else + testResult->setText(tr("No Device")); +} + +void AudioTest::modeChanged(int idx) +{ + testResult->clear(); + + // mode has changed + if (idx == 0) + mode = QAudio::AudioInput; + else + mode = QAudio::AudioOutput; + + deviceBox->clear(); + foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode)) + deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo)); + + deviceBox->setCurrentIndex(0); + deviceChanged(0); +} + +void AudioTest::deviceChanged(int idx) +{ + testResult->clear(); + + if (deviceBox->count() == 0) + return; + + // device has changed + deviceInfo = deviceBox->itemData(idx).value<QAudioDeviceInfo>(); + + frequencyBox->clear(); + QList<int> freqz = deviceInfo.supportedFrequencies(); + for(int i = 0; i < freqz.size(); ++i) + frequencyBox->addItem(QString("%1").arg(freqz.at(i))); + if(freqz.size()) + settings.setFrequency(freqz.at(0)); + + channelsBox->clear(); + QList<int> chz = deviceInfo.supportedChannels(); + for(int i = 0; i < chz.size(); ++i) + channelsBox->addItem(QString("%1").arg(chz.at(i))); + if(chz.size()) + settings.setChannels(chz.at(0)); + + codecsBox->clear(); + QStringList codecz = deviceInfo.supportedCodecs(); + for (int i = 0; i < codecz.size(); ++i) + codecsBox->addItem(QString("%1").arg(codecz.at(i))); + if (codecz.size()) + settings.setCodec(codecz.at(0)); + // Add false to create failed condition! + codecsBox->addItem("audio/test"); + + sampleSizesBox->clear(); + QList<int> sampleSizez = deviceInfo.supportedSampleSizes(); + for (int i = 0; i < sampleSizez.size(); ++i) + sampleSizesBox->addItem(QString("%1").arg(sampleSizez.at(i))); + if (sampleSizez.size()) + settings.setSampleSize(sampleSizez.at(0)); + + sampleTypesBox->clear(); + QList<QAudioFormat::SampleType> sampleTypez = deviceInfo.supportedSampleTypes(); + + for (int i = 0; i < sampleTypez.size(); ++i) + sampleTypesBox->addItem(toString(sampleTypez.at(i))); + if (sampleTypez.size()) + settings.setSampleType(sampleTypez.at(0)); + + endianBox->clear(); + QList<QAudioFormat::Endian> endianz = deviceInfo.supportedByteOrders(); + for (int i = 0; i < endianz.size(); ++i) + endianBox->addItem(toString(endianz.at(i))); + if (endianz.size()) + settings.setByteOrder(endianz.at(0)); + + allFormatsTable->clearContents(); +} + +void AudioTest::populateTable() +{ + int row = 0; + + QAudioFormat format; + foreach (QString codec, deviceInfo.supportedCodecs()) { + format.setCodec(codec); + foreach (int frequency, deviceInfo.supportedFrequencies()) { + format.setFrequency(frequency); + foreach (int channels, deviceInfo.supportedChannels()) { + format.setChannels(channels); + foreach (QAudioFormat::SampleType sampleType, deviceInfo.supportedSampleTypes()) { + format.setSampleType(sampleType); + foreach (int sampleSize, deviceInfo.supportedSampleSizes()) { + format.setSampleSize(sampleSize); + foreach (QAudioFormat::Endian endian, deviceInfo.supportedByteOrders()) { + format.setByteOrder(endian); + if (deviceInfo.isFormatSupported(format)) { + allFormatsTable->setRowCount(row + 1); + + QTableWidgetItem *codecItem = new QTableWidgetItem(format.codec()); + allFormatsTable->setItem(row, 0, codecItem); + + QTableWidgetItem *frequencyItem = new QTableWidgetItem(QString("%1").arg(format.frequency())); + allFormatsTable->setItem(row, 1, frequencyItem); + + QTableWidgetItem *channelsItem = new QTableWidgetItem(QString("%1").arg(format.channels())); + allFormatsTable->setItem(row, 2, channelsItem); + + QTableWidgetItem *sampleTypeItem = new QTableWidgetItem(toString(format.sampleType())); + allFormatsTable->setItem(row, 3, sampleTypeItem); + + QTableWidgetItem *sampleSizeItem = new QTableWidgetItem(QString("%1").arg(format.sampleSize())); + allFormatsTable->setItem(row, 4, sampleSizeItem); + + QTableWidgetItem *byteOrderItem = new QTableWidgetItem(toString(format.byteOrder())); + allFormatsTable->setItem(row, 5, byteOrderItem); + + ++row; + } + } + } + } + } + } + } +} + +void AudioTest::freqChanged(int idx) +{ + // freq has changed + settings.setFrequency(frequencyBox->itemText(idx).toInt()); +} + +void AudioTest::channelChanged(int idx) +{ + settings.setChannels(channelsBox->itemText(idx).toInt()); +} + +void AudioTest::codecChanged(int idx) +{ + settings.setCodec(codecsBox->itemText(idx)); +} + +void AudioTest::sampleSizeChanged(int idx) +{ + settings.setSampleSize(sampleSizesBox->itemText(idx).toInt()); +} + +void AudioTest::sampleTypeChanged(int idx) +{ + switch (sampleTypesBox->itemText(idx).toInt()) { + case QAudioFormat::SignedInt: + settings.setSampleType(QAudioFormat::SignedInt); + break; + case QAudioFormat::UnSignedInt: + settings.setSampleType(QAudioFormat::UnSignedInt); + break; + case QAudioFormat::Float: + settings.setSampleType(QAudioFormat::Float); + } +} + +void AudioTest::endianChanged(int idx) +{ + switch (endianBox->itemText(idx).toInt()) { + case QAudioFormat::LittleEndian: + settings.setByteOrder(QAudioFormat::LittleEndian); + break; + case QAudioFormat::BigEndian: + settings.setByteOrder(QAudioFormat::BigEndian); + } +} diff --git a/examples/audiodevices/audiodevices.h b/examples/audiodevices/audiodevices.h new file mode 100644 index 000000000..2938bfced --- /dev/null +++ b/examples/audiodevices/audiodevices.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AUDIODEVICES_H +#define AUDIODEVICES_H + +#include <QObject> +#include <QMainWindow> +#include <qaudiodeviceinfo.h> + +#include "ui_audiodevicesbase.h" + +class AudioDevicesBase : public QMainWindow, public Ui::AudioDevicesBase +{ +public: + AudioDevicesBase(QWidget *parent = 0, Qt::WFlags f = 0); + virtual ~AudioDevicesBase(); +}; + +class AudioTest : public AudioDevicesBase +{ + Q_OBJECT +public: + AudioTest(QWidget *parent = 0, Qt::WFlags f = 0); + virtual ~AudioTest(); + + QAudioDeviceInfo deviceInfo; + QAudioFormat settings; + QAudio::Mode mode; + +private slots: + void modeChanged(int idx); + void deviceChanged(int idx); + void freqChanged(int idx); + void channelChanged(int idx); + void codecChanged(int idx); + void sampleSizeChanged(int idx); + void sampleTypeChanged(int idx); + void endianChanged(int idx); + void test(); + void populateTable(); + +}; + +#endif + diff --git a/examples/audiodevices/audiodevices.pro b/examples/audiodevices/audiodevices.pro new file mode 100644 index 000000000..2af690b8c --- /dev/null +++ b/examples/audiodevices/audiodevices.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/audio +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = audiodevices.h + +SOURCES = audiodevices.cpp \ + main.cpp + +FORMS += audiodevicesbase.ui + +symbian { + TARGET.CAPABILITY = UserEnvironment WriteDeviceData ReadDeviceData +} diff --git a/examples/audiodevices/audiodevicesbase.ui b/examples/audiodevices/audiodevicesbase.ui new file mode 100644 index 000000000..23b45d736 --- /dev/null +++ b/examples/audiodevices/audiodevicesbase.ui @@ -0,0 +1,399 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AudioDevicesBase</class> + <widget class="QMainWindow" name="AudioDevicesBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>679</width> + <height>598</height> + </rect> + </property> + <property name="windowTitle"> + <string>Audio Devices</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>659</width> + <height>558</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="modeLabel"> + <property name="text"> + <string>Mode</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="deviceLabel"> + <property name="text"> + <string>Device</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QComboBox" name="modeBox"> + <item> + <property name="text"> + <string>Input</string> + </property> + </item> + <item> + <property name="text"> + <string>Output</string> + </property> + </item> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="deviceBox"/> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="testFormatTab"> + <attribute name="title"> + <string>Test format</string> + </attribute> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QLabel" name="actualLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="text"> + <string><i>Actual Settings</i></string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="nearestLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Nearest Settings</span></p></body></html></string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="frequencyBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="nearestFreq"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QComboBox" name="channelsBox"/> + </item> + <item row="5" column="2"> + <widget class="QLineEdit" name="nearestChannel"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QComboBox" name="sampleSizesBox"/> + </item> + <item row="9" column="2"> + <widget class="QLineEdit" name="nearestSampleSize"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="14" column="1"> + <widget class="QComboBox" name="endianBox"/> + </item> + <item row="14" column="2"> + <widget class="QLineEdit" name="nearestEndian"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="15" column="1"> + <widget class="QPushButton" name="testButton"> + <property name="text"> + <string>Test</string> + </property> + </widget> + </item> + <item row="15" column="2"> + <widget class="QLabel" name="testResult"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="actualFreqLabel"> + <property name="text"> + <string>Frequency (Hz)</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="actualChannelLabel"> + <property name="text"> + <string>Channels</string> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QLabel" name="actualSampleSizeLabel"> + <property name="text"> + <string>Sample size (bits)</string> + </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="actualEndianLabel"> + <property name="text"> + <string>Endianess</string> + </property> + </widget> + </item> + <item row="16" column="0" colspan="3"> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Note: an invalid codec 'audio/test' exists in order to allow an invalid format to be constructed, and therefore to trigger a 'nearest format' calculation.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="actualCodecLabel"> + <property name="text"> + <string>Codec</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLineEdit" name="nearestCodec"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="codecsBox"/> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="actualSampleTypeLabel"> + <property name="text"> + <string>SampleType</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QComboBox" name="sampleTypesBox"/> + </item> + <item row="6" column="2"> + <widget class="QLineEdit" name="nearestSampleType"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>All formats</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QPushButton" name="populateTableButton"> + <property name="text"> + <string>Populate table</string> + </property> + </widget> + </item> + <item> + <widget class="QTableWidget" name="allFormatsTable"> + <property name="editTriggers"> + <set>QAbstractItemView::NoEditTriggers</set> + </property> + <property name="dragDropOverwriteMode"> + <bool>false</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectItems</enum> + </property> + <property name="textElideMode"> + <enum>Qt::ElideNone</enum> + </property> + <property name="sortingEnabled"> + <bool>false</bool> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + <property name="cornerButtonEnabled"> + <bool>false</bool> + </property> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string>Codec</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Frequency (Hz)</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Channels</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Sample type</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Sample size (bits)</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + <column> + <property name="text"> + <string>Endianness</string> + </property> + <property name="textAlignment"> + <set>AlignHCenter|AlignVCenter|AlignCenter</set> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/audioinput/audioinput.cpp b/examples/audioinput/audioinput.cpp new file mode 100644 index 000000000..aa008df1a --- /dev/null +++ b/examples/audioinput/audioinput.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <stdlib.h> +#include <math.h> + +#include <QDebug> +#include <QPainter> +#include <QVBoxLayout> + +#include <qaudiodeviceinfo.h> +#include <qaudioinput.h> + +#include <QtCore/qendian.h> + +#include "audioinput.h" + +const QString InputTest::PushModeLabel(tr("Enable push mode")); +const QString InputTest::PullModeLabel(tr("Enable pull mode")); +const QString InputTest::SuspendLabel(tr("Suspend recording")); +const QString InputTest::ResumeLabel(tr("Resume recording")); + +const int BufferSize = 4096; + +AudioInfo::AudioInfo(const QAudioFormat &format, QObject *parent) + : QIODevice(parent) + , m_format(format) + , m_maxAmplitude(0) + , m_level(0.0) + +{ + switch (m_format.sampleSize()) { + case 8: + switch (m_format.sampleType()) { + case QAudioFormat::UnSignedInt: + m_maxAmplitude = 255; + break; + case QAudioFormat::SignedInt: + m_maxAmplitude = 127; + break; + default: + break; + } + break; + case 16: + switch (m_format.sampleType()) { + case QAudioFormat::UnSignedInt: + m_maxAmplitude = 65535; + break; + case QAudioFormat::SignedInt: + m_maxAmplitude = 32767; + break; + default: + break; + } + break; + default: + break; + } +} + +AudioInfo::~AudioInfo() +{ +} + +void AudioInfo::start() +{ + open(QIODevice::WriteOnly); +} + +void AudioInfo::stop() +{ + close(); +} + +qint64 AudioInfo::readData(char *data, qint64 maxlen) +{ + Q_UNUSED(data) + Q_UNUSED(maxlen) + + return 0; +} + +qint64 AudioInfo::writeData(const char *data, qint64 len) +{ + if (m_maxAmplitude) { + Q_ASSERT(m_format.sampleSize() % 8 == 0); + const int channelBytes = m_format.sampleSize() / 8; + const int sampleBytes = m_format.channels() * channelBytes; + Q_ASSERT(len % sampleBytes == 0); + const int numSamples = len / sampleBytes; + + quint16 maxValue = 0; + const unsigned char *ptr = reinterpret_cast<const unsigned char *>(data); + + for (int i = 0; i < numSamples; ++i) { + for(int j = 0; j < m_format.channels(); ++j) { + quint16 value = 0; + + if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::UnSignedInt) { + value = *reinterpret_cast<const quint8*>(ptr); + } else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) { + value = qAbs(*reinterpret_cast<const qint8*>(ptr)); + } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) { + if (m_format.byteOrder() == QAudioFormat::LittleEndian) + value = qFromLittleEndian<quint16>(ptr); + else + value = qFromBigEndian<quint16>(ptr); + } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) { + if (m_format.byteOrder() == QAudioFormat::LittleEndian) + value = qAbs(qFromLittleEndian<qint16>(ptr)); + else + value = qAbs(qFromBigEndian<qint16>(ptr)); + } + + maxValue = qMax(value, maxValue); + ptr += channelBytes; + } + } + + maxValue = qMin(maxValue, m_maxAmplitude); + m_level = qreal(maxValue) / m_maxAmplitude; + } + + emit update(); + return len; +} + +RenderArea::RenderArea(QWidget *parent) + : QWidget(parent) +{ + setBackgroundRole(QPalette::Base); + setAutoFillBackground(true); + + m_level = 0; + setMinimumHeight(30); + setMinimumWidth(200); +} + +void RenderArea::paintEvent(QPaintEvent * /* event */) +{ + QPainter painter(this); + + painter.setPen(Qt::black); + painter.drawRect(QRect(painter.viewport().left()+10, + painter.viewport().top()+10, + painter.viewport().right()-20, + painter.viewport().bottom()-20)); + if (m_level == 0.0) + return; + + int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*m_level; + painter.fillRect(painter.viewport().left()+11, + painter.viewport().top()+10, + pos, + painter.viewport().height()-21, + Qt::red); +} + +void RenderArea::setLevel(qreal value) +{ + m_level = value; + update(); +} + + +InputTest::InputTest() + : m_canvas(0) + , m_modeButton(0) + , m_suspendResumeButton(0) + , m_deviceBox(0) + , m_device(QAudioDeviceInfo::defaultInputDevice()) + , m_audioInfo(0) + , m_audioInput(0) + , m_input(0) + , m_pullMode(false) + , m_buffer(BufferSize, 0) +{ + initializeWindow(); + initializeAudio(); +} + +InputTest::~InputTest() {} + +void InputTest::initializeWindow() +{ + QScopedPointer<QWidget> window(new QWidget); + QScopedPointer<QVBoxLayout> layout(new QVBoxLayout); + + m_canvas = new RenderArea(this); + layout->addWidget(m_canvas); + + m_deviceBox = new QComboBox(this); + QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + for(int i = 0; i < devices.size(); ++i) + m_deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i))); + + connect(m_deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int))); + layout->addWidget(m_deviceBox); + + m_modeButton = new QPushButton(this); + m_modeButton->setText(PushModeLabel); + connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode())); + layout->addWidget(m_modeButton); + + m_suspendResumeButton = new QPushButton(this); + m_suspendResumeButton->setText(SuspendLabel); + connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspend())); + layout->addWidget(m_suspendResumeButton); + + window->setLayout(layout.data()); + layout.take(); // ownership transferred + + setCentralWidget(window.data()); + QWidget *const windowPtr = window.take(); // ownership transferred + windowPtr->show(); +} + +void InputTest::initializeAudio() +{ + m_pullMode = true; + + m_format.setFrequency(8000); + m_format.setChannels(1); + m_format.setSampleSize(16); + m_format.setSampleType(QAudioFormat::SignedInt); + m_format.setByteOrder(QAudioFormat::LittleEndian); + m_format.setCodec("audio/pcm"); + + QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice()); + if (!info.isFormatSupported(m_format)) { + qWarning() << "Default format not supported - trying to use nearest"; + m_format = info.nearestFormat(m_format); + } + + m_audioInfo = new AudioInfo(m_format, this); + connect(m_audioInfo, SIGNAL(update()), SLOT(refreshDisplay())); + + createAudioInput(); +} + +void InputTest::createAudioInput() +{ + m_audioInput = new QAudioInput(m_device, m_format, this); + connect(m_audioInput, SIGNAL(notify()), SLOT(notified())); + connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); + m_audioInfo->start(); + m_audioInput->start(m_audioInfo); +} + +void InputTest::notified() +{ + qWarning() << "bytesReady = " << m_audioInput->bytesReady() + << ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs() + << ", " << "processedUSecs = "<<m_audioInput->processedUSecs(); +} + +void InputTest::readMore() +{ + if(!m_audioInput) + return; + qint64 len = m_audioInput->bytesReady(); + if(len > BufferSize) + len = BufferSize; + qint64 l = m_input->read(m_buffer.data(), len); + if(l > 0) { + m_audioInfo->write(m_buffer.constData(), l); + } +} + +void InputTest::toggleMode() +{ + // Change bewteen pull and push modes + m_audioInput->stop(); + + if (m_pullMode) { + m_modeButton->setText(PullModeLabel); + m_input = m_audioInput->start(); + connect(m_input, SIGNAL(readyRead()), SLOT(readMore())); + m_pullMode = false; + } else { + m_modeButton->setText(PushModeLabel); + m_pullMode = true; + m_audioInput->start(m_audioInfo); + } + + m_suspendResumeButton->setText(SuspendLabel); +} + +void InputTest::toggleSuspend() +{ + // toggle suspend/resume + if(m_audioInput->state() == QAudio::SuspendedState) { + qWarning() << "status: Suspended, resume()"; + m_audioInput->resume(); + m_suspendResumeButton->setText(SuspendLabel); + } else if (m_audioInput->state() == QAudio::ActiveState) { + qWarning() << "status: Active, suspend()"; + m_audioInput->suspend(); + m_suspendResumeButton->setText(ResumeLabel); + } else if (m_audioInput->state() == QAudio::StoppedState) { + qWarning() << "status: Stopped, resume()"; + m_audioInput->resume(); + m_suspendResumeButton->setText(SuspendLabel); + } else if (m_audioInput->state() == QAudio::IdleState) { + qWarning() << "status: IdleState"; + } +} + +void InputTest::stateChanged(QAudio::State state) +{ + qWarning() << "state = " << state; +} + +void InputTest::refreshDisplay() +{ + m_canvas->setLevel(m_audioInfo->level()); +} + +void InputTest::deviceChanged(int index) +{ + m_audioInfo->stop(); + m_audioInput->stop(); + m_audioInput->disconnect(this); + delete m_audioInput; + + m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>(); + createAudioInput(); +} diff --git a/examples/audioinput/audioinput.h b/examples/audioinput/audioinput.h new file mode 100644 index 000000000..540e79845 --- /dev/null +++ b/examples/audioinput/audioinput.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AUDIOINPUT_H +#define AUDIOINPUT_H + +#include <QPixmap> +#include <QWidget> +#include <QObject> +#include <QMainWindow> +#include <QPushButton> +#include <QComboBox> +#include <QByteArray> + +#include <qaudioinput.h> + +class AudioInfo : public QIODevice +{ + Q_OBJECT +public: + AudioInfo(const QAudioFormat &format, QObject *parent); + ~AudioInfo(); + + void start(); + void stop(); + + qreal level() const { return m_level; } + + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + +private: + const QAudioFormat m_format; + quint16 m_maxAmplitude; + qreal m_level; // 0.0 <= m_level <= 1.0 + +signals: + void update(); +}; + + +class RenderArea : public QWidget +{ + Q_OBJECT + +public: + RenderArea(QWidget *parent = 0); + + void setLevel(qreal value); + +protected: + void paintEvent(QPaintEvent *event); + +private: + qreal m_level; + QPixmap m_pixmap; +}; + +class InputTest : public QMainWindow +{ + Q_OBJECT +public: + InputTest(); + ~InputTest(); + +private: + void initializeWindow(); + void initializeAudio(); + void createAudioInput(); + +private slots: + void refreshDisplay(); + void notified(); + void readMore(); + void toggleMode(); + void toggleSuspend(); + void stateChanged(QAudio::State state); + void deviceChanged(int index); + +private: + // Owned by layout + RenderArea *m_canvas; + QPushButton *m_modeButton; + QPushButton *m_suspendResumeButton; + QComboBox *m_deviceBox; + + QAudioDeviceInfo m_device; + AudioInfo *m_audioInfo; + QAudioFormat m_format; + QAudioInput *m_audioInput; + QIODevice *m_input; + bool m_pullMode; + QByteArray m_buffer; + + static const QString PushModeLabel; + static const QString PullModeLabel; + static const QString SuspendLabel; + static const QString ResumeLabel; +}; + +#endif + diff --git a/examples/audioinput/audioinput.pro b/examples/audioinput/audioinput.pro new file mode 100644 index 000000000..80daa8d65 --- /dev/null +++ b/examples/audioinput/audioinput.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/audio +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = audioinput.h + +SOURCES = audioinput.cpp \ + main.cpp + diff --git a/examples/audioinput/main.cpp b/examples/audioinput/main.cpp new file mode 100644 index 000000000..c14d1c843 --- /dev/null +++ b/examples/audioinput/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "audioinput.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Input Test"); + + InputTest input; + input.show(); + + return app.exec(); +} diff --git a/examples/audiooutput/audiooutput.cpp b/examples/audiooutput/audiooutput.cpp new file mode 100644 index 000000000..df0b226bb --- /dev/null +++ b/examples/audiooutput/audiooutput.cpp @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QVBoxLayout> + +#include <qaudiooutput.h> +#include <qaudiodeviceinfo.h> +#include <QtCore/qmath.h> +#include <QtCore/qendian.h> +#include "audiooutput.h" + +const QString AudioTest::PushModeLabel(tr("Enable push mode")); +const QString AudioTest::PullModeLabel(tr("Enable pull mode")); +const QString AudioTest::SuspendLabel(tr("Suspend playback")); +const QString AudioTest::ResumeLabel(tr("Resume playback")); + +const int DurationSeconds = 1; +const int ToneFrequencyHz = 600; +const int DataFrequencyHz = 44100; +const int BufferSize = 32768; + + +Generator::Generator(const QAudioFormat &format, + qint64 durationUs, + int frequency, + QObject *parent) + : QIODevice(parent) + , m_pos(0) +{ + generateData(format, durationUs, frequency); +} + +Generator::~Generator() +{ + +} + +void Generator::start() +{ + open(QIODevice::ReadOnly); +} + +void Generator::stop() +{ + m_pos = 0; + close(); +} + +void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int frequency) +{ + const int channelBytes = format.sampleSize() / 8; + const int sampleBytes = format.channels() * channelBytes; + + qint64 length = (format.frequency() * format.channels() * (format.sampleSize() / 8)) + * durationUs / 100000; + + Q_ASSERT(length % sampleBytes == 0); + Q_UNUSED(sampleBytes) // suppress warning in release builds + + m_buffer.resize(length); + unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data()); + int sampleIndex = 0; + + while (length) { + const qreal x = qSin(2 * M_PI * frequency * qreal(sampleIndex % format.frequency()) / format.frequency()); + for (int i=0; i<format.channels(); ++i) { + if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) { + const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255); + *reinterpret_cast<quint8*>(ptr) = value; + } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) { + const qint8 value = static_cast<qint8>(x * 127); + *reinterpret_cast<quint8*>(ptr) = value; + } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) { + quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535); + if (format.byteOrder() == QAudioFormat::LittleEndian) + qToLittleEndian<quint16>(value, ptr); + else + qToBigEndian<quint16>(value, ptr); + } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) { + qint16 value = static_cast<qint16>(x * 32767); + if (format.byteOrder() == QAudioFormat::LittleEndian) + qToLittleEndian<qint16>(value, ptr); + else + qToBigEndian<qint16>(value, ptr); + } + + ptr += channelBytes; + length -= channelBytes; + } + ++sampleIndex; + } +} + +qint64 Generator::readData(char *data, qint64 len) +{ + qint64 total = 0; + while (len - total > 0) { + const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total); + memcpy(data + total, m_buffer.constData() + m_pos, chunk); + m_pos = (m_pos + chunk) % m_buffer.size(); + total += chunk; + } + return total; +} + +qint64 Generator::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + Q_UNUSED(len); + + return 0; +} + +qint64 Generator::bytesAvailable() const +{ + return m_buffer.size() + QIODevice::bytesAvailable(); +} + +AudioTest::AudioTest() + : m_pullTimer(new QTimer(this)) + , m_modeButton(0) + , m_suspendResumeButton(0) + , m_deviceBox(0) + , m_device(QAudioDeviceInfo::defaultOutputDevice()) + , m_generator(0) + , m_audioOutput(0) + , m_output(0) + , m_buffer(BufferSize, 0) +{ + initializeWindow(); + initializeAudio(); +} + +void AudioTest::initializeWindow() +{ + QScopedPointer<QWidget> window(new QWidget); + QScopedPointer<QVBoxLayout> layout(new QVBoxLayout); + + m_deviceBox = new QComboBox(this); + foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) + m_deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo)); + connect(m_deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int))); + layout->addWidget(m_deviceBox); + + m_modeButton = new QPushButton(this); + m_modeButton->setText(PushModeLabel); + connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode())); + layout->addWidget(m_modeButton); + + m_suspendResumeButton = new QPushButton(this); + m_suspendResumeButton->setText(SuspendLabel); + connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume())); + layout->addWidget(m_suspendResumeButton); + + window->setLayout(layout.data()); + layout.take(); // ownership transferred + + setCentralWidget(window.data()); + QWidget *const windowPtr = window.take(); // ownership transferred + windowPtr->show(); +} + +void AudioTest::initializeAudio() +{ + connect(m_pullTimer, SIGNAL(timeout()), SLOT(pullTimerExpired())); + + m_pullMode = true; + + m_format.setFrequency(DataFrequencyHz); + m_format.setChannels(1); + m_format.setSampleSize(16); + m_format.setCodec("audio/pcm"); + m_format.setByteOrder(QAudioFormat::LittleEndian); + m_format.setSampleType(QAudioFormat::SignedInt); + + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + if (!info.isFormatSupported(m_format)) { + qWarning() << "Default format not supported - trying to use nearest"; + m_format = info.nearestFormat(m_format); + } + + m_generator = new Generator(m_format, DurationSeconds*1000000, ToneFrequencyHz, this); + + createAudioOutput(); +} + +void AudioTest::createAudioOutput() +{ + delete m_audioOutput; + m_audioOutput = 0; + m_audioOutput = new QAudioOutput(m_device, m_format, this); + connect(m_audioOutput, SIGNAL(notify()), SLOT(notified())); + connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); + m_generator->start(); + m_audioOutput->start(m_generator); +} + +AudioTest::~AudioTest() +{ + +} + +void AudioTest::deviceChanged(int index) +{ + m_pullTimer->stop(); + m_generator->stop(); + m_audioOutput->stop(); + m_audioOutput->disconnect(this); + m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>(); + createAudioOutput(); +} + +void AudioTest::notified() +{ + qWarning() << "bytesFree = " << m_audioOutput->bytesFree() + << ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs() + << ", " << "processedUSecs = " << m_audioOutput->processedUSecs(); +} + +void AudioTest::pullTimerExpired() +{ + if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) { + int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize(); + while (chunks) { + const qint64 len = m_generator->read(m_buffer.data(), m_audioOutput->periodSize()); + if (len) + m_output->write(m_buffer.data(), len); + if (len != m_audioOutput->periodSize()) + break; + --chunks; + } + } +} + +void AudioTest::toggleMode() +{ + m_pullTimer->stop(); + m_audioOutput->stop(); + + if (m_pullMode) { + m_modeButton->setText(PullModeLabel); + m_output = m_audioOutput->start(); + m_pullMode = false; + m_pullTimer->start(20); + } else { + m_modeButton->setText(PushModeLabel); + m_pullMode = true; + m_audioOutput->start(m_generator); + } + + m_suspendResumeButton->setText(SuspendLabel); +} + +void AudioTest::toggleSuspendResume() +{ + if (m_audioOutput->state() == QAudio::SuspendedState) { + qWarning() << "status: Suspended, resume()"; + m_audioOutput->resume(); + m_suspendResumeButton->setText(SuspendLabel); + } else if (m_audioOutput->state() == QAudio::ActiveState) { + qWarning() << "status: Active, suspend()"; + m_audioOutput->suspend(); + m_suspendResumeButton->setText(ResumeLabel); + } else if (m_audioOutput->state() == QAudio::StoppedState) { + qWarning() << "status: Stopped, resume()"; + m_audioOutput->resume(); + m_suspendResumeButton->setText(SuspendLabel); + } else if (m_audioOutput->state() == QAudio::IdleState) { + qWarning() << "status: IdleState"; + } +} + +void AudioTest::stateChanged(QAudio::State state) +{ + qWarning() << "state = " << state; +} diff --git a/examples/audiooutput/audiooutput.h b/examples/audiooutput/audiooutput.h new file mode 100644 index 000000000..805168e7c --- /dev/null +++ b/examples/audiooutput/audiooutput.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AUDIOOUTPUT_H +#define AUDIOOUTPUT_H + +#include <math.h> + +#include <QObject> +#include <QMainWindow> +#include <QIODevice> +#include <QTimer> +#include <QPushButton> +#include <QComboBox> +#include <QByteArray> + +#include <qaudiooutput.h> + +class Generator : public QIODevice +{ + Q_OBJECT +public: + Generator(const QAudioFormat &format, qint64 durationUs, int frequency, QObject *parent); + ~Generator(); + + void start(); + void stop(); + + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + qint64 bytesAvailable() const; + +private: + void generateData(const QAudioFormat &format, qint64 durationUs, int frequency); + +private: + qint64 m_pos; + QByteArray m_buffer; +}; + +class AudioTest : public QMainWindow +{ + Q_OBJECT +public: + AudioTest(); + ~AudioTest(); + +private: + void initializeWindow(); + void initializeAudio(); + void createAudioOutput(); + +private: + QTimer* m_pullTimer; + + // Owned by layout + QPushButton* m_modeButton; + QPushButton* m_suspendResumeButton; + QComboBox* m_deviceBox; + + QAudioDeviceInfo m_device; + Generator* m_generator; + QAudioOutput* m_audioOutput; + QIODevice* m_output; // not owned + QAudioFormat m_format; + + bool m_pullMode; + QByteArray m_buffer; + + static const QString PushModeLabel; + static const QString PullModeLabel; + static const QString SuspendLabel; + static const QString ResumeLabel; + +private slots: + void notified(); + void pullTimerExpired(); + void toggleMode(); + void toggleSuspendResume(); + void stateChanged(QAudio::State state); + void deviceChanged(int index); +}; + +#endif + diff --git a/examples/audiooutput/audiooutput.pro b/examples/audiooutput/audiooutput.pro new file mode 100644 index 000000000..63d037f60 --- /dev/null +++ b/examples/audiooutput/audiooutput.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/audio +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = audiooutput.h + +SOURCES = audiooutput.cpp \ + main.cpp diff --git a/examples/audiooutput/main.cpp b/examples/audiooutput/main.cpp new file mode 100644 index 000000000..93f972d04 --- /dev/null +++ b/examples/audiooutput/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtGui> + +#include "audiooutput.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Output Test"); + + AudioTest audio; + audio.show(); + + return app.exec(); +} diff --git a/examples/audiorecorder/audiorecorder.cpp b/examples/audiorecorder/audiorecorder.cpp new file mode 100644 index 000000000..e4d28df14 --- /dev/null +++ b/examples/audiorecorder/audiorecorder.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qdir.h> +#include <QtGui/qfiledialog.h> + +#include <qaudiocapturesource.h> +#include <qmediarecorder.h> + +#include "audiorecorder.h" + +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(SYMBIAN_S60_3X) +#include "ui_audiorecorder_small.h" +#else +#include "ui_audiorecorder.h" +#endif + +AudioRecorder::AudioRecorder(QWidget *parent) + : + QMainWindow(parent), + ui(new Ui::AudioRecorder), + outputLocationSet(false) +{ + ui->setupUi(this); + + audiosource = new QAudioCaptureSource(this); + capture = new QMediaRecorder(audiosource, this); + + //audio devices + ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString())); + foreach(const QString &device, audiosource->audioInputs()) { + ui->audioDeviceBox->addItem(device, QVariant(device)); + } + + //audio codecs + ui->audioCodecBox->addItem(tr("Default"), QVariant(QString())); + foreach(const QString &codecName, capture->supportedAudioCodecs()) { + ui->audioCodecBox->addItem(codecName, QVariant(codecName)); + } + + //containers + ui->containerBox->addItem(tr("Default"), QVariant(QString())); + foreach(const QString &containerName, capture->supportedContainers()) { + ui->containerBox->addItem(containerName, QVariant(containerName)); + } + + //sample rate: + ui->sampleRateBox->addItem(tr("Default"), QVariant(0)); + foreach(int sampleRate, capture->supportedAudioSampleRates()) { + ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant( + sampleRate)); + } + + ui->qualitySlider->setRange(0, int(QtMultimediaKit::VeryHighQuality)); + ui->qualitySlider->setValue(int(QtMultimediaKit::NormalQuality)); + + //bitrates: + ui->bitrateBox->addItem(QString("Default"), QVariant(0)); + ui->bitrateBox->addItem(QString("32000"), QVariant(32000)); + ui->bitrateBox->addItem(QString("64000"), QVariant(64000)); + ui->bitrateBox->addItem(QString("96000"), QVariant(96000)); + ui->bitrateBox->addItem(QString("128000"), QVariant(128000)); + + connect(capture, SIGNAL(durationChanged(qint64)), this, + SLOT(updateProgress(qint64))); + connect(capture, SIGNAL(stateChanged(QMediaRecorder::State)), this, + SLOT(updateState(QMediaRecorder::State))); + connect(capture, SIGNAL(error(QMediaRecorder::Error)), this, + SLOT(displayErrorMessage())); + } + +AudioRecorder::~AudioRecorder() +{ + delete capture; + delete audiosource; +} + +void AudioRecorder::updateProgress(qint64 duration) +{ + if (capture->error() != QMediaRecorder::NoError || duration < 2000) + return; + + ui->statusbar->showMessage(tr("Recorded %1 sec").arg(qRound(duration / 1000))); +} + +void AudioRecorder::updateState(QMediaRecorder::State state) +{ + QString statusMessage; + + switch (state) { + case QMediaRecorder::RecordingState: + ui->recordButton->setText(tr("Stop")); + ui->pauseButton->setText(tr("Pause")); + if (capture->outputLocation().isEmpty()) + statusMessage = tr("Recording"); + else + statusMessage = tr("Recording to %1").arg( + capture->outputLocation().toString()); + break; + case QMediaRecorder::PausedState: + ui->recordButton->setText(tr("Stop")); + ui->pauseButton->setText(tr("Resume")); + statusMessage = tr("Paused"); + break; + case QMediaRecorder::StoppedState: + ui->recordButton->setText(tr("Record")); + ui->pauseButton->setText(tr("Pause")); + statusMessage = tr("Stopped"); + } + + ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState); + + if (capture->error() == QMediaRecorder::NoError) + ui->statusbar->showMessage(statusMessage); +} + +static QVariant boxValue(const QComboBox *box) +{ + int idx = box->currentIndex(); + if (idx == -1) + return QVariant(); + + return box->itemData(idx); +} + +void AudioRecorder::toggleRecord() +{ + if (capture->state() == QMediaRecorder::StoppedState) { + audiosource->setAudioInput(boxValue(ui->audioDeviceBox).toString()); + + if (!outputLocationSet) + capture->setOutputLocation(generateAudioFilePath()); + + QAudioEncoderSettings settings; + settings.setCodec(boxValue(ui->audioCodecBox).toString()); + settings.setSampleRate(boxValue(ui->sampleRateBox).toInt()); + settings.setBitRate(boxValue(ui->bitrateBox).toInt()); + settings.setQuality(QtMultimediaKit::EncodingQuality(ui->qualitySlider->value())); + settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ? + QtMultimediaKit::ConstantQualityEncoding : + QtMultimediaKit::ConstantBitRateEncoding); + + QString container = boxValue(ui->containerBox).toString(); + + capture->setEncodingSettings(settings, QVideoEncoderSettings(), container); + capture->record(); + } + else { + capture->stop(); + } +} + +void AudioRecorder::togglePause() +{ + if (capture->state() != QMediaRecorder::PausedState) + capture->pause(); + else + capture->record(); +} + +void AudioRecorder::setOutputLocation() +{ + QString fileName = QFileDialog::getSaveFileName(); + capture->setOutputLocation(QUrl(fileName)); + outputLocationSet = true; +} + +void AudioRecorder::displayErrorMessage() +{ + ui->statusbar->showMessage(capture->errorString()); +} + +QUrl AudioRecorder::generateAudioFilePath() +{ + QDir outputDir(QDir::rootPath()); + + int lastImage = 0; + int fileCount = 0; + foreach(QString fileName, outputDir.entryList(QStringList() << "testclip_*")) { + int imgNumber = fileName.mid(5, fileName.size() - 9).toInt(); + lastImage = qMax(lastImage, imgNumber); + if (outputDir.exists(fileName)) + fileCount += 1; + } + lastImage += fileCount; + QUrl location(QDir::toNativeSeparators(outputDir.canonicalPath() + QString("/testclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0')))); + return location; +} diff --git a/examples/audiorecorder/audiorecorder.h b/examples/audiorecorder/audiorecorder.h new file mode 100644 index 000000000..3bcebf6ed --- /dev/null +++ b/examples/audiorecorder/audiorecorder.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AUDIORECORDER_H +#define AUDIORECORDER_H + +#include <QtCore/qurl.h> +#include <QtGui/qmainwindow.h> + +#include <qmediarecorder.h> + + +QT_BEGIN_NAMESPACE + +namespace Ui { + class AudioRecorder; +} + +class QAudioCaptureSource; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class AudioRecorder : public QMainWindow +{ + Q_OBJECT +public: + AudioRecorder(QWidget *parent = 0); + ~AudioRecorder(); + +private slots: + void setOutputLocation(); + void togglePause(); + void toggleRecord(); + + void updateState(QMediaRecorder::State); + void updateProgress(qint64 pos); + void displayErrorMessage(); + QUrl generateAudioFilePath(); + +private: + Ui::AudioRecorder *ui; + + QAudioCaptureSource* audiosource; + QMediaRecorder* capture; + QAudioEncoderSettings audioSettings; + bool outputLocationSet; + +}; + +#endif diff --git a/examples/audiorecorder/audiorecorder.pro b/examples/audiorecorder/audiorecorder.pro new file mode 100644 index 000000000..99502414e --- /dev/null +++ b/examples/audiorecorder/audiorecorder.pro @@ -0,0 +1,29 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/audio +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = \ + audiorecorder.h + +SOURCES = \ + main.cpp \ + audiorecorder.cpp + +maemo*: { + FORMS += audiorecorder_small.ui +}else:symbian:contains(S60_VERSION, 3.2)|contains(S60_VERSION, 3.1){ + DEFINES += SYMBIAN_S60_3X + FORMS += audiorecorder_small.ui +}else { + FORMS += audiorecorder.ui +} +symbian: { + TARGET.CAPABILITY = UserEnvironment ReadDeviceData WriteDeviceData +} diff --git a/examples/audiorecorder/audiorecorder.ui b/examples/audiorecorder/audiorecorder.ui new file mode 100644 index 000000000..8ade5ce8c --- /dev/null +++ b/examples/audiorecorder/audiorecorder.ui @@ -0,0 +1,250 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AudioRecorder</class> + <widget class="QMainWindow" name="AudioRecorder"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>297</width> + <height>374</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0" colspan="3"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Input Device:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="audioDeviceBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Audio Codec:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="audioCodecBox"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>File Container:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="containerBox"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Sample rate:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="sampleRateBox"/> + </item> + </layout> + </item> + <item row="1" column="0" colspan="3"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Encoding Mode:</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QRadioButton" name="constantQualityRadioButton"> + <property name="text"> + <string>Constant Quality:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="QSlider" name="qualitySlider"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QRadioButton" name="constantBitrateRadioButton"> + <property name="text"> + <string>Constant Bitrate:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="bitrateBox"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QPushButton" name="outputButton"> + <property name="text"> + <string>Output...</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QPushButton" name="recordButton"> + <property name="text"> + <string>Record</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QPushButton" name="pauseButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Pause</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections> + <connection> + <sender>constantQualityRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>qualitySlider</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>113</x> + <y>197</y> + </hint> + <hint type="destinationlabel"> + <x>115</x> + <y>223</y> + </hint> + </hints> + </connection> + <connection> + <sender>constantBitrateRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>bitrateBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>173</x> + <y>259</y> + </hint> + <hint type="destinationlabel"> + <x>190</x> + <y>291</y> + </hint> + </hints> + </connection> + <connection> + <sender>outputButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>setOutputLocation()</slot> + <hints> + <hint type="sourcelabel"> + <x>46</x> + <y>340</y> + </hint> + <hint type="destinationlabel"> + <x>6</x> + <y>302</y> + </hint> + </hints> + </connection> + <connection> + <sender>recordButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>toggleRecord()</slot> + <hints> + <hint type="sourcelabel"> + <x>191</x> + <y>340</y> + </hint> + <hint type="destinationlabel"> + <x>113</x> + <y>317</y> + </hint> + </hints> + </connection> + <connection> + <sender>pauseButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>togglePause()</slot> + <hints> + <hint type="sourcelabel"> + <x>252</x> + <y>334</y> + </hint> + <hint type="destinationlabel"> + <x>258</x> + <y>346</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>setOutputLocation()</slot> + <slot>toggleRecord()</slot> + <slot>togglePause()</slot> + </slots> +</ui> diff --git a/examples/audiorecorder/audiorecorder_small.ui b/examples/audiorecorder/audiorecorder_small.ui new file mode 100644 index 000000000..9d23c4267 --- /dev/null +++ b/examples/audiorecorder/audiorecorder_small.ui @@ -0,0 +1,266 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AudioRecorder</class> + <widget class="QMainWindow" name="AudioRecorder"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>420</width> + <height>346</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0" colspan="3"> + <widget class="QScrollArea" name="scrollArea"> + <property name="focusPolicy"> + <enum>Qt::ClickFocus</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>398</width> + <height>275</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QWidget" name="widget" native="true"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Input Device:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="audioDeviceBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Audio Codec:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="audioCodecBox"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>File Container:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="containerBox"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Sample rate:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="sampleRateBox"/> + </item> + </layout> + </item> + <item row="1" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QRadioButton" name="constantQualityRadioButton"> + <property name="text"> + <string>Quality:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="constantBitrateRadioButton"> + <property name="text"> + <string>Bitrate:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QSlider" name="qualitySlider"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="bitrateBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>29</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item row="1" column="0"> + <widget class="QPushButton" name="outputButton"> + <property name="text"> + <string>Output...</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="recordButton"> + <property name="text"> + <string>Record</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="pauseButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Pause</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections> + <connection> + <sender>constantQualityRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>qualitySlider</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>113</x> + <y>197</y> + </hint> + <hint type="destinationlabel"> + <x>115</x> + <y>223</y> + </hint> + </hints> + </connection> + <connection> + <sender>constantBitrateRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>bitrateBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>173</x> + <y>259</y> + </hint> + <hint type="destinationlabel"> + <x>190</x> + <y>291</y> + </hint> + </hints> + </connection> + <connection> + <sender>outputButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>setOutputLocation()</slot> + <hints> + <hint type="sourcelabel"> + <x>46</x> + <y>340</y> + </hint> + <hint type="destinationlabel"> + <x>6</x> + <y>302</y> + </hint> + </hints> + </connection> + <connection> + <sender>recordButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>toggleRecord()</slot> + <hints> + <hint type="sourcelabel"> + <x>191</x> + <y>340</y> + </hint> + <hint type="destinationlabel"> + <x>113</x> + <y>317</y> + </hint> + </hints> + </connection> + <connection> + <sender>pauseButton</sender> + <signal>clicked()</signal> + <receiver>AudioRecorder</receiver> + <slot>togglePause()</slot> + <hints> + <hint type="sourcelabel"> + <x>252</x> + <y>334</y> + </hint> + <hint type="destinationlabel"> + <x>258</x> + <y>346</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>setOutputLocation()</slot> + <slot>toggleRecord()</slot> + <slot>togglePause()</slot> + </slots> +</ui> diff --git a/examples/audiorecorder/main.cpp b/examples/audiorecorder/main.cpp new file mode 100644 index 000000000..7dee4f807 --- /dev/null +++ b/examples/audiorecorder/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "audiorecorder.h" + +#include <QtGui> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + AudioRecorder recorder; +#ifdef Q_OS_SYMBIAN + recorder.showMaximized(); +#else + recorder.show(); +#endif + + return app.exec(); +}; diff --git a/examples/camera/camera.cpp b/examples/camera/camera.cpp new file mode 100644 index 000000000..ab8ebf33d --- /dev/null +++ b/examples/camera/camera.cpp @@ -0,0 +1,440 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "camera.h" +#include "ui_camera.h" +#include "videosettings.h" +#include "imagesettings.h" + +#include <qmediaservice.h> +#include <qmediarecorder.h> +#include <qcamera.h> +#include <qcameraviewfinder.h> + +#include <qmessagebox.h> +#include <qpalette.h> + +#include <QtGui> + +#if (defined(Q_WS_MAEMO_5) || 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*)), this, 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(QtMultimediaKit::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()) { +#if QT_VERSION >= 0x040700 + 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; +#endif + default: + QMainWindow::keyPressEvent(event); + } +} + +void Camera::keyReleaseEvent(QKeyEvent * event) +{ + if (event->isAutoRepeat()) + return; + + switch (event->key()) { +#if QT_VERSION >= 0x040700 + case Qt::Key_CameraFocus: + camera->unlock(); + break; +#endif + 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::CaptureMode 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/camera/camera.h b/examples/camera/camera.h new file mode 100644 index 000000000..e569baf31 --- /dev/null +++ b/examples/camera/camera.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CAMERA_H +#define CAMERA_H + +#include <qcamera.h> +#include <qmediarecorder.h> +#include <qcameraimagecapture.h> + +QT_BEGIN_NAMESPACE +namespace Ui { + class Camera; +} +class QCameraViewfinder; +QT_END_NAMESPACE + +#include <QMainWindow> +#include <QDir> + +QT_USE_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*); + + 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); + void imageSaved(int, const QString&); + +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/camera/camera.pro b/examples/camera/camera.pro new file mode 100644 index 000000000..2d657e887 --- /dev/null +++ b/examples/camera/camera.pro @@ -0,0 +1,33 @@ +TEMPLATE = app +TARGET = camera + +INCLUDEPATH+=../../src/multimedia \ + ../../src/multimedia/video + +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +HEADERS = \ + camera.h \ + imagesettings.h \ + videosettings.h + +SOURCES = \ + main.cpp \ + camera.cpp \ + imagesettings.cpp \ + videosettings.cpp + +FORMS += \ + camera.ui \ + videosettings.ui \ + imagesettings.ui + +symbian { + include(camerakeyevent_symbian/camerakeyevent_symbian.pri) + TARGET.CAPABILITY += UserEnvironment WriteUserData ReadUserData + TARGET.EPOCHEAPSIZE = 0x20000 0x3000000 + LIBS += -lavkon -leiksrv -lcone -leikcore +} diff --git a/examples/camera/camera.ui b/examples/camera/camera.ui new file mode 100644 index 000000000..ea790fab0 --- /dev/null +++ b/examples/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/camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp new file mode 100644 index 000000000..30723af40 --- /dev/null +++ b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "camerakeyevent_symbian.h" + +#include <QtGui/QWidget> // WId +#include <eikon.hrh> // EKeyCamera +#include <coecntrl.h> // CCoeControl (WId) +#include <w32std.h> // RWindowbase, RWindowGroup, RWsSession + +QSymbianCameraKeyListener::QSymbianCameraKeyListener(QWidget *widget): + QObject(widget), + m_widget(widget) +{ + if (!m_widget) + return; + + // Get view's native Symbian window + WId windowId = 0; + if (m_widget->internalWinId()) + windowId = m_widget->internalWinId(); + else if (m_widget->parentWidget() && m_widget->effectiveWinId()) + windowId = m_widget->effectiveWinId(); + RWindowBase *window = windowId ? static_cast<RWindowBase*>(windowId->DrawableWindow()) : 0; + + // Get hold of the window group + TInt wGroupId = window ? window->WindowGroupId() : 0; + if (!wGroupId) + return; + RWsSession &wsSession = CCoeEnv::Static()->WsSession(); + TUint wGroupHandle = wsSession.GetWindowGroupHandle(wGroupId); + if (wGroupHandle) { + RWindowGroup wGroup(wsSession); + wGroup.Construct(wGroupHandle); + if (wGroup.CaptureKey(EKeyCamera, 0, 0, 100) < 0) + qWarning("Unable to register for camera capture key events, SwEvent capability may be missing"); + } +} + +QSymbianCameraKeyListener::~QSymbianCameraKeyListener() +{ + if (!m_widget) + return; + + // Get view's native Symbian window + WId windowId = 0; + if (m_widget->internalWinId()) + windowId = m_widget->internalWinId(); + else if (m_widget->parentWidget() && m_widget->effectiveWinId()) + windowId = m_widget->effectiveWinId(); + RWindowBase *window = windowId ? static_cast<RWindowBase*>(windowId->DrawableWindow()) : 0; + + // Get hold of the window group + TInt wGroupId = window ? window->WindowGroupId() : 0; + if (!wGroupId) + return; + RWsSession &wsSession = CCoeEnv::Static()->WsSession(); + TUint wGroupHandle = wsSession.GetWindowGroupHandle(wGroupId); + if (wGroupHandle) { + RWindowGroup wGroup(wsSession); + wGroup.Construct(wGroupHandle); + wGroup.CancelCaptureKey(EKeyCamera); + } +} diff --git a/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.h b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.h new file mode 100644 index 000000000..4cd5701b9 --- /dev/null +++ b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.h @@ -0,0 +1,87 @@ +#ifndef CAMERAKEYEVENT_SYMBIAN_H +#define CAMERAKEYEVENT_SYMBIAN_H + +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * Description: + * This header can be used to register application on Symbian platforms + * for the Camera capture button key events. Application can avoid native + * camera application from starting by not forwarding the key event. + * + * Usage: + * Application needs to include this header and include the needed Symbian + * libraries. Optionally application can include camerakeyevent_symbian.pri + * file. Application can register and unregister for the Camera capture + * key events by creating/destructing the QSymbianCameraKeyListener helper + * object. The widget needs to be shown before it registers for the + * Camera key event. + * + * Libraries needed: + * User needs to define following in the .pro file (or optionally include + * the camerakeyevent_symbian.pri): + * LIBS += -lcone -lws32 + * + * Symbian Capabilities needed: + * To use this header user needs to have SwEvent capability (included in + * the camerakeyevent_symbian.pri): + * TARGET.CAPABILITY += SwEvent + */ + +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QWidget) +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class QSymbianCameraKeyListener : public QObject +{ + Q_OBJECT +public: + QSymbianCameraKeyListener(QWidget *parent = 0); + ~QSymbianCameraKeyListener(); +private: + QWidget *m_widget; +}; + +#endif // CAMERAKEYEVENT_SYMBIAN_H diff --git a/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.pri b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.pri new file mode 100644 index 000000000..097c3b245 --- /dev/null +++ b/examples/camera/camerakeyevent_symbian/camerakeyevent_symbian.pri @@ -0,0 +1,7 @@ +message("camerakeyevent_symbian: Including Symbian camera capture key event register methods") + +HEADERS += $$PWD/camerakeyevent_symbian.h +SOURCES += $$PWD/camerakeyevent_symbian.cpp +INCLUDEPATH += $$PWD +LIBS *= -lcone -lws32 +TARGET.CAPABILITY *= SwEvent diff --git a/examples/camera/imagesettings.cpp b/examples/camera/imagesettings.cpp new file mode 100644 index 000000000..a7f389bb9 --- /dev/null +++ b/examples/camera/imagesettings.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "imagesettings.h" +#include "ui_imagesettings.h" + +#include <QtGui/qcombobox.h> +#include <QtCore/qdebug.h> +#include <qcameraimagecapture.h> +#include <qmediaservice.h> + + + +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(QtMultimediaKit::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(QtMultimediaKit::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/camera/imagesettings.h b/examples/camera/imagesettings.h new file mode 100644 index 000000000..b4b000f6a --- /dev/null +++ b/examples/camera/imagesettings.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IMAGESETTINGS_H +#define IMAGESETTINGS_H + +#include <QtGui/QDialog> +#include <qmediaencodersettings.h> + +QT_BEGIN_NAMESPACE +class QComboBox; +namespace Ui { + class ImageSettingsUi; +} + +class QCameraImageCapture; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class ImageSettings : public QDialog { + Q_OBJECT +public: + ImageSettings(QCameraImageCapture *imageCapture, QWidget *parent = 0); + ~ImageSettings(); + + QAudioEncoderSettings audioSettings() const; + void setAudioSettings(const QAudioEncoderSettings&); + + QImageEncoderSettings imageSettings() const; + void setImageSettings(const QImageEncoderSettings&); + + 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::ImageSettingsUi *ui; + QCameraImageCapture *imagecapture; +}; + +#endif // IMAGESETTINGS_H diff --git a/examples/camera/imagesettings.ui b/examples/camera/imagesettings.ui new file mode 100644 index 000000000..f790c770d --- /dev/null +++ b/examples/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/camera/main.cpp b/examples/camera/main.cpp new file mode 100644 index 000000000..7fd9a61f7 --- /dev/null +++ b/examples/camera/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "camera.h" +#ifdef Q_OS_SYMBIAN +#include "camerakeyevent_symbian.h" +#endif // Q_OS_SYMBIAN + +#include <QtGui> + +int main(int argc, char *argv[]) +{ +#if defined (Q_OS_SYMBIAN) + QApplication::setGraphicsSystem("raster"); + QApplication app(argc, argv); + // lock orientation before constructing camera + CAknAppUi* appUi = dynamic_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi()); + if(appUi){ + QT_TRAP_THROWING(appUi ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + } +#else + QApplication app(argc, argv); +#endif + + Camera camera; + +#ifdef Q_OS_SYMBIAN + camera.showMaximized(); + new QSymbianCameraKeyListener(&camera); +#else + camera.show(); +#endif + + return app.exec(); +}; diff --git a/examples/camera/videosettings.cpp b/examples/camera/videosettings.cpp new file mode 100644 index 000000000..f6beb70b5 --- /dev/null +++ b/examples/camera/videosettings.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videosettings.h" +#include "ui_videosettings.h" + +#include <QtGui/qcombobox.h> +#include <QtCore/qdebug.h> +#include <qmediarecorder.h> +#include <qmediaservice.h> + + +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(QtMultimediaKit::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(QtMultimediaKit::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(QtMultimediaKit::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(QtMultimediaKit::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/camera/videosettings.h b/examples/camera/videosettings.h new file mode 100644 index 000000000..8eeea35b1 --- /dev/null +++ b/examples/camera/videosettings.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOSETTINGS_H +#define VIDEOSETTINGS_H + +#include <QtGui/QDialog> +#include <qmediaencodersettings.h> + +QT_BEGIN_NAMESPACE +class QComboBox; +namespace Ui { + class VideoSettingsUi; +} + +class QMediaRecorder; +QT_END_NAMESPACE + +QT_USE_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/camera/videosettings.ui b/examples/camera/videosettings.ui new file mode 100644 index 000000000..f6aa004c5 --- /dev/null +++ b/examples/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/declarative-camera/CameraButton.qml b/examples/declarative-camera/CameraButton.qml new file mode 100644 index 000000000..cc0b1e787 --- /dev/null +++ b/examples/declarative-camera/CameraButton.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 + +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/declarative-camera/CameraPropertyButton.qml b/examples/declarative-camera/CameraPropertyButton.qml new file mode 100644 index 000000000..8787ecbe2 --- /dev/null +++ b/examples/declarative-camera/CameraPropertyButton.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +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 } + PropertyChanges { target: camera; focus: true } + }, + + 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/declarative-camera/CameraPropertyPopup.qml b/examples/declarative-camera/CameraPropertyPopup.qml new file mode 100644 index 000000000..4d49bb904 --- /dev/null +++ b/examples/declarative-camera/CameraPropertyPopup.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 + +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/declarative-camera/CaptureControls.qml b/examples/declarative-camera/CaptureControls.qml new file mode 100644 index 000000000..e431b73b5 --- /dev/null +++ b/examples/declarative-camera/CaptureControls.qml @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +FocusScope { + property Camera camera + property bool previewAvailable : false + + property alias whiteBalance : wbModesButton.value + property alias flashMode : flashModesButton.value + property alias exposureCompensation : exposureCompensationButton.value + + property int buttonsPanelWidth: buttonPaneShadow.width + + signal previewSelected + id : captureControls + + Rectangle { + id: buttonPaneShadow + width: buttonPanningPane.width + 16 + height: parent.height + anchors.top: parent.top + anchors.right: parent.right + color: Qt.rgba(0.08, 0.08, 0.08, 1) + + Flickable { + id: buttonPanningPane + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + margins: 8 + } + width: buttonsColumn.width + + contentWidth: buttonsColumn.width + contentHeight: buttonsColumn.height + + Column { + id: buttonsColumn + spacing: 8 + + FocusButton { + camera: captureControls.camera + } + + CameraButton { + text: "Capture" + onClicked: camera.captureImage() + } + + CameraPropertyButton { + id : flashModesButton + value: Camera.FlashOff + model: ListModel { + ListElement { + icon: "images/camera_flash_auto.png" + value: Camera.FlashAuto + text: "Auto" + } + ListElement { + icon: "images/camera_flash_off.png" + value: Camera.FlashOff + text: "Off" + } + ListElement { + icon: "images/camera_flash_fill.png" + value: Camera.FlashOn + text: "On" + } + ListElement { + icon: "images/camera_flash_redeye.png" + value: Camera.FlashRedEyeReduction + text: "Red Eye Reduction" + } + } + } + + CameraPropertyButton { + id : wbModesButton + value: Camera.WhiteBalanceAuto + model: ListModel { + ListElement { + icon: "images/camera_auto_mode.png" + value: Camera.WhiteBalanceAuto + text: "Auto" + } + ListElement { + icon: "images/camera_white_balance_sunny.png" + value: Camera.WhiteBalanceSunlight + text: "Sunlight" + } + ListElement { + icon: "images/camera_white_balance_cloudy.png" + value: Camera.WhiteBalanceCloudy + text: "Cloudy" + } + ListElement { + icon: "images/camera_white_balance_incandescent.png" + value: Camera.WhiteBalanceIncandescent + text: "Incandescent" + } + ListElement { + icon: "images/camera_white_balance_flourescent.png" + value: Camera.WhiteBalanceFluorescent + text: "Fluorescent" + } + } + } + + ExposureCompensationButton { + id : exposureCompensationButton + } + + CameraButton { + text: "View" + onClicked: captureControls.previewSelected() + visible: captureControls.previewAvailable + } + + CameraButton { + id: quitButton + text: "Quit" + onClicked: Qt.quit() + } + + } + } + } + + + Item { + id: exposureDetails + anchors.bottom : parent.bottom + anchors.left : parent.left + anchors.bottomMargin: 16 + anchors.leftMargin: 16 + height: childrenRect.height + width: childrenRect.width + + visible : camera.lockStatus == Camera.Locked + + Rectangle { + opacity: 0.4 + color: "black" + anchors.fill: parent + } + + Row { + spacing : 16 + + Text { + text: "Av: "+camera.aperture.toFixed(1) + font.pixelSize: 18 + color: "white" + visible: camera.aperture > 0 + } + + Text { + font.pixelSize: 18 + color: "white" + visible: camera.shutterSpped > 0 + text: "Tv: "+printableExposureTime(camera.shutterSpeed) + + function printableExposureTime(t) { + if (t > 3.9) + return "Tv: "+t.toFixed() + "\""; + + if (t > 0.24 ) + return "Tv: "+t.toFixed(1) + "\""; + + if (t > 0) + return "Tv: 1/"+(1/t).toFixed(); + + return ""; + } + } + + Text { + text: "ISO: "+camera.iso.toFixed() + font.pixelSize: 18 + color: "white" + visible: camera.iso > 0 + } + } + } + + 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/declarative-camera/ExposureCompensationButton.qml b/examples/declarative-camera/ExposureCompensationButton.qml new file mode 100644 index 000000000..98e038b8a --- /dev/null +++ b/examples/declarative-camera/ExposureCompensationButton.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 + +Item { + id: exposureCompensation + property real value : flickableList.items[flickableList.index] + signal clicked + + width : 144 + height: 70 + + BorderImage { + id: buttonImage + source: "images/toolbutton.sci" + width: exposureCompensation.width; height: exposureCompensation.height + } + + Text { + text: "Ev:" + x: 8 + y: 8 + font.pixelSize: 18 + color: "white" + } + + FlickableList { + anchors.fill: buttonImage + id: flickableList + items: ["-2", "-1.5", "-1", "-0.5", "0", "+0.5", "+1", "+1.5", "+2"] + index: 4 + + onClicked: exposureCompensation.clicked() + + delegate: Text { + font.pixelSize: 22 + color: "white" + styleColor: "black" + width: flickableList.width + height: flickableList.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: flickableList.items[index] + } + } +} + diff --git a/examples/declarative-camera/FlickableList.qml b/examples/declarative-camera/FlickableList.qml new file mode 100644 index 000000000..f33c45311 --- /dev/null +++ b/examples/declarative-camera/FlickableList.qml @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 + +Item { + id: flickableList + clip: true + + signal clicked + + property alias delegate : repeater.delegate + + property variant items: [] + property int index: 0 + property int itemWidth : flickableList.width + + function scrollTo(id) { + var x = id*flickableList.itemWidth + if (flickArea.contentX != x) { + centeringAnimation.stop(); + flickArea.newX = id*flickableList.itemWidth + centeringAnimation.start(); + } + } + + onIndexChanged: scrollTo(index) + onWidthChanged: scrollTo(index) + + Flickable { + id: flickArea + property int newX: 0 + + MouseArea { + anchors.fill: parent + onClicked: { + var x = mapToItem(flickableList, mouseX, mouseY).x + + if (x < flickableList.width/3) { + if (flickableList.index > 0) + flickableList.scrollTo(flickableList.index-1); + } else if (x > flickableList.width*2/3) { + if (flickableList.index < flickableList.items.length-1) + flickableList.scrollTo(flickableList.index+1); + } else { + flickableList.clicked() + } + + } + } + + PropertyAnimation { + id: centeringAnimation + target: flickArea + properties: "contentX" + easing.type: Easing.OutQuad + from: flickArea.contentX + to: flickArea.newX + + onCompleted: { + flickableList.index = flickArea.newX / flickableList.itemWidth + } + } + + onMovementStarted: { + centeringAnimation.stop(); + } + + onMovementEnded: { + var modulo = flickArea.contentX % flickableList.itemWidth; + var offset = flickableList.itemWidth / 2; + flickArea.newX = modulo < offset ? flickArea.contentX - modulo : flickArea.contentX + (flickableList.itemWidth - modulo); + centeringAnimation.start(); + } + + + width: flickableList.width + height: flickableList.height + contentWidth: items.width + contentHeight: items.height + flickDeceleration: 4000 + + Row { + id: items + Repeater { + id: repeater + model: flickableList.items.length + } + } + } +} diff --git a/examples/declarative-camera/FocusButton.qml b/examples/declarative-camera/FocusButton.qml new file mode 100644 index 000000000..39848c043 --- /dev/null +++ b/examples/declarative-camera/FocusButton.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +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/declarative-camera/PhotoPreview.qml b/examples/declarative-camera/PhotoPreview.qml new file mode 100644 index 000000000..c161d7f1c --- /dev/null +++ b/examples/declarative-camera/PhotoPreview.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +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/declarative-camera/ZoomControl.qml b/examples/declarative-camera/ZoomControl.qml new file mode 100644 index 000000000..681f63bd5 --- /dev/null +++ b/examples/declarative-camera/ZoomControl.qml @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +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 + } + + onMousePositionChanged: { + 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/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp new file mode 100644 index 000000000..30723af40 --- /dev/null +++ b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "camerakeyevent_symbian.h" + +#include <QtGui/QWidget> // WId +#include <eikon.hrh> // EKeyCamera +#include <coecntrl.h> // CCoeControl (WId) +#include <w32std.h> // RWindowbase, RWindowGroup, RWsSession + +QSymbianCameraKeyListener::QSymbianCameraKeyListener(QWidget *widget): + QObject(widget), + m_widget(widget) +{ + if (!m_widget) + return; + + // Get view's native Symbian window + WId windowId = 0; + if (m_widget->internalWinId()) + windowId = m_widget->internalWinId(); + else if (m_widget->parentWidget() && m_widget->effectiveWinId()) + windowId = m_widget->effectiveWinId(); + RWindowBase *window = windowId ? static_cast<RWindowBase*>(windowId->DrawableWindow()) : 0; + + // Get hold of the window group + TInt wGroupId = window ? window->WindowGroupId() : 0; + if (!wGroupId) + return; + RWsSession &wsSession = CCoeEnv::Static()->WsSession(); + TUint wGroupHandle = wsSession.GetWindowGroupHandle(wGroupId); + if (wGroupHandle) { + RWindowGroup wGroup(wsSession); + wGroup.Construct(wGroupHandle); + if (wGroup.CaptureKey(EKeyCamera, 0, 0, 100) < 0) + qWarning("Unable to register for camera capture key events, SwEvent capability may be missing"); + } +} + +QSymbianCameraKeyListener::~QSymbianCameraKeyListener() +{ + if (!m_widget) + return; + + // Get view's native Symbian window + WId windowId = 0; + if (m_widget->internalWinId()) + windowId = m_widget->internalWinId(); + else if (m_widget->parentWidget() && m_widget->effectiveWinId()) + windowId = m_widget->effectiveWinId(); + RWindowBase *window = windowId ? static_cast<RWindowBase*>(windowId->DrawableWindow()) : 0; + + // Get hold of the window group + TInt wGroupId = window ? window->WindowGroupId() : 0; + if (!wGroupId) + return; + RWsSession &wsSession = CCoeEnv::Static()->WsSession(); + TUint wGroupHandle = wsSession.GetWindowGroupHandle(wGroupId); + if (wGroupHandle) { + RWindowGroup wGroup(wsSession); + wGroup.Construct(wGroupHandle); + wGroup.CancelCaptureKey(EKeyCamera); + } +} diff --git a/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.h b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.h new file mode 100644 index 000000000..4cd5701b9 --- /dev/null +++ b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.h @@ -0,0 +1,87 @@ +#ifndef CAMERAKEYEVENT_SYMBIAN_H +#define CAMERAKEYEVENT_SYMBIAN_H + +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * Description: + * This header can be used to register application on Symbian platforms + * for the Camera capture button key events. Application can avoid native + * camera application from starting by not forwarding the key event. + * + * Usage: + * Application needs to include this header and include the needed Symbian + * libraries. Optionally application can include camerakeyevent_symbian.pri + * file. Application can register and unregister for the Camera capture + * key events by creating/destructing the QSymbianCameraKeyListener helper + * object. The widget needs to be shown before it registers for the + * Camera key event. + * + * Libraries needed: + * User needs to define following in the .pro file (or optionally include + * the camerakeyevent_symbian.pri): + * LIBS += -lcone -lws32 + * + * Symbian Capabilities needed: + * To use this header user needs to have SwEvent capability (included in + * the camerakeyevent_symbian.pri): + * TARGET.CAPABILITY += SwEvent + */ + +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QWidget) +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class QSymbianCameraKeyListener : public QObject +{ + Q_OBJECT +public: + QSymbianCameraKeyListener(QWidget *parent = 0); + ~QSymbianCameraKeyListener(); +private: + QWidget *m_widget; +}; + +#endif // CAMERAKEYEVENT_SYMBIAN_H diff --git a/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.pri b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.pri new file mode 100644 index 000000000..097c3b245 --- /dev/null +++ b/examples/declarative-camera/camerakeyevent_symbian/camerakeyevent_symbian.pri @@ -0,0 +1,7 @@ +message("camerakeyevent_symbian: Including Symbian camera capture key event register methods") + +HEADERS += $$PWD/camerakeyevent_symbian.h +SOURCES += $$PWD/camerakeyevent_symbian.cpp +INCLUDEPATH += $$PWD +LIBS *= -lcone -lws32 +TARGET.CAPABILITY *= SwEvent diff --git a/examples/declarative-camera/declarative-camera.pro b/examples/declarative-camera/declarative-camera.pro new file mode 100644 index 000000000..297361cf3 --- /dev/null +++ b/examples/declarative-camera/declarative-camera.pro @@ -0,0 +1,31 @@ +include (../mobility_examples.pri) + +TEMPLATE=app + +QT += declarative network + +!maemo5 { + contains(QT_CONFIG, opengl) { + QT += opengl + } +} + +win32 { + #required by Qt SDK to resolve Mobility libraries + CONFIG+=mobility + MOBILITY+=multimedia +} + +SOURCES += $$PWD/qmlcamera.cpp +!mac:TARGET = qml_camera +else:TARGET = QmlCamera + +RESOURCES += declarative-camera.qrc + +symbian { + include(camerakeyevent_symbian/camerakeyevent_symbian.pri) + load(data_caging_paths) + TARGET.CAPABILITY += UserEnvironment NetworkServices Location ReadUserData WriteUserData + TARGET.EPOCHEAPSIZE = 0x20000 0x3000000 +} + diff --git a/examples/declarative-camera/declarative-camera.qml b/examples/declarative-camera/declarative-camera.qml new file mode 100644 index 000000000..0d9f984de --- /dev/null +++ b/examples/declarative-camera/declarative-camera.qml @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import QtMultimediaKit 1.1 + +Rectangle { + id : cameraUI + color: "black" + state: "PhotoCapture" + + states: [ + State { + name: "PhotoCapture" + StateChangeScript { + script: { + camera.visible = true + camera.focus = true + stillControls.visible = true + photoPreview.visible = false + } + } + }, + State { + name: "PhotoPreview" + StateChangeScript { + script: { + camera.visible = false + stillControls.visible = false + photoPreview.visible = true + photoPreview.focus = true + } + } + } + ] + + PhotoPreview { + id : photoPreview + anchors.fill : parent + onClosed: cameraUI.state = "PhotoCapture" + focus: visible + + Keys.onPressed : { + //return to capture mode if the shutter button is touched + if (event.key == Qt.Key_CameraFocus && !event.isAutoRepeat) { + cameraUI.state = "PhotoCapture" + event.accepted = true; + } + } + } + + Camera { + id: camera + x: 0 + y: 0 + width: parent.width - stillControls.buttonsPanelWidth + height: parent.height + focus: visible //to receive focus and capture key events + //captureResolution : "640x480" + + flashMode: stillControls.flashMode + whiteBalanceMode: stillControls.whiteBalance + exposureCompensation: stillControls.exposureCompensation + + onImageCaptured : { + photoPreview.source = preview + stillControls.previewAvailable = true + cameraUI.state = "PhotoPreview" + } + } + + CaptureControls { + id: stillControls + anchors.fill: parent + camera: camera + onPreviewSelected: cameraUI.state = "PhotoPreview" + } + +} diff --git a/examples/declarative-camera/declarative-camera.qmlproject b/examples/declarative-camera/declarative-camera.qmlproject new file mode 100644 index 000000000..53f5ecb8d --- /dev/null +++ b/examples/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/declarative-camera/declarative-camera.qrc b/examples/declarative-camera/declarative-camera.qrc new file mode 100644 index 000000000..f8ce52784 --- /dev/null +++ b/examples/declarative-camera/declarative-camera.qrc @@ -0,0 +1,28 @@ +<!DOCTYPE RCC> + <RCC version="1.0"> + + <qresource prefix="/"> + <file>declarative-camera.qml</file> + <file>CameraButton.qml</file> + <file>CameraPropertyPopup.qml</file> + <file>CameraPropertyButton.qml</file> + <file>CaptureControls.qml</file> + <file>ExposureCompensationButton.qml</file> + <file>FlickableList.qml</file> + <file>FocusButton.qml</file> + <file>PhotoPreview.qml</file> + <file>ZoomControl.qml</file> + <file>images/camera_auto_mode.png</file> + <file>images/camera_camera_setting.png</file> + <file>images/camera_flash_auto.png</file> + <file>images/camera_flash_fill.png</file> + <file>images/camera_flash_off.png</file> + <file>images/camera_flash_redeye.png</file> + <file>images/camera_white_balance_cloudy.png</file> + <file>images/camera_white_balance_flourescent.png</file> + <file>images/camera_white_balance_incandescent.png</file> + <file>images/camera_white_balance_sunny.png</file> + <file>images/toolbutton.png</file> + <file>images/toolbutton.sci</file> + </qresource> + </RCC> diff --git a/examples/declarative-camera/images/camera_auto_mode.png b/examples/declarative-camera/images/camera_auto_mode.png Binary files differnew file mode 100644 index 000000000..f168296cf --- /dev/null +++ b/examples/declarative-camera/images/camera_auto_mode.png diff --git a/examples/declarative-camera/images/camera_camera_setting.png b/examples/declarative-camera/images/camera_camera_setting.png Binary files differnew file mode 100644 index 000000000..7b993eee9 --- /dev/null +++ b/examples/declarative-camera/images/camera_camera_setting.png diff --git a/examples/declarative-camera/images/camera_flash_auto.png b/examples/declarative-camera/images/camera_flash_auto.png Binary files differnew file mode 100644 index 000000000..fb5cc40ec --- /dev/null +++ b/examples/declarative-camera/images/camera_flash_auto.png diff --git a/examples/declarative-camera/images/camera_flash_fill.png b/examples/declarative-camera/images/camera_flash_fill.png Binary files differnew file mode 100644 index 000000000..7bc5949ac --- /dev/null +++ b/examples/declarative-camera/images/camera_flash_fill.png diff --git a/examples/declarative-camera/images/camera_flash_off.png b/examples/declarative-camera/images/camera_flash_off.png Binary files differnew file mode 100644 index 000000000..3c5db10cc --- /dev/null +++ b/examples/declarative-camera/images/camera_flash_off.png diff --git a/examples/declarative-camera/images/camera_flash_redeye.png b/examples/declarative-camera/images/camera_flash_redeye.png Binary files differnew file mode 100644 index 000000000..534a087df --- /dev/null +++ b/examples/declarative-camera/images/camera_flash_redeye.png diff --git a/examples/declarative-camera/images/camera_white_balance_cloudy.png b/examples/declarative-camera/images/camera_white_balance_cloudy.png Binary files differnew file mode 100644 index 000000000..243b699e7 --- /dev/null +++ b/examples/declarative-camera/images/camera_white_balance_cloudy.png diff --git a/examples/declarative-camera/images/camera_white_balance_flourescent.png b/examples/declarative-camera/images/camera_white_balance_flourescent.png Binary files differnew file mode 100644 index 000000000..032efe1d1 --- /dev/null +++ b/examples/declarative-camera/images/camera_white_balance_flourescent.png diff --git a/examples/declarative-camera/images/camera_white_balance_incandescent.png b/examples/declarative-camera/images/camera_white_balance_incandescent.png Binary files differnew file mode 100644 index 000000000..98f906741 --- /dev/null +++ b/examples/declarative-camera/images/camera_white_balance_incandescent.png diff --git a/examples/declarative-camera/images/camera_white_balance_sunny.png b/examples/declarative-camera/images/camera_white_balance_sunny.png Binary files differnew file mode 100644 index 000000000..d7d5c9a36 --- /dev/null +++ b/examples/declarative-camera/images/camera_white_balance_sunny.png diff --git a/examples/declarative-camera/images/toolbutton.png b/examples/declarative-camera/images/toolbutton.png Binary files differnew file mode 100644 index 000000000..11310013e --- /dev/null +++ b/examples/declarative-camera/images/toolbutton.png diff --git a/examples/declarative-camera/images/toolbutton.sci b/examples/declarative-camera/images/toolbutton.sci new file mode 100644 index 000000000..9e4f96530 --- /dev/null +++ b/examples/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/declarative-camera/qmlcamera.cpp b/examples/declarative-camera/qmlcamera.cpp new file mode 100644 index 000000000..f6d3e9c36 --- /dev/null +++ b/examples/declarative-camera/qmlcamera.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QApplication> +#include <QtGui/QDesktopWidget> +#include <QtDeclarative/QDeclarativeView> +#include <QtDeclarative/QDeclarativeEngine> + +#if !defined(QT_NO_OPENGL) +#include <QtOpenGL/QGLWidget> +#endif + +#ifdef Q_OS_SYMBIAN +#include "camerakeyevent_symbian.h" +#endif // Q_OS_SYMBIAN + +int main(int argc, char *argv[]) +{ + +#if defined (Q_WS_X11) || defined (Q_WS_MAC) || defined (Q_OS_SYMBIAN) + //### default to using raster graphics backend for now + bool gsSpecified = false; + for (int i = 0; i < argc; ++i) { + QString arg = argv[i]; + if (arg == "-graphicssystem") { + gsSpecified = true; + break; + } + } + + if (!gsSpecified) + QApplication::setGraphicsSystem("raster"); +#endif + + QApplication application(argc, argv); + const QString mainQmlApp = QLatin1String("qrc:/declarative-camera.qml"); + QDeclarativeView view; +#if !defined(QT_NO_OPENGL) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_S60) + view.setViewport(new QGLWidget); +#endif + view.setSource(QUrl(mainQmlApp)); + view.setResizeMode(QDeclarativeView::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())); +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + view.setGeometry(application.desktop()->screenGeometry()); + view.showFullScreen(); +#ifdef Q_OS_SYMBIAN + new QSymbianCameraKeyListener(&view); +#endif // Q_OS_SYMBIAN +#else + view.setGeometry(QRect(100, 100, 800, 480)); + view.show(); +#endif + return application.exec(); +} + diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 000000000..fd0069732 --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,21 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + radio \ + camera \ + slideshow \ + audiorecorder \ + audiodevices \ + audioinput \ + audiooutput \ + videographicsitem \ + videowidget + +contains(QT_CONFIG, declarative) { + SUBDIRS += declarative-camera +} + +sources.path = $$QT_MOBILITY_EXAMPLES + +INSTALLS += sources + diff --git a/examples/main.cpp b/examples/main.cpp new file mode 100644 index 000000000..451be57b9 --- /dev/null +++ b/examples/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "audiodevices.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + app.setApplicationName("Audio Device Test"); + + AudioTest audio; +#ifdef Q_OS_SYMBIAN + audio.showMaximized(); +#else + audio.show(); +#endif + + return app.exec(); +} diff --git a/examples/radio/main.cpp b/examples/radio/main.cpp new file mode 100644 index 000000000..89e2c70b6 --- /dev/null +++ b/examples/radio/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "radio.h" + +#include <QtGui> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Radio radio; +#ifdef Q_OS_SYMBIAN + radio.showMaximized(); +#else + radio.show(); +#endif + + return app.exec(); +}; diff --git a/examples/radio/radio.cpp b/examples/radio/radio.cpp new file mode 100644 index 000000000..b37b0b551 --- /dev/null +++ b/examples/radio/radio.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "radio.h" + +#include <QtGui> + +Radio::Radio() +{ + radio = new QRadioTuner; + connect(radio,SIGNAL(frequencyChanged(int)),this,SLOT(freqChanged(int))); + connect(radio,SIGNAL(signalStrengthChanged(int)),this,SLOT(signalChanged(int))); + connect(radio, SIGNAL(error(QRadioTuner::Error)), this, SLOT(error(QRadioTuner::Error))); + + if(radio->isBandSupported(QRadioTuner::FM)) + radio->setBand(QRadioTuner::FM); + + QWidget *window = new QWidget; + QVBoxLayout* layout = new QVBoxLayout; + QHBoxLayout* buttonBar = new QHBoxLayout; +#if defined Q_OS_SYMBIAN // this is so that we can see all buttons also in 3.1 devices, where the screens are smaller.. + QHBoxLayout* buttonBar2 = new QHBoxLayout; +#endif + QHBoxLayout* topBar = new QHBoxLayout; + + layout->addLayout(topBar); + + freq = new QLabel; + freq->setText(QString("%1 kHz").arg(radio->frequency()/1000)); + topBar->addWidget(freq); + + signal = new QLabel; + if (radio->isAvailable()) + signal->setText(tr("No Signal")); + else + signal->setText(tr("No radio found")); + topBar->addWidget(signal); +#if defined Q_WS_MAEMO_5 + QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + topBar->addItem(spacer); + volumeSlider = new QSlider(Qt::Horizontal,this); +#else + volumeSlider = new QSlider(Qt::Vertical,this); +#endif + volumeSlider->setRange(0,100); + volumeSlider->setValue(50); + connect(volumeSlider,SIGNAL(valueChanged(int)),this,SLOT(updateVolume(int))); + topBar->addWidget(volumeSlider); + + layout->addLayout(buttonBar); +#if defined Q_OS_SYMBIAN + layout->addLayout(buttonBar2); +#endif + + searchLeft = new QPushButton; + searchLeft->setText(tr("scan Down")); + connect(searchLeft,SIGNAL(clicked()),SLOT(searchDown())); + buttonBar->addWidget(searchLeft); + + left = new QPushButton; + left->setText(tr("Freq Down")); + connect(left,SIGNAL(clicked()),SLOT(freqDown())); +#if defined Q_OS_SYMBIAN + buttonBar2->addWidget(left); +#else + buttonBar->addWidget(left); +#endif + + right = new QPushButton; + connect(right,SIGNAL(clicked()),SLOT(freqUp())); + right->setText(tr("Freq Up")); +#if defined Q_OS_SYMBIAN + buttonBar2->addWidget(right); +#else + buttonBar->addWidget(right); +#endif + + searchRight = new QPushButton; + searchRight->setText(tr("scan Up")); + connect(searchRight,SIGNAL(clicked()),SLOT(searchUp())); + buttonBar->addWidget(searchRight); + + window->setLayout(layout); + setCentralWidget(window); + window->show(); + + radio->start(); +} + +Radio::~Radio() +{ +} + +void Radio::freqUp() +{ + int f = radio->frequency(); + f = f + radio->frequencyStep(QRadioTuner::FM); + radio->setFrequency(f); +} + +void Radio::freqDown() +{ + int f = radio->frequency(); + f = f - radio->frequencyStep(QRadioTuner::FM); + radio->setFrequency(f); +} + +void Radio::searchUp() +{ + radio->searchForward(); +} + +void Radio::searchDown() +{ + radio->searchBackward(); +} + +void Radio::freqChanged(int) +{ + freq->setText(QString("%1 kHz").arg(radio->frequency()/1000)); +} + +void Radio::signalChanged(int) +{ + if(radio->signalStrength() > 25) + signal->setText(tr("Got Signal")); + else + signal->setText(tr("No Signal")); +} + +void Radio::updateVolume(int v) +{ + radio->setVolume(v); +} + +void Radio::error(QRadioTuner::Error error) +{ + const QMetaObject* metaObj = radio->metaObject(); + QMetaEnum errorEnum = metaObj->enumerator(metaObj->indexOfEnumerator("Error")); + qWarning().nospace() << "Warning: Example application received error QRadioTuner::" << errorEnum.valueToKey(error); +} + diff --git a/examples/radio/radio.h b/examples/radio/radio.h new file mode 100644 index 000000000..2cdcd5c01 --- /dev/null +++ b/examples/radio/radio.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RADIO_H +#define RADIO_H + +#include <QtGui> + +#include <qradiotuner.h> + +QT_BEGIN_NAMESPACE +class QLabel; +class QPushButton; +class QSlider; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class Radio : public QMainWindow +{ + Q_OBJECT +public: + Radio(); + ~Radio(); + +public slots: + void freqUp(); + void freqDown(); + void searchUp(); + void searchDown(); + void freqChanged(int f); + void signalChanged(int s); + void updateVolume(int v); + void error(QRadioTuner::Error error); + +private: + QLabel* freq; + QLabel* signal; + QPushButton* left; + QPushButton* right; + QPushButton* searchLeft; + QPushButton* searchRight; + QSlider* volumeSlider; + QRadioTuner* radio; +}; + +#endif diff --git a/examples/radio/radio.pro b/examples/radio/radio.pro new file mode 100644 index 000000000..386efd4a5 --- /dev/null +++ b/examples/radio/radio.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = \ + radio.h + +SOURCES = \ + main.cpp \ + radio.cpp + +symbian: { + TARGET.CAPABILITY = UserEnvironment WriteDeviceData ReadDeviceData SwEvent +} diff --git a/examples/slideshow/main.cpp b/examples/slideshow/main.cpp new file mode 100644 index 000000000..665c0490d --- /dev/null +++ b/examples/slideshow/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "slideshow.h" + +#include <QtGui> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + SlideShow slideShow; +#ifdef Q_OS_SYMBIAN + slideShow.showMaximized(); +#else + slideShow.show(); +#endif + + return app.exec(); +} diff --git a/examples/slideshow/slideshow.cpp b/examples/slideshow/slideshow.cpp new file mode 100644 index 000000000..5c877de66 --- /dev/null +++ b/examples/slideshow/slideshow.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "slideshow.h" + +#include <qmediaservice.h> +#include <qmediaplaylist.h> +#include <qvideowidget.h> + +#include <QtGui> + +SlideShow::SlideShow(QWidget *parent) + : QMainWindow(parent) + , imageViewer(0) + , playlist(0) + , statusLabel(0) + , countdownLabel(0) + , playAction(0) + , stopAction(0) +{ + imageViewer = new QMediaImageViewer(this); + + connect(imageViewer, SIGNAL(stateChanged(QMediaImageViewer::State)), + this, SLOT(stateChanged(QMediaImageViewer::State))); + connect(imageViewer, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)), + this, SLOT(statusChanged(QMediaImageViewer::MediaStatus))); + connect(imageViewer, SIGNAL(elapsedTimeChanged(int)), this, SLOT(elapsedTimeChanged(int))); + + playlist = new QMediaPlaylist; + imageViewer->bind(playlist); + + connect(playlist, SIGNAL(loaded()), this, SLOT(playlistLoaded())); + connect(playlist, SIGNAL(loadFailed()), this, SLOT(playlistLoadFailed())); + + QVideoWidget *videoWidget = new QVideoWidget; + imageViewer->setVideoOutput(videoWidget); + + menuBar()->addAction(tr("Open Directory..."), this, SLOT(openDirectory())); + menuBar()->addAction(tr("Open Playlist..."), this, SLOT(openPlaylist())); + + toolBar = new QToolBar; + toolBar->setMovable(false); + toolBar->setFloatable(false); + toolBar->setEnabled(false); + + toolBar->addAction( + style()->standardIcon(QStyle::SP_MediaSkipBackward), + tr("Previous"), + playlist, + SLOT(previous())); + stopAction = toolBar->addAction( + style()->standardIcon(QStyle::SP_MediaStop), tr("Stop"), imageViewer, SLOT(stop())); + playAction = toolBar->addAction( + style()->standardIcon(QStyle::SP_MediaPlay), tr("Play"), this, SLOT(play())); + toolBar->addAction( + style()->standardIcon(QStyle::SP_MediaSkipForward), tr("Next"), playlist, SLOT(next())); + + addToolBar(Qt::BottomToolBarArea, toolBar); + + statusLabel = new QLabel(tr("%1 Images").arg(0)); + statusLabel->setAlignment(Qt::AlignCenter); + + countdownLabel = new QLabel; + countdownLabel->setAlignment(Qt::AlignRight); + + statusBar()->addPermanentWidget(statusLabel, 1); + statusBar()->addPermanentWidget(countdownLabel); + + setCentralWidget(videoWidget); +} + +void SlideShow::openPlaylist() +{ + QString path = QFileDialog::getOpenFileName(this); + + if (!path.isEmpty()) { + playlist->clear(); + playlist->load(QUrl::fromLocalFile(path)); + } +} + +void SlideShow::openDirectory() +{ + QString path = QFileDialog::getExistingDirectory(this); + + if (!path.isEmpty()) { + playlist->clear(); + + QDir dir(path); + + foreach (const QString &fileName, dir.entryList(QDir::Files)) + playlist->addMedia(QUrl::fromLocalFile(dir.absoluteFilePath(fileName))); + + statusChanged(imageViewer->mediaStatus()); + + toolBar->setEnabled(playlist->mediaCount() > 0); + } +} + +void SlideShow::play() +{ + switch (imageViewer->state()) { + case QMediaImageViewer::StoppedState: + case QMediaImageViewer::PausedState: + imageViewer->play(); + break; + case QMediaImageViewer::PlayingState: + imageViewer->pause(); + break; + } +} + +void SlideShow::stateChanged(QMediaImageViewer::State state) +{ + switch (state) { + case QMediaImageViewer::StoppedState: + stopAction->setEnabled(false); + playAction->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + break; + case QMediaImageViewer::PlayingState: + stopAction->setEnabled(true); + playAction->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + break; + case QMediaImageViewer::PausedState: + stopAction->setEnabled(true); + playAction->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + break; + } +} + +void SlideShow::statusChanged(QMediaImageViewer::MediaStatus status) +{ + switch (status) { + case QMediaImageViewer::NoMedia: + statusLabel->setText(tr("%1 Images").arg(playlist->mediaCount())); + break; + case QMediaImageViewer::LoadingMedia: + statusLabel->setText(tr("Image %1 of %2\nLoading...") + .arg(playlist->currentIndex()) + .arg(playlist->mediaCount())); + break; + case QMediaImageViewer::LoadedMedia: + statusLabel->setText(tr("Image %1 of %2") + .arg(playlist->currentIndex()) + .arg(playlist->mediaCount())); + break; + case QMediaImageViewer::InvalidMedia: + statusLabel->setText(tr("Image %1 of %2\nInvalid") + .arg(playlist->currentIndex()) + .arg(playlist->mediaCount())); + break; + default: + break; + } +} + +void SlideShow::playlistLoaded() +{ + statusChanged(imageViewer->mediaStatus()); + + toolBar->setEnabled(playlist->mediaCount() > 0); +} + +void SlideShow::playlistLoadFailed() +{ + statusLabel->setText(playlist->errorString()); + + toolBar->setEnabled(false); +} + +void SlideShow::elapsedTimeChanged(int time) +{ + const int remaining = (imageViewer->timeout() - time) / 1000; + + countdownLabel->setText(tr("%1:%2") + .arg(remaining / 60, 2, 10, QLatin1Char('0')) + .arg(remaining % 60, 2, 10, QLatin1Char('0'))); +} diff --git a/examples/slideshow/slideshow.h b/examples/slideshow/slideshow.h new file mode 100644 index 000000000..196ec4723 --- /dev/null +++ b/examples/slideshow/slideshow.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SLIDESHOW_H +#define SLIDESHOW_H + +#include <QMainWindow> +#include <qmediaimageviewer.h> + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QLabel; +class QStackedLayout; + +class QMediaPlaylist; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + +class SlideShow : public QMainWindow +{ + Q_OBJECT +public: + SlideShow(QWidget *parent = 0); + +private slots: + void openPlaylist(); + void openDirectory(); + + void play(); + + void stateChanged(QMediaImageViewer::State state); + void statusChanged(QMediaImageViewer::MediaStatus status); + + void playlistLoaded(); + void playlistLoadFailed(); + + void elapsedTimeChanged(int time); + +private: + QMediaImageViewer *imageViewer; + QMediaPlaylist *playlist; + QLabel *statusLabel; + QLabel *countdownLabel; + QAction *playAction; + QAction *stopAction; + QToolBar *toolBar; +}; + +#endif diff --git a/examples/slideshow/slideshow.pro b/examples/slideshow/slideshow.pro new file mode 100644 index 000000000..76c660a16 --- /dev/null +++ b/examples/slideshow/slideshow.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = slideshow +INCLUDEPATH+=../../src/multimedia +include (../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +HEADERS = \ + slideshow.h + +SOURCES = \ + main.cpp \ + slideshow.cpp + +symbian { + TARGET.CAPABILITY = NetworkServices + TARGET.EPOCHEAPSIZE = 0x20000 0x3000000 +} diff --git a/examples/videographicsitem/main.cpp b/examples/videographicsitem/main.cpp new file mode 100644 index 000000000..46e66d26c --- /dev/null +++ b/examples/videographicsitem/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include <QtGui/QApplication> + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + VideoPlayer player; + player.show(); + + return app.exec(); +} + diff --git a/examples/videographicsitem/videographicsitem.pro b/examples/videographicsitem/videographicsitem.pro new file mode 100644 index 000000000..8461bebe6 --- /dev/null +++ b/examples/videographicsitem/videographicsitem.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/video +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +!symbian:contains(QT_CONFIG, opengl): QT += opengl + +HEADERS += videoplayer.h \ + videoitem.h + +SOURCES += main.cpp \ + videoplayer.cpp \ + videoitem.cpp diff --git a/examples/videographicsitem/videoitem.cpp b/examples/videographicsitem/videoitem.cpp new file mode 100644 index 000000000..a0a71a06b --- /dev/null +++ b/examples/videographicsitem/videoitem.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoitem.h" + +#include <QtGui> +#include <qvideosurfaceformat.h> + +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/videographicsitem/videoitem.h b/examples/videographicsitem/videoitem.h new file mode 100644 index 000000000..85388fb6a --- /dev/null +++ b/examples/videographicsitem/videoitem.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOITEM_H +#define VIDEOITEM_H + +#include <qabstractvideosurface.h> +#include <QtGui/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 + diff --git a/examples/videographicsitem/videoplayer.cpp b/examples/videographicsitem/videoplayer.cpp new file mode 100644 index 000000000..48df7f36b --- /dev/null +++ b/examples/videographicsitem/videoplayer.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" +#include "videoitem.h" + +#include <QtGui> +#include <qvideosurfaceformat.h> + +#if !defined(QT_NO_OPENGL) && !defined(Q_OS_SYMBIAN) +# include <QtOpenGL/QGLWidget> +#endif + +VideoPlayer::VideoPlayer(QWidget *parent, Qt::WindowFlags flags) + : QWidget(parent, flags) + , 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) && !defined(Q_OS_SYMBIAN) + 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/videographicsitem/videoplayer.h b/examples/videographicsitem/videoplayer.h new file mode 100644 index 000000000..e04d54d59 --- /dev/null +++ b/examples/videographicsitem/videoplayer.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOPLAYER_H +#define VIDEOPLAYER_H + +#include <qmediaplayer.h> + +#include <QtGui/QMovie> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QAbstractButton; +class QSlider; +QT_END_NAMESPACE + + +class VideoItem; + +class VideoPlayer : public QWidget +{ + Q_OBJECT +public: + VideoPlayer(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~VideoPlayer(); + + QSize sizeHint() const { return QSize(800, 600); } + +public slots: + void openFile(); + void play(); + +private slots: + void 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 + diff --git a/examples/videowidget/main.cpp b/examples/videowidget/main.cpp new file mode 100644 index 000000000..7165108f0 --- /dev/null +++ b/examples/videowidget/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include <QtGui/QApplication> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + VideoPlayer player; + player.show(); + + return app.exec(); +} diff --git a/examples/videowidget/videoplayer.cpp b/examples/videowidget/videoplayer.cpp new file mode 100644 index 000000000..9276c9b25 --- /dev/null +++ b/examples/videowidget/videoplayer.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videoplayer.h" + +#include "videowidget.h" + +#include <QtGui> +#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/videowidget/videoplayer.h b/examples/videowidget/videoplayer.h new file mode 100644 index 000000000..79334a373 --- /dev/null +++ b/examples/videowidget/videoplayer.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOPLAYER_H +#define VIDEOPLAYER_H + +#include <qmediaplayer.h> + +#include <QtGui/QMovie> +#include <QtGui/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/videowidget/videowidget.cpp b/examples/videowidget/videowidget.cpp new file mode 100644 index 000000000..925b27d9b --- /dev/null +++ b/examples/videowidget/videowidget.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videowidget.h" + +#include "videowidgetsurface.h" + +#include <QtGui> +#include <qvideosurfaceformat.h> + +//! [0] +VideoWidget::VideoWidget(QWidget *parent) + : QWidget(parent) + , surface(0) +{ + setAutoFillBackground(false); + setAttribute(Qt::WA_NoSystemBackground, true); + setAttribute(Qt::WA_PaintOnScreen, true); + + QPalette palette = this->palette(); + palette.setColor(QPalette::Background, Qt::black); + setPalette(palette); + + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + surface = new VideoWidgetSurface(this); +} +//! [0] + +//! [1] +VideoWidget::~VideoWidget() +{ + delete surface; +} +//! [1] + +//! [2] +QSize VideoWidget::sizeHint() const +{ + return surface->surfaceFormat().sizeHint(); +} +//! [2] + + +//! [3] +void VideoWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + if (surface->isActive()) { + const QRect videoRect = surface->videoRect(); + + if (!videoRect.contains(event->rect())) { + QRegion region = event->region(); + region.subtract(videoRect); + + QBrush brush = palette().background(); + + foreach (const QRect &rect, region.rects()) + painter.fillRect(rect, brush); + } + + surface->paint(&painter); + } else { + painter.fillRect(event->rect(), palette().background()); + } +} +//! [3] + +//! [4] +void VideoWidget::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + surface->updateVideoRect(); +} +//! [4] diff --git a/examples/videowidget/videowidget.h b/examples/videowidget/videowidget.h new file mode 100644 index 000000000..3e888cfe3 --- /dev/null +++ b/examples/videowidget/videowidget.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include "videowidgetsurface.h" + +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QAbstractVideoSurface; +QT_END_NAMESPACE + +class VideoWidgetSurface; + +//! [0] +class VideoWidget : public QWidget +{ + Q_OBJECT +public: + VideoWidget(QWidget *parent = 0); + ~VideoWidget(); + + QAbstractVideoSurface *videoSurface() const { return surface; } + + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + +private: + VideoWidgetSurface *surface; +}; +//! [0] + +#endif diff --git a/examples/videowidget/videowidget.pro b/examples/videowidget/videowidget.pro new file mode 100644 index 000000000..1ef79fcaa --- /dev/null +++ b/examples/videowidget/videowidget.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +CONFIG += example + +INCLUDEPATH += ../../src/multimedia ../../src/multimedia/video +include(../mobility_examples.pri) + +CONFIG += mobility +MOBILITY = multimedia + +QMAKE_RPATHDIR += $$DESTDIR + +HEADERS = \ + videoplayer.h \ + videowidget.h \ + videowidgetsurface.h + +SOURCES = \ + main.cpp \ + videoplayer.cpp \ + videowidget.cpp \ + videowidgetsurface.cpp + diff --git a/examples/videowidget/videowidgetsurface.cpp b/examples/videowidget/videowidgetsurface.cpp new file mode 100644 index 000000000..5819f2b25 --- /dev/null +++ b/examples/videowidget/videowidgetsurface.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videowidgetsurface.h" + +#include <QtGui> +#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, QVideoSurfaceFormat *similar) const +{ + Q_UNUSED(similar); + + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + return imageFormat != QImage::Format_Invalid + && !size.isEmpty() + && format.handleType() == QAbstractVideoBuffer::NoHandle; +} +//! [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/videowidget/videowidgetsurface.h b/examples/videowidget/videowidgetsurface.h new file mode 100644 index 000000000..fa3bfce23 --- /dev/null +++ b/examples/videowidget/videowidgetsurface.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOWIDGETSURFACE_H +#define VIDEOWIDGETSURFACE_H + +#include <QtCore/QRect> +#include <QtGui/QImage> +#include <qabstractvideosurface.h> +#include <qvideoframe.h> + +//! [0] +class VideoWidgetSurface : public QAbstractVideoSurface +{ + Q_OBJECT +public: + VideoWidgetSurface(QWidget *widget, QObject *parent = 0); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + bool isFormatSupported(const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + + bool present(const QVideoFrame &frame); + + QRect videoRect() const { return targetRect; } + void updateVideoRect(); + + void paint(QPainter *painter); + +private: + QWidget *widget; + QImage::Format imageFormat; + QRect targetRect; + QSize imageSize; + QRect sourceRect; + QVideoFrame currentFrame; +}; +//! [0] + +#endif |