summaryrefslogtreecommitdiffstats
path: root/src/plugins/qnx
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-20 16:43:44 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-20 16:43:45 +0100
commit0c8be637087a3c7aa038cf72f3a3ed6f7aca0510 (patch)
tree9d55f94a9bcb70b60a5f73439fb1c308cea392ca /src/plugins/qnx
parentf15105a02dc1c6b2b95b8ab0dafd36098840fb0e (diff)
parent2c7e734c8b4decc89820cc946ff72c89aee5cde5 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src/plugins/qnx')
-rw-r--r--src/plugins/qnx/audio/audio.pro22
-rw-r--r--src/plugins/qnx/audio/qnx_audio.json3
-rw-r--r--src/plugins/qnx/audio/qnxaudiodeviceinfo.cpp150
-rw-r--r--src/plugins/qnx/audio/qnxaudioinput.cpp447
-rw-r--r--src/plugins/qnx/audio/qnxaudioinput.h139
-rw-r--r--src/plugins/qnx/audio/qnxaudiooutput.cpp443
-rw-r--r--src/plugins/qnx/audio/qnxaudiooutput.h131
-rw-r--r--src/plugins/qnx/audio/qnxaudioutils.cpp130
-rw-r--r--src/plugins/qnx/bbserviceplugin.cpp112
-rw-r--r--src/plugins/qnx/bbserviceplugin.h77
-rw-r--r--src/plugins/qnx/blackberry_mediaservice.json4
-rw-r--r--src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp89
-rw-r--r--src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h (renamed from src/plugins/qnx/audio/qnxaudiodeviceinfo.h)32
-rw-r--r--src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.cpp66
-rw-r--r--src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.h61
-rw-r--r--src/plugins/qnx/camera/bbcameracapturedestinationcontrol.cpp70
-rw-r--r--src/plugins/qnx/camera/bbcameracapturedestinationcontrol.h66
-rw-r--r--src/plugins/qnx/camera/bbcameracontrol.cpp92
-rw-r--r--src/plugins/qnx/camera/bbcameracontrol.h73
-rw-r--r--src/plugins/qnx/camera/bbcameraexposurecontrol.cpp236
-rw-r--r--src/plugins/qnx/camera/bbcameraexposurecontrol.h73
-rw-r--r--src/plugins/qnx/camera/bbcameraflashcontrol.cpp113
-rw-r--r--src/plugins/qnx/camera/bbcameraflashcontrol.h (renamed from src/plugins/qnx/audio/qnxaudioplugin.h)28
-rw-r--r--src/plugins/qnx/camera/bbcamerafocuscontrol.cpp331
-rw-r--r--src/plugins/qnx/camera/bbcamerafocuscontrol.h79
-rw-r--r--src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp85
-rw-r--r--src/plugins/qnx/camera/bbcameraimagecapturecontrol.h70
-rw-r--r--src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp146
-rw-r--r--src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h67
-rw-r--r--src/plugins/qnx/camera/bbcameralockscontrol.cpp258
-rw-r--r--src/plugins/qnx/camera/bbcameralockscontrol.h86
-rw-r--r--src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp169
-rw-r--r--src/plugins/qnx/camera/bbcameramediarecordercontrol.h76
-rw-r--r--src/plugins/qnx/camera/bbcameraorientationhandler.cpp102
-rw-r--r--src/plugins/qnx/camera/bbcameraorientationhandler.h69
-rw-r--r--src/plugins/qnx/camera/bbcameraservice.cpp141
-rw-r--r--src/plugins/qnx/camera/bbcameraservice.h104
-rw-r--r--src/plugins/qnx/camera/bbcamerasession.cpp1164
-rw-r--r--src/plugins/qnx/camera/bbcamerasession.h217
-rw-r--r--src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp90
-rw-r--r--src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h69
-rw-r--r--src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp249
-rw-r--r--src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h66
-rw-r--r--src/plugins/qnx/camera/bbcamerazoomcontrol.cpp157
-rw-r--r--src/plugins/qnx/camera/bbcamerazoomcontrol.h79
-rw-r--r--src/plugins/qnx/camera/bbimageencodercontrol.cpp (renamed from src/plugins/qnx/audio/qnxaudioplugin.cpp)49
-rw-r--r--src/plugins/qnx/camera/bbimageencodercontrol.h68
-rw-r--r--src/plugins/qnx/camera/bbmediastoragelocation.cpp119
-rw-r--r--src/plugins/qnx/camera/bbmediastoragelocation.h66
-rw-r--r--src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp146
-rw-r--r--src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h79
-rw-r--r--src/plugins/qnx/camera/bbvideorenderercontrol.cpp64
-rw-r--r--src/plugins/qnx/camera/bbvideorenderercontrol.h65
-rw-r--r--src/plugins/qnx/camera/camera.pri53
-rw-r--r--src/plugins/qnx/common/common.pri7
-rw-r--r--src/plugins/qnx/common/windowgrabber.cpp367
-rw-r--r--src/plugins/qnx/common/windowgrabber.h109
-rw-r--r--src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp117
-rw-r--r--src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h66
-rw-r--r--src/plugins/qnx/mediaplayer/mediaplayer.pri31
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp634
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h172
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp149
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h78
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp269
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermetadata.h99
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp170
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h68
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp158
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h84
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererutil.cpp129
-rw-r--r--src/plugins/qnx/mediaplayer/mmrendererutil.h (renamed from src/plugins/qnx/audio/qnxaudioutils.h)19
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp414
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h120
-rw-r--r--src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp199
-rw-r--r--src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h75
-rw-r--r--src/plugins/qnx/neutrino_mediaservice.json4
-rw-r--r--src/plugins/qnx/neutrinoserviceplugin.cpp70
-rw-r--r--src/plugins/qnx/neutrinoserviceplugin.h65
-rw-r--r--src/plugins/qnx/qnx.pro23
80 files changed, 9400 insertions, 1536 deletions
diff --git a/src/plugins/qnx/audio/audio.pro b/src/plugins/qnx/audio/audio.pro
deleted file mode 100644
index 35ddf73de..000000000
--- a/src/plugins/qnx/audio/audio.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-TARGET = qtmedia_qnx_audio
-QT += multimedia-private
-CONFIG += no_private_qt_headers_warning
-
-PLUGIN_TYPE = audio
-load(qt_plugin)
-
-LIBS += -lasound
-
-HEADERS += qnxaudioplugin.h \
- qnxaudiodeviceinfo.h \
- qnxaudioinput.h \
- qnxaudiooutput.h \
- qnxaudioutils.h
-
-SOURCES += qnxaudioplugin.cpp \
- qnxaudiodeviceinfo.cpp \
- qnxaudioinput.cpp \
- qnxaudiooutput.cpp \
- qnxaudioutils.cpp
-
-OTHER_FILES += qnx_audio.json
diff --git a/src/plugins/qnx/audio/qnx_audio.json b/src/plugins/qnx/audio/qnx_audio.json
deleted file mode 100644
index a31d52107..000000000
--- a/src/plugins/qnx/audio/qnx_audio.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": ["default"]
-}
diff --git a/src/plugins/qnx/audio/qnxaudiodeviceinfo.cpp b/src/plugins/qnx/audio/qnxaudiodeviceinfo.cpp
deleted file mode 100644
index ce8083573..000000000
--- a/src/plugins/qnx/audio/qnxaudiodeviceinfo.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qnxaudiodeviceinfo.h"
-
-#include "qnxaudioutils.h"
-
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QnxAudioDeviceInfo::QnxAudioDeviceInfo(const QString &deviceName, QAudio::Mode mode)
- : m_name(deviceName),
- m_mode(mode)
-{
-}
-
-QnxAudioDeviceInfo::~QnxAudioDeviceInfo()
-{
-}
-
-QAudioFormat QnxAudioDeviceInfo::preferredFormat() const
-{
- QAudioFormat format;
- if (m_mode == QAudio::AudioOutput) {
- format.setSampleRate(44100);
- format.setChannelCount(2);
- format.setByteOrder(QAudioFormat::LittleEndian);
- format.setSampleType(QAudioFormat::SignedInt);
- format.setSampleSize(16);
- format.setCodec(QLatin1String("audio/pcm"));
- } else {
- format.setSampleRate(8000);
- format.setChannelCount(1);
- format.setSampleType(QAudioFormat::UnSignedInt);
- format.setSampleSize(8);
- format.setCodec(QLatin1String("audio/pcm"));
- if (!isFormatSupported(format)) {
- format.setChannelCount(2);
- format.setSampleSize(16);
- format.setSampleType(QAudioFormat::SignedInt);
- }
- }
- return format;
-}
-
-bool QnxAudioDeviceInfo::isFormatSupported(const QAudioFormat &format) const
-{
- if (!format.codec().startsWith(QLatin1String("audio/pcm")))
- return false;
-
- const int pcmMode = (m_mode == QAudio::AudioOutput) ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE;
- snd_pcm_t *handle;
-
- int card = 0;
- int device = 0;
- if (snd_pcm_open_preferred(&handle, &card, &device, pcmMode) < 0)
- return false;
-
- snd_pcm_channel_info_t info;
- memset (&info, 0, sizeof(info));
- info.channel = (m_mode == QAudio::AudioOutput) ? SND_PCM_CHANNEL_PLAYBACK : SND_PCM_CHANNEL_CAPTURE;
-
- if (snd_pcm_plugin_info(handle, &info) < 0) {
- qWarning("QAudioDeviceInfo: couldn't get channel info");
- snd_pcm_close(handle);
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(format, m_mode, info.max_fragment_size);
- const int errorCode = snd_pcm_plugin_params(handle, &params);
- snd_pcm_close(handle);
-
- return errorCode == 0;
-}
-
-QString QnxAudioDeviceInfo::deviceName() const
-{
- return m_name;
-}
-
-QStringList QnxAudioDeviceInfo::supportedCodecs()
-{
- return QStringList() << QLatin1String("audio/pcm");
-}
-
-QList<int> QnxAudioDeviceInfo::supportedSampleRates()
-{
- return QList<int>() << 8000 << 11025 << 22050 << 44100 << 48000;
-}
-
-QList<int> QnxAudioDeviceInfo::supportedChannelCounts()
-{
- return QList<int>() << 1 << 2;
-}
-
-QList<int> QnxAudioDeviceInfo::supportedSampleSizes()
-{
- return QList<int>() << 8 << 16 << 32;
-}
-
-QList<QAudioFormat::Endian> QnxAudioDeviceInfo::supportedByteOrders()
-{
- return QList<QAudioFormat::Endian>() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian;
-}
-
-QList<QAudioFormat::SampleType> QnxAudioDeviceInfo::supportedSampleTypes()
-{
- return QList<QAudioFormat::SampleType>() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudioinput.cpp b/src/plugins/qnx/audio/qnxaudioinput.cpp
deleted file mode 100644
index eb8064598..000000000
--- a/src/plugins/qnx/audio/qnxaudioinput.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qnxaudioinput.h"
-
-#include "qnxaudioutils.h"
-
-#include <private/qaudiohelpers_p.h>
-
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-QnxAudioInput::QnxAudioInput()
- : m_audioSource(0)
- , m_pcmHandle(0)
- , m_pcmNotifier(0)
- , m_error(QAudio::NoError)
- , m_state(QAudio::StoppedState)
- , m_bytesRead(0)
- , m_elapsedTimeOffset(0)
- , m_totalTimeValue(0)
- , m_volume(qreal(1.0f))
- , m_bytesAvailable(0)
- , m_bufferSize(0)
- , m_periodSize(0)
- , m_intervalTime(1000)
- , m_pullMode(true)
-{
-}
-
-QnxAudioInput::~QnxAudioInput()
-{
- close();
-}
-
-void QnxAudioInput::start(QIODevice *device)
-{
- if (m_state != QAudio::StoppedState)
- close();
-
- if (!m_pullMode && m_audioSource)
- delete m_audioSource;
-
- m_pullMode = true;
- m_audioSource = device;
-
- if (open()) {
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- } else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-}
-
-QIODevice *QnxAudioInput::start()
-{
- if (m_state != QAudio::StoppedState)
- close();
-
- if (!m_pullMode && m_audioSource)
- delete m_audioSource;
-
- m_pullMode = false;
- m_audioSource = new InputPrivate(this);
- m_audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- if (open()) {
- setError(QAudio::NoError);
- setState(QAudio::IdleState);
- } else {
- delete m_audioSource;
- m_audioSource = 0;
-
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-
- return m_audioSource;
-}
-
-void QnxAudioInput::stop()
-{
- if (m_state == QAudio::StoppedState)
- return;
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
- close();
-}
-
-void QnxAudioInput::reset()
-{
- stop();
- m_bytesAvailable = 0;
-}
-
-void QnxAudioInput::suspend()
-{
- if (m_pcmNotifier)
- m_pcmNotifier->setEnabled(false);
-
- setState(QAudio::SuspendedState);
-}
-
-void QnxAudioInput::resume()
-{
- if (m_pcmNotifier)
- m_pcmNotifier->setEnabled(true);
-
- if (m_pullMode) {
- setState(QAudio::ActiveState);
- } else {
- setState(QAudio::IdleState);
- }
-}
-
-int QnxAudioInput::bytesReady() const
-{
- return qMax(m_bytesAvailable, 0);
-}
-
-int QnxAudioInput::periodSize() const
-{
- return m_periodSize;
-}
-
-void QnxAudioInput::setBufferSize(int bufferSize)
-{
- m_bufferSize = bufferSize;
-}
-
-int QnxAudioInput::bufferSize() const
-{
- return m_bufferSize;
-}
-
-void QnxAudioInput::setNotifyInterval(int milliSeconds)
-{
- m_intervalTime = qMax(0, milliSeconds);
-}
-
-int QnxAudioInput::notifyInterval() const
-{
- return m_intervalTime;
-}
-
-qint64 QnxAudioInput::processedUSecs() const
-{
- return qint64(1000000) * m_format.framesForBytes(m_bytesRead) / m_format.sampleRate();
-}
-
-qint64 QnxAudioInput::elapsedUSecs() const
-{
- if (m_state == QAudio::StoppedState)
- return 0;
-
- return m_clockStamp.elapsed() * 1000;
-}
-
-QAudio::Error QnxAudioInput::error() const
-{
- return m_error;
-}
-
-QAudio::State QnxAudioInput::state() const
-{
- return m_state;
-}
-
-void QnxAudioInput::setFormat(const QAudioFormat &format)
-{
- if (m_state == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QnxAudioInput::format() const
-{
- return m_format;
-}
-
-void QnxAudioInput::setVolume(qreal volume)
-{
- m_volume = qBound(qreal(0.0), volume, qreal(1.0));
-}
-
-qreal QnxAudioInput::volume() const
-{
- return m_volume;
-}
-
-void QnxAudioInput::userFeed()
-{
- if (m_state == QAudio::StoppedState || m_state == QAudio::SuspendedState)
- return;
-
- deviceReady();
-}
-
-bool QnxAudioInput::deviceReady()
-{
- if (m_pullMode) {
- // reads some audio data and writes it to QIODevice
- read(0, 0);
- } else {
- m_bytesAvailable = m_periodSize;
-
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- if (m_audioSource != 0) {
- InputPrivate *input = qobject_cast<InputPrivate*>(m_audioSource);
- input->trigger();
- }
- }
-
- if (m_state != QAudio::ActiveState)
- return true;
-
- if (m_intervalTime && (m_timeStamp.elapsed() + m_elapsedTimeOffset) > m_intervalTime) {
- emit notify();
- m_elapsedTimeOffset = m_timeStamp.elapsed() + m_elapsedTimeOffset - m_intervalTime;
- m_timeStamp.restart();
- }
-
- return true;
-}
-
-bool QnxAudioInput::open()
-{
- if (!m_format.isValid() || m_format.sampleRate() <= 0) {
- if (!m_format.isValid())
- qWarning("QnxAudioInput: open error, invalid format.");
- else
- qWarning("QnxAudioInput: open error, invalid sample rate (%d).", m_format.sampleRate());
-
- return false;
- }
-
- int errorCode = 0;
-
- int card = 0;
- int device = 0;
- if ((errorCode = snd_pcm_open_preferred(&m_pcmHandle, &card, &device, SND_PCM_OPEN_CAPTURE)) < 0) {
- qWarning("QnxAudioInput: open error, couldn't open card (0x%x)", -errorCode);
- return false;
- }
-
- // Necessary so that bytesFree() which uses the "free" member of the status struct works
- snd_pcm_plugin_set_disable(m_pcmHandle, PLUGIN_DISABLE_MMAP);
-
- snd_pcm_channel_info_t info;
- memset(&info, 0, sizeof(info));
- info.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_info(m_pcmHandle, &info)) < 0) {
- qWarning("QnxAudioInput: open error, couldn't get channel info (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format, QAudio::AudioInput, info.max_fragment_size);
-
- if ((errorCode = snd_pcm_plugin_params(m_pcmHandle, &params)) < 0) {
- qWarning("QnxAudioInput: open error, couldn't set channel params (0x%x)", -errorCode);
- close();
- return false;
- }
-
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
- qWarning("QnxAudioInput: open error, couldn't prepare channel (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_setup_t setup;
-
- memset(&setup, 0, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_setup(m_pcmHandle, &setup)) < 0) {
- qWarning("QnxAudioInput: open error, couldn't get channel setup (0x%x)", -errorCode);
- close();
- return false;
- }
-
- m_periodSize = qMin(2048, setup.buf.block.frag_size);
-
- m_clockStamp.restart();
- m_timeStamp.restart();
- m_elapsedTimeOffset = 0;
- m_totalTimeValue = 0;
- m_bytesRead = 0;
-
- m_pcmNotifier = new QSocketNotifier(snd_pcm_file_descriptor(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE),
- QSocketNotifier::Read, this);
- connect(m_pcmNotifier, SIGNAL(activated(int)), SLOT(userFeed()));
-
- return true;
-}
-
-void QnxAudioInput::close()
-{
- if (m_pcmHandle)
- snd_pcm_plugin_flush(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE);
-
- if (m_pcmNotifier) {
- delete m_pcmNotifier;
- m_pcmNotifier = 0;
- }
-
- if (m_pcmHandle) {
- snd_pcm_close(m_pcmHandle);
- m_pcmHandle = 0;
- }
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = 0;
- }
-}
-
-qint64 QnxAudioInput::read(char *data, qint64 len)
-{
- int errorCode = 0;
- QByteArray tempBuffer(m_periodSize, 0);
-
- const int actualRead = snd_pcm_plugin_read(m_pcmHandle, tempBuffer.data(), m_periodSize);
- if (actualRead < 1) {
- snd_pcm_channel_status_t status;
- memset(&status, 0, sizeof(status));
- status.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_status(m_pcmHandle, &status)) < 0) {
- qWarning("QnxAudioInput: read error, couldn't get plugin status (0x%x)", -errorCode);
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return -1;
- }
-
- if (status.status == SND_PCM_STATUS_READY
- || status.status == SND_PCM_STATUS_OVERRUN) {
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
- qWarning("QnxAudioInput: read error, couldn't prepare plugin (0x%x)", -errorCode);
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return -1;
- }
- }
- } else {
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- }
-
- if (m_volume < 1.0f)
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, tempBuffer.data(), tempBuffer.data(), actualRead);
-
- m_bytesRead += actualRead;
-
- if (m_pullMode) {
- m_audioSource->write(tempBuffer.data(), actualRead);
- } else {
- memcpy(data, tempBuffer.data(), qMin(static_cast<qint64>(actualRead), len));
- }
-
- m_bytesAvailable = 0;
-
- return actualRead;
-}
-
-void QnxAudioInput::setError(QAudio::Error error)
-{
- if (m_error == error)
- return;
-
- m_error = error;
- emit errorChanged(m_error);
-}
-
-void QnxAudioInput::setState(QAudio::State state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
- emit stateChanged(m_state);
-}
-
-InputPrivate::InputPrivate(QnxAudioInput *audio)
- : m_audioDevice(audio)
-{
-}
-
-qint64 InputPrivate::readData(char *data, qint64 len)
-{
- return m_audioDevice->read(data, len);
-}
-
-qint64 InputPrivate::writeData(const char *data, qint64 len)
-{
- Q_UNUSED(data)
- Q_UNUSED(len)
- return 0;
-}
-
-void InputPrivate::trigger()
-{
- emit readyRead();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudioinput.h b/src/plugins/qnx/audio/qnxaudioinput.h
deleted file mode 100644
index 3084b1de3..000000000
--- a/src/plugins/qnx/audio/qnxaudioinput.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QNXAUDIOINPUT_H
-#define QNXAUDIOINPUT_H
-
-#include "qaudiosystem.h"
-
-#include <QSocketNotifier>
-#include <QTime>
-#include <QTimer>
-
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-class QnxAudioInput : public QAbstractAudioInput
-{
- Q_OBJECT
-
-public:
- QnxAudioInput();
- ~QnxAudioInput();
-
- void start(QIODevice*) Q_DECL_OVERRIDE;
- QIODevice* start() Q_DECL_OVERRIDE;
- void stop() Q_DECL_OVERRIDE;
- void reset() Q_DECL_OVERRIDE;
- void suspend() Q_DECL_OVERRIDE;
- void resume() Q_DECL_OVERRIDE;
- int bytesReady() const Q_DECL_OVERRIDE;
- int periodSize() const Q_DECL_OVERRIDE;
- void setBufferSize(int ) Q_DECL_OVERRIDE;
- int bufferSize() const Q_DECL_OVERRIDE;
- void setNotifyInterval(int ) Q_DECL_OVERRIDE;
- int notifyInterval() const Q_DECL_OVERRIDE;
- qint64 processedUSecs() const Q_DECL_OVERRIDE;
- qint64 elapsedUSecs() const Q_DECL_OVERRIDE;
- QAudio::Error error() const Q_DECL_OVERRIDE;
- QAudio::State state() const Q_DECL_OVERRIDE;
- void setFormat(const QAudioFormat&) Q_DECL_OVERRIDE;
- QAudioFormat format() const Q_DECL_OVERRIDE;
- void setVolume(qreal) Q_DECL_OVERRIDE;
- qreal volume() const Q_DECL_OVERRIDE;
-
-private slots:
- void userFeed();
- bool deviceReady();
-
-private:
- friend class InputPrivate;
-
- bool open();
- void close();
- qint64 read(char *data, qint64 len);
- void setError(QAudio::Error error);
- void setState(QAudio::State state);
-
- QTime m_timeStamp;
- QTime m_clockStamp;
- QAudioFormat m_format;
-
- QIODevice *m_audioSource;
- snd_pcm_t *m_pcmHandle;
- QSocketNotifier *m_pcmNotifier;
-
- QAudio::Error m_error;
- QAudio::State m_state;
-
- qint64 m_bytesRead;
- qint64 m_elapsedTimeOffset;
- qint64 m_totalTimeValue;
-
- qreal m_volume;
-
- int m_bytesAvailable;
- int m_bufferSize;
- int m_periodSize;
- int m_intervalTime;
-
- bool m_pullMode;
-};
-
-class InputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- InputPrivate(QnxAudioInput *audio);
-
- qint64 readData(char *data, qint64 len) Q_DECL_OVERRIDE;
- qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
-
- void trigger();
-
-private:
- QnxAudioInput *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qnx/audio/qnxaudiooutput.cpp b/src/plugins/qnx/audio/qnxaudiooutput.cpp
deleted file mode 100644
index 4a82e93bb..000000000
--- a/src/plugins/qnx/audio/qnxaudiooutput.cpp
+++ /dev/null
@@ -1,443 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qnxaudiooutput.h"
-
-#include "qnxaudioutils.h"
-
-#include <private/qaudiohelpers_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QnxAudioOutput::QnxAudioOutput()
- : m_source(0),
- m_pushSource(false),
- m_notifyInterval(1000),
- m_error(QAudio::NoError),
- m_state(QAudio::StoppedState),
- m_volume(1.0),
- m_periodSize(0),
- m_pcmHandle(0),
- m_bytesWritten(0),
- m_intervalOffset(0)
-{
- m_timer.setSingleShot(false);
- m_timer.setInterval(20);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(pullData()));
-}
-
-QnxAudioOutput::~QnxAudioOutput()
-{
- stop();
-}
-
-void QnxAudioOutput::start(QIODevice *source)
-{
- if (m_state != QAudio::StoppedState)
- stop();
-
- m_error = QAudio::NoError;
- m_source = source;
- m_pushSource = false;
-
- if (open()) {
- setState(QAudio::ActiveState);
- m_timer.start();
- } else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-}
-
-QIODevice *QnxAudioOutput::start()
-{
- if (m_state != QAudio::StoppedState)
- stop();
-
- m_error = QAudio::NoError;
- m_source = new QnxPushIODevice(this);
- m_source->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- m_pushSource = true;
-
- if (open())
- setState(QAudio::IdleState);
- else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-
- return m_source;
-}
-
-void QnxAudioOutput::stop()
-{
- if (m_state == QAudio::StoppedState)
- return;
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
- close();
-}
-
-void QnxAudioOutput::reset()
-{
- if (m_pcmHandle)
- snd_pcm_playback_drain(m_pcmHandle);
- stop();
-}
-
-void QnxAudioOutput::suspend()
-{
- m_timer.stop();
- setState(QAudio::SuspendedState);
-}
-
-void QnxAudioOutput::resume()
-{
- if (m_pushSource)
- setState(QAudio::IdleState);
- else {
- setState(QAudio::ActiveState);
- m_timer.start();
- }
-}
-
-int QnxAudioOutput::bytesFree() const
-{
- if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState)
- return 0;
-
- snd_pcm_channel_status_t status;
- status.channel = SND_PCM_CHANNEL_PLAYBACK;
- const int errorCode = snd_pcm_plugin_status(m_pcmHandle, &status);
-
- if (errorCode)
- return 0;
- else
- return status.free;
-}
-
-int QnxAudioOutput::periodSize() const
-{
- return m_periodSize;
-}
-
-void QnxAudioOutput::setNotifyInterval(int ms)
-{
- m_notifyInterval = ms;
-}
-
-int QnxAudioOutput::notifyInterval() const
-{
- return m_notifyInterval;
-}
-
-qint64 QnxAudioOutput::processedUSecs() const
-{
- return qint64(1000000) * m_format.framesForBytes(m_bytesWritten) / m_format.sampleRate();
-}
-
-qint64 QnxAudioOutput::elapsedUSecs() const
-{
- if (m_state == QAudio::StoppedState)
- return 0;
- else
- return m_startTimeStamp.elapsed() * 1000;
-}
-
-QAudio::Error QnxAudioOutput::error() const
-{
- return m_error;
-}
-
-QAudio::State QnxAudioOutput::state() const
-{
- return m_state;
-}
-
-void QnxAudioOutput::setFormat(const QAudioFormat &format)
-{
- if (m_state == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QnxAudioOutput::format() const
-{
- return m_format;
-}
-
-void QnxAudioOutput::setVolume(qreal volume)
-{
- m_volume = qBound(qreal(0.0), volume, qreal(1.0));
-}
-
-qreal QnxAudioOutput::volume() const
-{
- return m_volume;
-}
-
-void QnxAudioOutput::pullData()
-{
- if (m_state == QAudio::StoppedState || m_state == QAudio::SuspendedState)
- return;
-
- const int bytesAvailable = bytesFree();
- const int frames = m_format.framesForBytes(bytesAvailable);
-
- if (frames == 0 || bytesAvailable < periodSize())
- return;
-
- const int bytesRequested = m_format.bytesForFrames(frames);
-
- char buffer[bytesRequested];
- const int bytesRead = m_source->read(buffer, bytesRequested);
-
- // reading can take a while and stream may have been stopped
- if (!m_pcmHandle)
- return;
-
- if (bytesRead > 0) {
- // Got some data to output
- if (m_state != QAudio::ActiveState)
- return;
-
- const qint64 bytesWritten = write(buffer, bytesRead);
- if (bytesWritten != bytesRead)
- m_source->seek(m_source->pos()-(bytesRead-bytesWritten));
-
- } else {
- // We're done
- close();
- if (bytesRead != 0)
- setError(QAudio::IOError);
- setState(QAudio::StoppedState);
- }
-
- if (m_state != QAudio::ActiveState)
- return;
-
- if (m_notifyInterval > 0 && (m_intervalTimeStamp.elapsed() + m_intervalOffset) > m_notifyInterval) {
- emit notify();
- m_intervalOffset = m_intervalTimeStamp.elapsed() + m_intervalOffset - m_notifyInterval;
- m_intervalTimeStamp.restart();
- }
-}
-
-bool QnxAudioOutput::open()
-{
- if (!m_format.isValid() || m_format.sampleRate() <= 0) {
- if (!m_format.isValid())
- qWarning("QnxAudioOutput: open error, invalid format.");
- else
- qWarning("QnxAudioOutput: open error, invalid sample rate (%d).", m_format.sampleRate());
-
- return false;
- }
-
- int errorCode = 0;
-
- int card = 0;
- int device = 0;
- if ((errorCode = snd_pcm_open_preferred(&m_pcmHandle, &card, &device, SND_PCM_OPEN_PLAYBACK)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't open card (0x%x)", -errorCode);
- return false;
- }
-
- if ((errorCode = snd_pcm_nonblock_mode(m_pcmHandle, 0)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't set non block mode (0x%x)", -errorCode);
- close();
- return false;
- }
-
- // Necessary so that bytesFree() which uses the "free" member of the status struct works
- snd_pcm_plugin_set_disable(m_pcmHandle, PLUGIN_DISABLE_MMAP);
-
- snd_pcm_channel_info_t info;
- memset(&info, 0, sizeof(info));
- info.channel = SND_PCM_CHANNEL_PLAYBACK;
- if ((errorCode = snd_pcm_plugin_info(m_pcmHandle, &info)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't get channel info (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format, QAudio::AudioOutput, info.max_fragment_size);
-
- if ((errorCode = snd_pcm_plugin_params(m_pcmHandle, &params)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't set channel params (0x%x)", -errorCode);
- close();
- return false;
- }
-
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't prepare channel (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_setup_t setup;
- memset(&setup, 0, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_PLAYBACK;
- if ((errorCode = snd_pcm_plugin_setup(m_pcmHandle, &setup)) < 0) {
- qWarning("QnxAudioOutput: open error, couldn't get channel setup (0x%x)", -errorCode);
- close();
- return false;
- }
-
- m_periodSize = qMin(2048, setup.buf.block.frag_size);
- m_startTimeStamp.restart();
- m_intervalTimeStamp.restart();
- m_intervalOffset = 0;
- m_bytesWritten = 0;
-
- return true;
-}
-
-void QnxAudioOutput::close()
-{
- m_timer.stop();
-
- if (m_pcmHandle) {
- snd_pcm_plugin_flush(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK);
- snd_pcm_close(m_pcmHandle);
- m_pcmHandle = 0;
- }
-
- if (m_pushSource) {
- delete m_source;
- m_source = 0;
- }
-}
-
-void QnxAudioOutput::setError(QAudio::Error error)
-{
- if (m_error != error) {
- m_error = error;
- emit errorChanged(error);
- }
-}
-
-void QnxAudioOutput::setState(QAudio::State state)
-{
- if (m_state != state) {
- m_state = state;
- emit stateChanged(state);
- }
-}
-
-qint64 QnxAudioOutput::write(const char *data, qint64 len)
-{
- if (!m_pcmHandle)
- return 0;
-
- // Make sure we're writing (N * frame) worth of bytes
- const int size = m_format.bytesForFrames(qBound(qint64(0), qint64(bytesFree()), len) / m_format.bytesPerFrame());
-
- if (size == 0)
- return 0;
-
- int written = 0;
-
- if (m_volume < 1.0f) {
- char out[size];
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, out, size);
- written = snd_pcm_plugin_write(m_pcmHandle, out, size);
- } else {
- written = snd_pcm_plugin_write(m_pcmHandle, data, size);
- }
-
- if (written > 0) {
- m_bytesWritten += written;
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- return written;
- } else {
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return 0;
- }
-}
-
-QnxPushIODevice::QnxPushIODevice(QnxAudioOutput *output)
- : QIODevice(output),
- m_output(output)
-{
-}
-
-QnxPushIODevice::~QnxPushIODevice()
-{
-}
-
-qint64 QnxPushIODevice::readData(char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-qint64 QnxPushIODevice::writeData(const char *data, qint64 len)
-{
- int retry = 0;
- qint64 written = 0;
-
- if (m_output->state() == QAudio::ActiveState
- || m_output->state() == QAudio::IdleState) {
- while (written < len) {
- const int writeSize = m_output->write(data + written, len - written);
-
- if (writeSize <= 0) {
- retry++;
- if (retry > 10)
- return written;
- else
- continue;
- }
-
- retry = 0;
- written += writeSize;
- }
- }
-
- return written;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudiooutput.h b/src/plugins/qnx/audio/qnxaudiooutput.h
deleted file mode 100644
index 77c15e47a..000000000
--- a/src/plugins/qnx/audio/qnxaudiooutput.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QNXAUDIOOUTPUT_H
-#define QNXAUDIOOUTPUT_H
-
-#include "qaudiosystem.h"
-
-#include <QTime>
-#include <QTimer>
-
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-class QnxPushIODevice;
-
-class QnxAudioOutput : public QAbstractAudioOutput
-{
- Q_OBJECT
-
-public:
- QnxAudioOutput();
- ~QnxAudioOutput();
-
- void start(QIODevice *source) Q_DECL_OVERRIDE;
- QIODevice *start() Q_DECL_OVERRIDE;
- void stop() Q_DECL_OVERRIDE;
- void reset() Q_DECL_OVERRIDE;
- void suspend() Q_DECL_OVERRIDE;
- void resume() Q_DECL_OVERRIDE;
- int bytesFree() const Q_DECL_OVERRIDE;
- int periodSize() const Q_DECL_OVERRIDE;
- void setBufferSize(int) Q_DECL_OVERRIDE {}
- int bufferSize() const Q_DECL_OVERRIDE { return 0; }
- void setNotifyInterval(int ms) Q_DECL_OVERRIDE;
- int notifyInterval() const Q_DECL_OVERRIDE;
- qint64 processedUSecs() const Q_DECL_OVERRIDE;
- qint64 elapsedUSecs() const Q_DECL_OVERRIDE;
- QAudio::Error error() const Q_DECL_OVERRIDE;
- QAudio::State state() const Q_DECL_OVERRIDE;
- void setFormat(const QAudioFormat &format) Q_DECL_OVERRIDE;
- QAudioFormat format() const Q_DECL_OVERRIDE;
- void setVolume(qreal volume) Q_DECL_OVERRIDE;
- qreal volume() const Q_DECL_OVERRIDE;
-
-private slots:
- void pullData();
-
-private:
- bool open();
- void close();
- void setError(QAudio::Error error);
- void setState(QAudio::State state);
-
- friend class QnxPushIODevice;
- qint64 write(const char *data, qint64 len);
-
- QIODevice *m_source;
- bool m_pushSource;
- QTimer m_timer;
-
- int m_notifyInterval;
- QAudio::Error m_error;
- QAudio::State m_state;
- QAudioFormat m_format;
- qreal m_volume;
- int m_periodSize;
-
- snd_pcm_t *m_pcmHandle;
- qint64 m_bytesWritten;
- QTime m_startTimeStamp;
- QTime m_intervalTimeStamp;
- qint64 m_intervalOffset;
-};
-
-class QnxPushIODevice : public QIODevice
-{
- Q_OBJECT
-public:
- explicit QnxPushIODevice(QnxAudioOutput *output);
- ~QnxPushIODevice();
-
- qint64 readData(char *data, qint64 len);
- qint64 writeData(const char *data, qint64 len);
-
-private:
- QnxAudioOutput *m_output;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qnx/audio/qnxaudioutils.cpp b/src/plugins/qnx/audio/qnxaudioutils.cpp
deleted file mode 100644
index d6400c2b1..000000000
--- a/src/plugins/qnx/audio/qnxaudioutils.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qnxaudioutils.h"
-
-QT_BEGIN_NAMESPACE
-
-snd_pcm_channel_params_t QnxAudioUtils::formatToChannelParams(const QAudioFormat &format, QAudio::Mode mode, int fragmentSize)
-{
- snd_pcm_channel_params_t params;
- memset(&params, 0, sizeof(params));
- params.channel = (mode == QAudio::AudioOutput) ? SND_PCM_CHANNEL_PLAYBACK : SND_PCM_CHANNEL_CAPTURE;
- params.mode = SND_PCM_MODE_BLOCK;
- params.start_mode = SND_PCM_START_DATA;
- params.stop_mode = SND_PCM_STOP_ROLLOVER;
- params.buf.block.frag_size = fragmentSize;
- params.buf.block.frags_min = 1;
- params.buf.block.frags_max = 1;
- strcpy(params.sw_mixer_subchn_name, "QAudio Channel");
-
- params.format.interleave = 1;
- params.format.rate = format.sampleRate();
- params.format.voices = format.channelCount();
-
- switch (format.sampleSize()) {
- case 8:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- params.format.format = SND_PCM_SFMT_S8;
- break;
- case QAudioFormat::UnSignedInt:
- params.format.format = SND_PCM_SFMT_U8;
- break;
- default:
- break;
- }
- break;
-
- case 16:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_S16_LE;
- } else {
- params.format.format = SND_PCM_SFMT_S16_BE;
- }
- break;
- case QAudioFormat::UnSignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_U16_LE;
- } else {
- params.format.format = SND_PCM_SFMT_U16_BE;
- }
- break;
- default:
- break;
- }
- break;
-
- case 32:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_S32_LE;
- } else {
- params.format.format = SND_PCM_SFMT_S32_BE;
- }
- break;
- case QAudioFormat::UnSignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_U32_LE;
- } else {
- params.format.format = SND_PCM_SFMT_U32_BE;
- }
- break;
- case QAudioFormat::Float:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_FLOAT_LE;
- } else {
- params.format.format = SND_PCM_SFMT_FLOAT_BE;
- }
- break;
- default:
- break;
- }
- break;
- }
-
- return params;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/qnx/bbserviceplugin.cpp b/src/plugins/qnx/bbserviceplugin.cpp
new file mode 100644
index 000000000..59be46453
--- /dev/null
+++ b/src/plugins/qnx/bbserviceplugin.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbserviceplugin.h"
+
+#include "bbcameraservice.h"
+#include "bbvideodeviceselectorcontrol.h"
+#include "mmrenderermediaplayerservice.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbServicePlugin::BbServicePlugin()
+{
+}
+
+QMediaService *BbServicePlugin::create(const QString &key)
+{
+ if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+ return new BbCameraService();
+
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
+ return new MmRendererMediaPlayerService();
+
+ return 0;
+}
+
+void BbServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+QMediaServiceProviderHint::Features BbServicePlugin::supportedFeatures(const QByteArray &service) const
+{
+ Q_UNUSED(service)
+ return QMediaServiceProviderHint::Features();
+}
+
+QList<QByteArray> BbServicePlugin::devices(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_CAMERA) {
+ if (m_cameraDevices.isEmpty())
+ updateDevices();
+
+ return m_cameraDevices;
+ }
+
+ return QList<QByteArray>();
+}
+
+QString BbServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+{
+ if (service == Q_MEDIASERVICE_CAMERA) {
+ if (m_cameraDevices.isEmpty())
+ updateDevices();
+
+ for (int i = 0; i < m_cameraDevices.count(); i++)
+ if (m_cameraDevices[i] == device)
+ return m_cameraDescriptions[i];
+ }
+
+ return QString();
+}
+
+void BbServicePlugin::updateDevices() const
+{
+ BbVideoDeviceSelectorControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
+
+ if (m_cameraDevices.isEmpty()) {
+ qWarning() << "No camera devices found";
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/bbserviceplugin.h b/src/plugins/qnx/bbserviceplugin.h
new file mode 100644
index 000000000..62fc4a0df
--- /dev/null
+++ b/src/plugins/qnx/bbserviceplugin.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBRSERVICEPLUGIN_H
+#define BBRSERVICEPLUGIN_H
+
+#include <qmediaserviceproviderplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbServicePlugin
+ : public QMediaServiceProviderPlugin,
+ public QMediaServiceSupportedDevicesInterface,
+ public QMediaServiceFeaturesInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
+ Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "blackberry_mediaservice.json")
+public:
+ BbServicePlugin();
+
+ QMediaService *create(const QString &key) Q_DECL_OVERRIDE;
+ void release(QMediaService *service) Q_DECL_OVERRIDE;
+ QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
+
+ QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
+ QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
+ QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) Q_DECL_OVERRIDE;
+
+private:
+ void updateDevices() const;
+
+ mutable QList<QByteArray> m_cameraDevices;
+ mutable QStringList m_cameraDescriptions;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/blackberry_mediaservice.json b/src/plugins/qnx/blackberry_mediaservice.json
new file mode 100644
index 000000000..2a59cc770
--- /dev/null
+++ b/src/plugins/qnx/blackberry_mediaservice.json
@@ -0,0 +1,4 @@
+{
+ "Keys": ["blackberrymultimedia"],
+ "Services": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer"]
+}
diff --git a/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp
new file mode 100644
index 000000000..2ff800a0f
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraaudioencodersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraAudioEncoderSettingsControl::BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent)
+ : QAudioEncoderSettingsControl(parent)
+ , m_session(session)
+{
+}
+
+QStringList BbCameraAudioEncoderSettingsControl::supportedAudioCodecs() const
+{
+ return QStringList() << QLatin1String("none") << QLatin1String("aac") << QLatin1String("raw");
+}
+
+QString BbCameraAudioEncoderSettingsControl::codecDescription(const QString &codecName) const
+{
+ if (codecName == QLatin1String("none"))
+ return tr("No compression");
+ else if (codecName == QLatin1String("aac"))
+ return tr("AAC compression");
+ else if (codecName == QLatin1String("raw"))
+ return tr("PCM uncompressed");
+
+ return QString();
+}
+
+QList<int> BbCameraAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
+{
+ Q_UNUSED(settings);
+ Q_UNUSED(continuous);
+
+ // no API provided by BB10 yet
+ return QList<int>();
+}
+
+QAudioEncoderSettings BbCameraAudioEncoderSettingsControl::audioSettings() const
+{
+ return m_session->audioSettings();
+}
+
+void BbCameraAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ m_session->setAudioSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudiodeviceinfo.h b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h
index 72c10cc75..21fb520e7 100644
--- a/src/plugins/qnx/audio/qnxaudiodeviceinfo.h
+++ b/src/plugins/qnx/camera/bbcameraaudioencodersettingscontrol.h
@@ -38,35 +38,29 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef BBCAMERAAUDIOENCODERSETTINGSCONTROL_H
+#define BBCAMERAAUDIOENCODERSETTINGSCONTROL_H
-#ifndef QNXAUDIODEVICEINFO_H
-#define QNXAUDIODEVICEINFO_H
-
-#include "qaudiosystem.h"
+#include <qaudioencodersettingscontrol.h>
QT_BEGIN_NAMESPACE
-class QnxAudioDeviceInfo : public QAbstractAudioDeviceInfo
+class BbCameraSession;
+
+class BbCameraAudioEncoderSettingsControl : public QAudioEncoderSettingsControl
{
Q_OBJECT
-
public:
- QnxAudioDeviceInfo(const QString &deviceName, QAudio::Mode mode);
- ~QnxAudioDeviceInfo();
+ explicit BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0);
- QAudioFormat preferredFormat() const Q_DECL_OVERRIDE;
- bool isFormatSupported(const QAudioFormat &format) const Q_DECL_OVERRIDE;
- QString deviceName() const Q_DECL_OVERRIDE;
- QStringList supportedCodecs() Q_DECL_OVERRIDE;
- QList<int> supportedSampleRates() Q_DECL_OVERRIDE;
- QList<int> supportedChannelCounts() Q_DECL_OVERRIDE;
- QList<int> supportedSampleSizes() Q_DECL_OVERRIDE;
- QList<QAudioFormat::Endian> supportedByteOrders() Q_DECL_OVERRIDE;
- QList<QAudioFormat::SampleType> supportedSampleTypes() Q_DECL_OVERRIDE;
+ QStringList supportedAudioCodecs() const Q_DECL_OVERRIDE;
+ QString codecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+ QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+ QAudioEncoderSettings audioSettings() const Q_DECL_OVERRIDE;
+ void setAudioSettings(const QAudioEncoderSettings &settings) Q_DECL_OVERRIDE;
private:
- const QString m_name;
- const QAudio::Mode m_mode;
+ BbCameraSession *m_session;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.cpp b/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.cpp
new file mode 100644
index 000000000..57f3c9fb1
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracapturebufferformatcontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraCaptureBufferFormatControl::BbCameraCaptureBufferFormatControl(QObject *parent)
+ : QCameraCaptureBufferFormatControl(parent)
+{
+}
+
+QList<QVideoFrame::PixelFormat> BbCameraCaptureBufferFormatControl::supportedBufferFormats() const
+{
+ return (QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_Jpeg);
+}
+
+QVideoFrame::PixelFormat BbCameraCaptureBufferFormatControl::bufferFormat() const
+{
+ return QVideoFrame::Format_Jpeg;
+}
+
+void BbCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format)
+{
+ Q_UNUSED(format)
+ // Do nothing, we support only Jpeg for now
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.h b/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.h
new file mode 100644
index 000000000..2897cb2fd
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracapturebufferformatcontrol.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACAPTUREBUFFERFORMATCONTROL_H
+#define BBCAMERACAPTUREBUFFERFORMATCONTROL_H
+
+#include <qcameracapturebufferformatcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraCaptureBufferFormatControl(QObject *parent = 0);
+
+ QList<QVideoFrame::PixelFormat> supportedBufferFormats() const Q_DECL_OVERRIDE;
+ QVideoFrame::PixelFormat bufferFormat() const Q_DECL_OVERRIDE;
+ void setBufferFormat(QVideoFrame::PixelFormat format) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.cpp b/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.cpp
new file mode 100644
index 000000000..6b6bcfcb9
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracapturedestinationcontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraCaptureDestinationControl::BbCameraCaptureDestinationControl(BbCameraSession *session, QObject *parent)
+ : QCameraCaptureDestinationControl(parent)
+ , m_session(session)
+{
+ connect(m_session, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
+ this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+}
+
+bool BbCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+ return m_session->isCaptureDestinationSupported(destination);
+}
+
+QCameraImageCapture::CaptureDestinations BbCameraCaptureDestinationControl::captureDestination() const
+{
+ return m_session->captureDestination();;
+}
+
+void BbCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+ m_session->setCaptureDestination(destination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.h b/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.h
new file mode 100644
index 000000000..93a7d2d14
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracapturedestinationcontrol.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACAPTUREDESTINATIONCONTROL_H
+#define BBCAMERACAPTUREDESTINATIONCONTROL_H
+
+#include <qcameracapturedestinationcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraCaptureDestinationControl : public QCameraCaptureDestinationControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraCaptureDestinationControl(BbCameraSession *session, QObject *parent = 0);
+
+ bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const Q_DECL_OVERRIDE;
+ QCameraImageCapture::CaptureDestinations captureDestination() const Q_DECL_OVERRIDE;
+ void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameracontrol.cpp b/src/plugins/qnx/camera/bbcameracontrol.cpp
new file mode 100644
index 000000000..bc3c78264
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracontrol.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraControl::BbCameraControl(BbCameraSession *session, QObject *parent)
+ : QCameraControl(parent)
+ , m_session(session)
+{
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(statusChanged(QCamera::Status)));
+ connect(m_session, SIGNAL(stateChanged(QCamera::State)), this, SIGNAL(stateChanged(QCamera::State)));
+ connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+ connect(m_session, SIGNAL(captureModeChanged(QCamera::CaptureModes)), this, SIGNAL(captureModeChanged(QCamera::CaptureModes)));
+}
+
+QCamera::State BbCameraControl::state() const
+{
+ return m_session->state();
+}
+
+void BbCameraControl::setState(QCamera::State state)
+{
+ m_session->setState(state);
+}
+
+QCamera::CaptureModes BbCameraControl::captureMode() const
+{
+ return m_session->captureMode();
+}
+
+void BbCameraControl::setCaptureMode(QCamera::CaptureModes mode)
+{
+ m_session->setCaptureMode(mode);
+}
+
+QCamera::Status BbCameraControl::status() const
+{
+ return m_session->status();
+}
+
+bool BbCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+ return m_session->isCaptureModeSupported(mode);
+}
+
+bool BbCameraControl::canChangeProperty(PropertyChangeType /* changeType */, QCamera::Status /* status */) const
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameracontrol.h b/src/plugins/qnx/camera/bbcameracontrol.h
new file mode 100644
index 000000000..a5792c5df
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameracontrol.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACONTROL_H
+#define BBCAMERACONTROL_H
+
+#include <qcameracontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraControl : public QCameraControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraControl(BbCameraSession *session, QObject *parent = 0);
+
+ QCamera::State state() const Q_DECL_OVERRIDE;
+ void setState(QCamera::State state) Q_DECL_OVERRIDE;
+
+ QCamera::Status status() const Q_DECL_OVERRIDE;
+
+ QCamera::CaptureModes captureMode() const Q_DECL_OVERRIDE;
+ void setCaptureMode(QCamera::CaptureModes) Q_DECL_OVERRIDE;
+ bool isCaptureModeSupported(QCamera::CaptureModes mode) const Q_DECL_OVERRIDE;
+
+ bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp b/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp
new file mode 100644
index 000000000..b1d637cd0
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraexposurecontrol.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraexposurecontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraExposureControl::BbCameraExposureControl(BbCameraSession *session, QObject *parent)
+ : QCameraExposureControl(parent)
+ , m_session(session)
+ , m_requestedExposureMode(QCameraExposure::ExposureAuto)
+{
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
+}
+
+bool BbCameraExposureControl::isParameterSupported(ExposureParameter parameter) const
+{
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ return false;
+ case QCameraExposureControl::Aperture:
+ return false;
+ case QCameraExposureControl::ShutterSpeed:
+ return false;
+ case QCameraExposureControl::ExposureCompensation:
+ return false;
+ case QCameraExposureControl::FlashPower:
+ return false;
+ case QCameraExposureControl::FlashCompensation:
+ return false;
+ case QCameraExposureControl::TorchPower:
+ return false;
+ case QCameraExposureControl::SpotMeteringPoint:
+ return false;
+ case QCameraExposureControl::ExposureMode:
+ return true;
+ case QCameraExposureControl::MeteringMode:
+ return false;
+ default:
+ return false;
+ }
+}
+
+QVariantList BbCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const
+{
+ if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+ return QVariantList();
+
+ if (m_session->status() != QCamera::ActiveStatus) // we can query supported exposure modes only with active viewfinder
+ return QVariantList();
+
+ if (continuous)
+ *continuous = false;
+
+ int supported = 0;
+ camera_scenemode_t modes[20];
+ const camera_error_t result = camera_get_scene_modes(m_session->handle(), 20, &supported, modes);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve supported scene modes:" << result;
+ return QVariantList();
+ }
+
+ QVariantList exposureModes;
+ for (int i = 0; i < supported; ++i) {
+ switch (modes[i]) {
+ case CAMERA_SCENE_AUTO:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto);
+ break;
+ case CAMERA_SCENE_SPORTS:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports);
+ break;
+ case CAMERA_SCENE_CLOSEUP:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposurePortrait);
+ break;
+ case CAMERA_SCENE_ACTION:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports);
+ break;
+ case CAMERA_SCENE_BEACHANDSNOW:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureBeach) << QVariant::fromValue(QCameraExposure::ExposureSnow);
+ break;
+ case CAMERA_SCENE_NIGHT:
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureNight);
+ break;
+ default: break;
+ }
+ }
+
+ return exposureModes;
+}
+
+QVariant BbCameraExposureControl::requestedValue(ExposureParameter parameter) const
+{
+ if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+ return QVariant();
+
+ return QVariant::fromValue(m_requestedExposureMode);
+}
+
+QVariant BbCameraExposureControl::actualValue(ExposureParameter parameter) const
+{
+#ifndef Q_OS_BLACKBERRY_TABLET
+ if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+ return QVariantList();
+
+ if (m_session->status() != QCamera::ActiveStatus) // we can query actual scene modes only with active viewfinder
+ return QVariantList();
+
+ camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT;
+ const camera_error_t result = camera_get_scene_mode(m_session->handle(), &sceneMode);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve scene mode:" << result;
+ return QVariant();
+ }
+
+ switch (sceneMode) {
+ case CAMERA_SCENE_AUTO:
+ return QVariant::fromValue(QCameraExposure::ExposureAuto);
+ case CAMERA_SCENE_SPORTS:
+ return QVariant::fromValue(QCameraExposure::ExposureSports);
+ case CAMERA_SCENE_CLOSEUP:
+ return QVariant::fromValue(QCameraExposure::ExposurePortrait);
+ case CAMERA_SCENE_ACTION:
+ return QVariant::fromValue(QCameraExposure::ExposureSports);
+ case CAMERA_SCENE_BEACHANDSNOW:
+ return (m_requestedExposureMode == QCameraExposure::ExposureBeach ? QVariant::fromValue(QCameraExposure::ExposureBeach)
+ : QVariant::fromValue(QCameraExposure::ExposureSnow));
+ case CAMERA_SCENE_NIGHT:
+ return QVariant::fromValue(QCameraExposure::ExposureNight);
+ default:
+ return QVariant();
+ }
+#else
+ return QVariant();
+#endif
+}
+
+bool BbCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value)
+{
+ if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+ return false;
+
+ if (m_session->status() != QCamera::ActiveStatus) // we can set actual scene modes only with active viewfinder
+ return false;
+
+ camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT;
+
+ if (value.isValid()) {
+ m_requestedExposureMode = value.value<QCameraExposure::ExposureMode>();
+ emit requestedValueChanged(QCameraExposureControl::ExposureMode);
+
+ switch (m_requestedExposureMode) {
+ case QCameraExposure::ExposureAuto:
+ sceneMode = CAMERA_SCENE_AUTO;
+ break;
+ case QCameraExposure::ExposureSports:
+ sceneMode = CAMERA_SCENE_SPORTS;
+ break;
+ case QCameraExposure::ExposurePortrait:
+ sceneMode = CAMERA_SCENE_CLOSEUP;
+ break;
+ case QCameraExposure::ExposureBeach:
+ sceneMode = CAMERA_SCENE_BEACHANDSNOW;
+ break;
+ case QCameraExposure::ExposureSnow:
+ sceneMode = CAMERA_SCENE_BEACHANDSNOW;
+ break;
+ case QCameraExposure::ExposureNight:
+ sceneMode = CAMERA_SCENE_NIGHT;
+ break;
+ default:
+ sceneMode = CAMERA_SCENE_DEFAULT;
+ break;
+ }
+ }
+
+ const camera_error_t result = camera_set_scene_mode(m_session->handle(), sceneMode);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set scene mode:" << result;
+ return false;
+ }
+
+ emit actualValueChanged(QCameraExposureControl::ExposureMode);
+
+ return true;
+}
+
+void BbCameraExposureControl::statusChanged(QCamera::Status status)
+{
+ if (status == QCamera::ActiveStatus || status == QCamera::LoadedStatus)
+ emit parameterRangeChanged(QCameraExposureControl::ExposureMode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraexposurecontrol.h b/src/plugins/qnx/camera/bbcameraexposurecontrol.h
new file mode 100644
index 000000000..f4659b624
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraexposurecontrol.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAEXPOSURECONTROL_H
+#define BBCAMERAEXPOSURECONTROL_H
+
+#include <qcameraexposurecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraExposureControl : public QCameraExposureControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraExposureControl(BbCameraSession *session, QObject *parent = 0);
+
+ virtual bool isParameterSupported(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+ virtual QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const Q_DECL_OVERRIDE;
+
+ virtual QVariant requestedValue(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+ virtual QVariant actualValue(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+ virtual bool setValue(ExposureParameter parameter, const QVariant& value) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+ void statusChanged(QCamera::Status status);
+
+private:
+ BbCameraSession *m_session;
+ QCameraExposure::ExposureMode m_requestedExposureMode;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraflashcontrol.cpp b/src/plugins/qnx/camera/bbcameraflashcontrol.cpp
new file mode 100644
index 000000000..06ebe01f6
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraflashcontrol.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraflashcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraFlashControl::BbCameraFlashControl(BbCameraSession *session, QObject *parent)
+ : QCameraFlashControl(parent)
+ , m_session(session)
+ , m_flashMode(QCameraExposure::FlashAuto)
+{
+}
+
+QCameraExposure::FlashModes BbCameraFlashControl::flashMode() const
+{
+ return m_flashMode;
+}
+
+void BbCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode)
+{
+ if (m_flashMode == mode)
+ return;
+
+ if (m_session->status() != QCamera::ActiveStatus) // can only be changed when viewfinder is active
+ return;
+
+ if (m_flashMode == QCameraExposure::FlashVideoLight) {
+ const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_OFF);
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to switch off video light:" << result;
+ }
+
+ m_flashMode = mode;
+
+ if (m_flashMode == QCameraExposure::FlashVideoLight) {
+ const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_ON);
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to switch on video light:" << result;
+ } else {
+ camera_flashmode_t flashMode = CAMERA_FLASH_AUTO;
+
+ if (m_flashMode.testFlag(QCameraExposure::FlashAuto)) flashMode = CAMERA_FLASH_AUTO;
+ else if (mode.testFlag(QCameraExposure::FlashOff)) flashMode = CAMERA_FLASH_OFF;
+ else if (mode.testFlag(QCameraExposure::FlashOn)) flashMode = CAMERA_FLASH_ON;
+
+ const camera_error_t result = camera_config_flash(m_session->handle(), flashMode);
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to configure flash:" << result;
+ }
+}
+
+bool BbCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+{
+ bool supportsVideoLight = false;
+ if (m_session->handle() != CAMERA_HANDLE_INVALID) {
+ supportsVideoLight = camera_has_feature(m_session->handle(), CAMERA_FEATURE_VIDEOLIGHT);
+ }
+
+ return (mode == QCameraExposure::FlashOff ||
+ mode == QCameraExposure::FlashOn ||
+ mode == QCameraExposure::FlashAuto ||
+ ((mode == QCameraExposure::FlashVideoLight) && supportsVideoLight));
+}
+
+bool BbCameraFlashControl::isFlashReady() const
+{
+ //TODO: check for flash charge-level here?!?
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudioplugin.h b/src/plugins/qnx/camera/bbcameraflashcontrol.h
index 1886057b4..d46dc8c12 100644
--- a/src/plugins/qnx/audio/qnxaudioplugin.h
+++ b/src/plugins/qnx/camera/bbcameraflashcontrol.h
@@ -38,27 +38,29 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef BBCAMERAFLASHCONTROL_H
+#define BBCAMERAFLASHCONTROL_H
-#ifndef QNXAUDIOPLUGIN_H
-#define QNXAUDIOPLUGIN_H
-
-#include <qaudiosystemplugin.h>
+#include <qcameraflashcontrol.h>
QT_BEGIN_NAMESPACE
-class QnxAudioPlugin : public QAudioSystemPlugin
+class BbCameraSession;
+
+class BbCameraFlashControl : public QCameraFlashControl
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "qnx_audio.json")
-
public:
- explicit QnxAudioPlugin(QObject *parent = 0);
- ~QnxAudioPlugin() {}
+ explicit BbCameraFlashControl(BbCameraSession *session, QObject *parent = 0);
+
+ QCameraExposure::FlashModes flashMode() const Q_DECL_OVERRIDE;
+ void setFlashMode(QCameraExposure::FlashModes mode) Q_DECL_OVERRIDE;
+ bool isFlashModeSupported(QCameraExposure::FlashModes mode) const Q_DECL_OVERRIDE;
+ bool isFlashReady() const Q_DECL_OVERRIDE;
- QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE;
- QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE;
- QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE;
- QAbstractAudioDeviceInfo *createDeviceInfo(const QByteArray &device, QAudio::Mode mode) Q_DECL_OVERRIDE;
+private:
+ BbCameraSession *m_session;
+ QCameraExposure::FlashModes m_flashMode;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp b/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp
new file mode 100644
index 000000000..e0b57d6c6
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerafocuscontrol.cpp
@@ -0,0 +1,331 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerafocuscontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraFocusControl::BbCameraFocusControl(BbCameraSession *session, QObject *parent)
+ : QCameraFocusControl(parent)
+ , m_session(session)
+ , m_focusMode(QCameraFocus::FocusModes())
+ , m_focusPointMode(QCameraFocus::FocusPointAuto)
+ , m_customFocusPoint(QPointF(0, 0))
+{
+}
+
+QCameraFocus::FocusModes BbCameraFocusControl::focusMode() const
+{
+ camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+
+ const camera_error_t result = camera_get_focus_mode(m_session->handle(), &focusMode);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve focus mode from camera:" << result;
+ return QCameraFocus::FocusModes();
+ }
+
+ switch (focusMode) {
+ case CAMERA_FOCUSMODE_EDOF:
+ return QCameraFocus::HyperfocalFocus;
+ case CAMERA_FOCUSMODE_MANUAL:
+ return QCameraFocus::ManualFocus;
+ case CAMERA_FOCUSMODE_AUTO:
+ return QCameraFocus::AutoFocus;
+ case CAMERA_FOCUSMODE_MACRO:
+ return QCameraFocus::MacroFocus;
+ case CAMERA_FOCUSMODE_CONTINUOUS_AUTO:
+ return QCameraFocus::ContinuousFocus;
+ case CAMERA_FOCUSMODE_CONTINUOUS_MACRO: // fall through
+ case CAMERA_FOCUSMODE_OFF: // fall through
+ default:
+ return QCameraFocus::FocusModes();
+ }
+}
+
+void BbCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode)
+{
+ if (m_focusMode == mode)
+ return;
+
+ camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+
+ if (mode == QCameraFocus::HyperfocalFocus)
+ focusMode = CAMERA_FOCUSMODE_EDOF;
+ else if (mode == QCameraFocus::ManualFocus)
+ focusMode = CAMERA_FOCUSMODE_MANUAL;
+ else if (mode == QCameraFocus::AutoFocus)
+ focusMode = CAMERA_FOCUSMODE_AUTO;
+ else if (mode == QCameraFocus::MacroFocus)
+ focusMode = CAMERA_FOCUSMODE_MACRO;
+ else if (mode == QCameraFocus::ContinuousFocus)
+ focusMode = CAMERA_FOCUSMODE_CONTINUOUS_AUTO;
+
+ const camera_error_t result = camera_set_focus_mode(m_session->handle(), focusMode);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set focus mode:" << result;
+ return;
+ }
+
+ m_focusMode = mode;
+ emit focusModeChanged(m_focusMode);
+}
+
+bool BbCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const
+{
+ if (m_session->state() == QCamera::UnloadedState)
+ return false;
+
+ if (mode == QCameraFocus::HyperfocalFocus)
+ return false; //TODO how to check?
+ else if (mode == QCameraFocus::ManualFocus)
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MANUALFOCUS);
+ else if (mode == QCameraFocus::AutoFocus)
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+ else if (mode == QCameraFocus::MacroFocus)
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MACROFOCUS);
+ else if (mode == QCameraFocus::ContinuousFocus)
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+
+ return false;
+}
+
+QCameraFocus::FocusPointMode BbCameraFocusControl::focusPointMode() const
+{
+ return m_focusPointMode;
+}
+
+void BbCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+{
+ if (m_session->status() != QCamera::ActiveStatus)
+ return;
+
+ if (m_focusPointMode == mode)
+ return;
+
+ m_focusPointMode = mode;
+ emit focusPointModeChanged(m_focusPointMode);
+
+ if (m_focusPointMode == QCameraFocus::FocusPointAuto) {
+ //TODO: is this correct?
+ const camera_error_t result = camera_set_focus_regions(m_session->handle(), 0, 0);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set focus region:" << result;
+ return;
+ }
+
+ emit focusZonesChanged();
+ } else if (m_focusPointMode == QCameraFocus::FocusPointCenter) {
+ // get the size of the viewfinder
+ int viewfinderWidth = 0;
+ int viewfinderHeight = 0;
+
+ if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight))
+ return;
+
+ // define a 40x40 pixel focus region in the center of the viewfinder
+ camera_region_t focusRegion;
+ focusRegion.left = (viewfinderWidth / 2) - 20;
+ focusRegion.top = (viewfinderHeight / 2) - 20;
+ focusRegion.width = 40;
+ focusRegion.height = 40;
+
+ camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set focus region:" << result;
+ return;
+ }
+
+ // re-set focus mode to apply focus region changes
+ camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+ result = camera_get_focus_mode(m_session->handle(), &focusMode);
+ camera_set_focus_mode(m_session->handle(), focusMode);
+
+ emit focusZonesChanged();
+
+ } else if (m_focusPointMode == QCameraFocus::FocusPointFaceDetection) {
+ //TODO: implement later
+ } else if (m_focusPointMode == QCameraFocus::FocusPointCustom) {
+ updateCustomFocusRegion();
+ }
+}
+
+bool BbCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+{
+ if (m_session->state() == QCamera::UnloadedState)
+ return false;
+
+ if (mode == QCameraFocus::FocusPointAuto) {
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+ } else if (mode == QCameraFocus::FocusPointCenter) {
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS);
+ } else if (mode == QCameraFocus::FocusPointFaceDetection) {
+ return false; //TODO: implement via custom region in combination with face detection in viewfinder
+ } else if (mode == QCameraFocus::FocusPointCustom) {
+ return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS);
+ }
+
+ return false;
+}
+
+QPointF BbCameraFocusControl::customFocusPoint() const
+{
+ return m_customFocusPoint;
+}
+
+void BbCameraFocusControl::setCustomFocusPoint(const QPointF &point)
+{
+ if (m_customFocusPoint == point)
+ return;
+
+ m_customFocusPoint = point;
+ emit customFocusPointChanged(m_customFocusPoint);
+
+ updateCustomFocusRegion();
+}
+
+QCameraFocusZoneList BbCameraFocusControl::focusZones() const
+{
+ if (m_session->state() == QCamera::UnloadedState)
+ return QCameraFocusZoneList();
+
+ camera_region_t regions[20];
+ int supported = 0;
+ int asked = 0;
+ camera_error_t result = camera_get_focus_regions(m_session->handle(), 20, &supported, &asked, regions);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve focus regions:" << result;
+ return QCameraFocusZoneList();
+ }
+
+ // retrieve width and height of viewfinder
+ int viewfinderWidth = 0;
+ int viewfinderHeight = 0;
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(),
+ CAMERA_IMGPROP_WIDTH, &viewfinderWidth,
+ CAMERA_IMGPROP_HEIGHT, &viewfinderHeight);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(),
+ CAMERA_IMGPROP_WIDTH, &viewfinderWidth,
+ CAMERA_IMGPROP_HEIGHT, &viewfinderHeight);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve viewfinder size:" << result;
+ return QCameraFocusZoneList();
+ }
+
+ QCameraFocusZoneList list;
+ for (int i = 0; i < asked; ++i) {
+ const int x = regions[i].left;
+ const int y = regions[i].top;
+ const int width = regions[i].width;
+ const int height = regions[i].height;
+
+ QRectF rect(static_cast<float>(x)/static_cast<float>(viewfinderWidth),
+ static_cast<float>(y)/static_cast<float>(viewfinderHeight),
+ static_cast<float>(width)/static_cast<float>(viewfinderWidth),
+ static_cast<float>(height)/static_cast<float>(viewfinderHeight));
+
+ list << QCameraFocusZone(rect, QCameraFocusZone::Focused); //TODO: how to know if a zone is unused/selected/focused?!?
+ }
+
+ return list;
+}
+
+void BbCameraFocusControl::updateCustomFocusRegion()
+{
+ // get the size of the viewfinder
+ int viewfinderWidth = 0;
+ int viewfinderHeight = 0;
+
+ if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight))
+ return;
+
+ // define a 40x40 pixel focus region around the custom focus point
+ camera_region_t focusRegion;
+ focusRegion.left = qMax(0, static_cast<int>(m_customFocusPoint.x() * viewfinderWidth) - 20);
+ focusRegion.top = qMax(0, static_cast<int>(m_customFocusPoint.y() * viewfinderHeight) - 20);
+ focusRegion.width = 40;
+ focusRegion.height = 40;
+
+ camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set focus region:" << result;
+ return;
+ }
+
+ // re-set focus mode to apply focus region changes
+ camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+ result = camera_get_focus_mode(m_session->handle(), &focusMode);
+ camera_set_focus_mode(m_session->handle(), focusMode);
+
+ emit focusZonesChanged();
+}
+
+bool BbCameraFocusControl::retrieveViewfinderSize(int *width, int *height)
+{
+ if (!width || !height)
+ return false;
+
+ camera_error_t result = CAMERA_EOK;
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(),
+ CAMERA_IMGPROP_WIDTH, width,
+ CAMERA_IMGPROP_HEIGHT, height);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(),
+ CAMERA_IMGPROP_WIDTH, width,
+ CAMERA_IMGPROP_HEIGHT, height);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve viewfinder size:" << result;
+ return false;
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcamerafocuscontrol.h b/src/plugins/qnx/camera/bbcamerafocuscontrol.h
new file mode 100644
index 000000000..052c29b4b
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerafocuscontrol.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAFOCUSCONTROL_H
+#define BBCAMERAFOCUSCONTROL_H
+
+#include <qcamerafocuscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraFocusControl : public QCameraFocusControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraFocusControl(BbCameraSession *session, QObject *parent = 0);
+
+ QCameraFocus::FocusModes focusMode() const Q_DECL_OVERRIDE;
+ void setFocusMode(QCameraFocus::FocusModes mode) Q_DECL_OVERRIDE;
+ bool isFocusModeSupported(QCameraFocus::FocusModes mode) const Q_DECL_OVERRIDE;
+ QCameraFocus::FocusPointMode focusPointMode() const Q_DECL_OVERRIDE;
+ void setFocusPointMode(QCameraFocus::FocusPointMode mode) Q_DECL_OVERRIDE;
+ bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const Q_DECL_OVERRIDE;
+ QPointF customFocusPoint() const Q_DECL_OVERRIDE;
+ void setCustomFocusPoint(const QPointF &point) Q_DECL_OVERRIDE;
+ QCameraFocusZoneList focusZones() const Q_DECL_OVERRIDE;
+
+private:
+ void updateCustomFocusRegion();
+ bool retrieveViewfinderSize(int *width, int *height);
+
+ BbCameraSession *m_session;
+
+ QCameraFocus::FocusModes m_focusMode;
+ QCameraFocus::FocusPointMode m_focusPointMode;
+ QPointF m_customFocusPoint;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp
new file mode 100644
index 000000000..a2f61f73d
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraimagecapturecontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraImageCaptureControl::BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent)
+ : QCameraImageCaptureControl(parent)
+ , m_session(session)
+{
+ connect(m_session, SIGNAL(readyForCaptureChanged(bool)), this, SIGNAL(readyForCaptureChanged(bool)));
+ connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
+ connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
+ connect(m_session, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
+ connect(m_session, SIGNAL(imageAvailable(int,QVideoFrame)), this, SIGNAL(imageAvailable(int,QVideoFrame)));
+ connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString)));
+ connect(m_session, SIGNAL(imageCaptureError(int,int,QString)), this, SIGNAL(error(int,int,QString)));
+}
+
+bool BbCameraImageCaptureControl::isReadyForCapture() const
+{
+ return m_session->isReadyForCapture();
+}
+
+QCameraImageCapture::DriveMode BbCameraImageCaptureControl::driveMode() const
+{
+ return m_session->driveMode();
+}
+
+void BbCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+ m_session->setDriveMode(mode);
+}
+
+int BbCameraImageCaptureControl::capture(const QString &fileName)
+{
+ return m_session->capture(fileName);
+}
+
+void BbCameraImageCaptureControl::cancelCapture()
+{
+ m_session->cancelCapture();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h
new file mode 100644
index 000000000..a73a4f1d5
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraimagecapturecontrol.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAIMAGECAPTURECONTROL_H
+#define BBCAMERAIMAGECAPTURECONTROL_H
+
+#include <qcameraimagecapturecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraImageCaptureControl : public QCameraImageCaptureControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent = 0);
+
+ bool isReadyForCapture() const Q_DECL_OVERRIDE;
+
+ QCameraImageCapture::DriveMode driveMode() const Q_DECL_OVERRIDE;
+ void setDriveMode(QCameraImageCapture::DriveMode mode) Q_DECL_OVERRIDE;
+
+ int capture(const QString &fileName) Q_DECL_OVERRIDE;
+ void cancelCapture() Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp
new file mode 100644
index 000000000..54ae48c6b
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraimageprocessingcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraImageProcessingControl::BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent)
+ : QCameraImageProcessingControl(parent)
+ , m_session(session)
+{
+}
+
+bool BbCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const
+{
+ return (parameter == QCameraImageProcessingControl::WhiteBalancePreset);
+}
+
+bool BbCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const
+{
+ if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+ return false;
+
+ if (m_session->handle() == CAMERA_HANDLE_INVALID)
+ return false;
+
+ int supported = 0;
+ camera_whitebalancemode_t modes[20];
+ const camera_error_t result = camera_get_whitebalance_modes(m_session->handle(), 20, &supported, modes);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve supported whitebalance modes:" << result;
+ return false;
+ }
+
+ QSet<QCameraImageProcessing::WhiteBalanceMode> supportedModes;
+ for (int i = 0; i < supported; ++i) {
+ switch (modes[i]) {
+ case CAMERA_WHITEBALANCEMODE_AUTO:
+ supportedModes.insert(QCameraImageProcessing::WhiteBalanceAuto);
+ break;
+ case CAMERA_WHITEBALANCEMODE_MANUAL:
+ supportedModes.insert(QCameraImageProcessing::WhiteBalanceManual);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return supportedModes.contains(value.value<QCameraImageProcessing::WhiteBalanceMode>());
+}
+
+QVariant BbCameraImageProcessingControl::parameter(ProcessingParameter parameter) const
+{
+ if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+ return QVariant();
+
+ if (m_session->handle() == CAMERA_HANDLE_INVALID)
+ return QVariant();
+
+ camera_whitebalancemode_t mode;
+ const camera_error_t result = camera_get_whitebalance_mode(m_session->handle(), &mode);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve current whitebalance mode:" << result;
+ return QVariant();
+ }
+
+ switch (mode) {
+ case CAMERA_WHITEBALANCEMODE_AUTO:
+ return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceAuto);
+ case CAMERA_WHITEBALANCEMODE_MANUAL:
+ return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceManual);
+ default:
+ return QVariant();
+ }
+}
+
+void BbCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value)
+{
+ if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+ return;
+
+ if (m_session->handle() == CAMERA_HANDLE_INVALID)
+ return;
+
+ camera_whitebalancemode_t mode = CAMERA_WHITEBALANCEMODE_DEFAULT;
+ switch (value.value<QCameraImageProcessing::WhiteBalanceMode>()) {
+ case QCameraImageProcessing::WhiteBalanceAuto:
+ mode = CAMERA_WHITEBALANCEMODE_AUTO;
+ break;
+ case QCameraImageProcessing::WhiteBalanceManual:
+ mode = CAMERA_WHITEBALANCEMODE_MANUAL;
+ break;
+ default:
+ break;
+ }
+
+ const camera_error_t result = camera_set_whitebalance_mode(m_session->handle(), mode);
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to set whitebalance mode:" << result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h
new file mode 100644
index 000000000..ec16d66d7
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraimageprocessingcontrol.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAIMAGEPROCESSINGCONTROL_H
+#define BBCAMERAIMAGEPROCESSINGCONTROL_H
+
+#include <qcameraimageprocessingcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraImageProcessingControl : public QCameraImageProcessingControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent = 0);
+
+ bool isParameterSupported(ProcessingParameter) const Q_DECL_OVERRIDE;
+ bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const Q_DECL_OVERRIDE;
+ QVariant parameter(ProcessingParameter parameter) const Q_DECL_OVERRIDE;
+ void setParameter(ProcessingParameter parameter, const QVariant &value) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameralockscontrol.cpp b/src/plugins/qnx/camera/bbcameralockscontrol.cpp
new file mode 100644
index 000000000..d2537361c
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameralockscontrol.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameralockscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraLocksControl::BbCameraLocksControl(BbCameraSession *session, QObject *parent)
+ : QCameraLocksControl(parent)
+ , m_session(session)
+ , m_locksApplyMode(IndependentMode)
+ , m_focusLockStatus(QCamera::Unlocked)
+ , m_exposureLockStatus(QCamera::Unlocked)
+ , m_whiteBalanceLockStatus(QCamera::Unlocked)
+ , m_currentLockTypes(QCamera::NoLock)
+ , m_supportedLockTypes(QCamera::NoLock)
+{
+ connect(m_session, SIGNAL(cameraOpened()), SLOT(cameraOpened()));
+ connect(m_session, SIGNAL(focusStatusChanged(int)), SLOT(focusStatusChanged(int)));
+}
+
+QCamera::LockTypes BbCameraLocksControl::supportedLocks() const
+{
+ return (QCamera::LockFocus | QCamera::LockExposure | QCamera::LockWhiteBalance);
+}
+
+QCamera::LockStatus BbCameraLocksControl::lockStatus(QCamera::LockType lock) const
+{
+ if (!m_supportedLockTypes.testFlag(lock) || (m_session->handle() == CAMERA_HANDLE_INVALID))
+ return QCamera::Locked;
+
+ switch (lock) {
+ case QCamera::LockExposure:
+ return m_exposureLockStatus;
+ case QCamera::LockWhiteBalance:
+ return m_whiteBalanceLockStatus;
+ case QCamera::LockFocus:
+ return m_focusLockStatus;
+ default:
+ return QCamera::Locked;
+ }
+}
+
+void BbCameraLocksControl::searchAndLock(QCamera::LockTypes locks)
+{
+ if (m_session->handle() == CAMERA_HANDLE_INVALID)
+ return;
+
+ // filter out unsupported locks
+ locks &= m_supportedLockTypes;
+
+ m_currentLockTypes |= locks;
+
+ uint32_t lockModes = CAMERA_3A_NONE;
+
+ switch (m_locksApplyMode) {
+ case IndependentMode:
+ if (m_currentLockTypes & QCamera::LockExposure)
+ lockModes |= CAMERA_3A_AUTOEXPOSURE;
+ if (m_currentLockTypes & QCamera::LockWhiteBalance)
+ lockModes |= CAMERA_3A_AUTOWHITEBALANCE;
+ if (m_currentLockTypes & QCamera::LockFocus)
+ lockModes |= CAMERA_3A_AUTOFOCUS;
+ break;
+ case FocusExposureBoundMode:
+ if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus))
+ lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS);
+ break;
+ case AllBoundMode:
+ lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE);
+ break;
+ case FocusOnlyMode:
+ lockModes = CAMERA_3A_AUTOFOCUS;
+ break;
+ }
+
+ const camera_error_t result = camera_set_3a_lock(m_session->handle(), lockModes);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set lock modes:" << result;
+ } else {
+ if (lockModes & CAMERA_3A_AUTOFOCUS) {
+ // handled by focusStatusChanged()
+ }
+
+ if (lockModes & CAMERA_3A_AUTOEXPOSURE) {
+ m_exposureLockStatus = QCamera::Locked;
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Locked, QCamera::LockAcquired);
+ }
+
+ if (lockModes & CAMERA_3A_AUTOWHITEBALANCE) {
+ m_whiteBalanceLockStatus = QCamera::Locked;
+ emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Locked, QCamera::LockAcquired);
+ }
+ }
+}
+
+void BbCameraLocksControl::unlock(QCamera::LockTypes locks)
+{
+ // filter out unsupported locks
+ locks &= m_supportedLockTypes;
+
+ m_currentLockTypes &= ~locks;
+
+ uint32_t lockModes = CAMERA_3A_NONE;
+
+ switch (m_locksApplyMode) {
+ case IndependentMode:
+ if (m_currentLockTypes & QCamera::LockExposure)
+ lockModes |= CAMERA_3A_AUTOEXPOSURE;
+ if (m_currentLockTypes & QCamera::LockWhiteBalance)
+ lockModes |= CAMERA_3A_AUTOWHITEBALANCE;
+ if (m_currentLockTypes & QCamera::LockFocus)
+ lockModes |= CAMERA_3A_AUTOFOCUS;
+ break;
+ case FocusExposureBoundMode:
+ if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus))
+ lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS);
+ break;
+ case AllBoundMode:
+ lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE);
+ break;
+ case FocusOnlyMode:
+ lockModes = CAMERA_3A_AUTOFOCUS;
+ break;
+ }
+
+ const camera_error_t result = camera_set_3a_lock(m_session->handle(), lockModes);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to set lock modes:" << result;
+ } else {
+ if (locks.testFlag(QCamera::LockFocus)) {
+ // handled by focusStatusChanged()
+ }
+
+ if (locks.testFlag(QCamera::LockExposure)) {
+ m_exposureLockStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Unlocked, QCamera::UserRequest);
+ }
+
+ if (locks.testFlag(QCamera::LockWhiteBalance)) {
+ m_whiteBalanceLockStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Unlocked, QCamera::UserRequest);
+ }
+ }
+}
+
+void BbCameraLocksControl::cameraOpened()
+{
+ // retrieve information about lock apply modes
+ int supported = 0;
+ uint32_t modes[20];
+
+ const camera_error_t result = camera_get_3a_lock_modes(m_session->handle(), 20, &supported, modes);
+
+ if (result == CAMERA_EOK) {
+ // see API documentation of camera_get_3a_lock_modes for explanation of case discrimination below
+ if (supported == 4) {
+ m_locksApplyMode = IndependentMode;
+ } else if (supported == 3) {
+ m_locksApplyMode = FocusExposureBoundMode;
+ } else if (supported == 2) {
+ if (modes[0] == (CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOWHITEBALANCE))
+ m_locksApplyMode = AllBoundMode;
+ else
+ m_locksApplyMode = FocusOnlyMode;
+ }
+ }
+
+ // retrieve information about supported lock types
+ m_supportedLockTypes = QCamera::NoLock;
+
+ if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS))
+ m_supportedLockTypes |= QCamera::LockFocus;
+
+ if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOEXPOSURE))
+ m_supportedLockTypes |= QCamera::LockExposure;
+
+ if (camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOWHITEBALANCE))
+ m_supportedLockTypes |= QCamera::LockWhiteBalance;
+
+ m_focusLockStatus = QCamera::Unlocked;
+ m_exposureLockStatus = QCamera::Unlocked;
+ m_whiteBalanceLockStatus = QCamera::Unlocked;
+}
+
+void BbCameraLocksControl::focusStatusChanged(int value)
+{
+ const camera_focusstate_t focusState = static_cast<camera_focusstate_t>(value);
+
+ switch (focusState) {
+ case CAMERA_FOCUSSTATE_NONE:
+ m_focusLockStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::UserRequest);
+ break;
+ case CAMERA_FOCUSSTATE_WAITING:
+ case CAMERA_FOCUSSTATE_SEARCHING:
+ m_focusLockStatus = QCamera::Searching;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Searching, QCamera::UserRequest);
+ break;
+ case CAMERA_FOCUSSTATE_FAILED:
+ m_focusLockStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+ break;
+ case CAMERA_FOCUSSTATE_LOCKED:
+ m_focusLockStatus = QCamera::Locked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Locked, QCamera::LockAcquired);
+ break;
+ case CAMERA_FOCUSSTATE_SCENECHANGE:
+ m_focusLockStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockTemporaryLost);
+ break;
+ default:
+ break;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameralockscontrol.h b/src/plugins/qnx/camera/bbcameralockscontrol.h
new file mode 100644
index 000000000..8257abdbc
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameralockscontrol.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERALOCKSCONTROL_H
+#define BBCAMERALOCKSCONTROL_H
+
+#include <qcameralockscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraLocksControl : public QCameraLocksControl
+{
+ Q_OBJECT
+public:
+ enum LocksApplyMode
+ {
+ IndependentMode,
+ FocusExposureBoundMode,
+ AllBoundMode,
+ FocusOnlyMode
+ };
+
+ explicit BbCameraLocksControl(BbCameraSession *session, QObject *parent = 0);
+
+ QCamera::LockTypes supportedLocks() const Q_DECL_OVERRIDE;
+ QCamera::LockStatus lockStatus(QCamera::LockType lock) const Q_DECL_OVERRIDE;
+ void searchAndLock(QCamera::LockTypes locks) Q_DECL_OVERRIDE;
+ void unlock(QCamera::LockTypes locks) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+ void cameraOpened();
+ void focusStatusChanged(int value);
+
+private:
+ BbCameraSession *m_session;
+
+ LocksApplyMode m_locksApplyMode;
+ QCamera::LockStatus m_focusLockStatus;
+ QCamera::LockStatus m_exposureLockStatus;
+ QCamera::LockStatus m_whiteBalanceLockStatus;
+ QCamera::LockTypes m_currentLockTypes;
+ QCamera::LockTypes m_supportedLockTypes;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp b/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp
new file mode 100644
index 000000000..44c19fb46
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameramediarecordercontrol.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameramediarecordercontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+#include <QUrl>
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+#include <audio/audio_manager_device.h>
+#include <audio/audio_manager_volume.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+static audio_manager_device_t currentAudioInputDevice()
+{
+ audio_manager_device_t device = AUDIO_DEVICE_HEADSET;
+
+ const int result = audio_manager_get_default_input_device(&device);
+ if (result != EOK) {
+ qWarning() << "Unable to retrieve default audio input device:" << result;
+ return AUDIO_DEVICE_HEADSET;
+ }
+
+ return device;
+}
+#endif
+
+BbCameraMediaRecorderControl::BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent)
+ : QMediaRecorderControl(parent)
+ , m_session(session)
+{
+ connect(m_session, SIGNAL(videoStateChanged(QMediaRecorder::State)), this, SIGNAL(stateChanged(QMediaRecorder::State)));
+ connect(m_session, SIGNAL(videoStatusChanged(QMediaRecorder::Status)), this, SIGNAL(statusChanged(QMediaRecorder::Status)));
+ connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+ connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl)));
+ connect(m_session, SIGNAL(videoError(int,QString)), this, SIGNAL(error(int,QString)));
+}
+
+QUrl BbCameraMediaRecorderControl::outputLocation() const
+{
+ return m_session->outputLocation();
+}
+
+bool BbCameraMediaRecorderControl::setOutputLocation(const QUrl &location)
+{
+ return m_session->setOutputLocation(location);
+}
+
+QMediaRecorder::State BbCameraMediaRecorderControl::state() const
+{
+ return m_session->videoState();
+}
+
+QMediaRecorder::Status BbCameraMediaRecorderControl::status() const
+{
+ return m_session->videoStatus();
+}
+
+qint64 BbCameraMediaRecorderControl::duration() const
+{
+ return m_session->duration();
+}
+
+bool BbCameraMediaRecorderControl::isMuted() const
+{
+ bool muted = false;
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+ const int result = audio_manager_get_input_mute(currentAudioInputDevice(), &muted);
+ if (result != EOK) {
+ emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve mute status"));
+ return false;
+ }
+#endif
+ return muted;
+}
+
+qreal BbCameraMediaRecorderControl::volume() const
+{
+ double level = 0.0;
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+ const int result = audio_manager_get_input_level(currentAudioInputDevice(), &level);
+ if (result != EOK) {
+ emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve audio input volume"));
+ return 0.0;
+ }
+#endif
+
+ return (level / 100);
+}
+
+void BbCameraMediaRecorderControl::applySettings()
+{
+ m_session->applyVideoSettings();
+}
+
+void BbCameraMediaRecorderControl::setState(QMediaRecorder::State state)
+{
+ m_session->setVideoState(state);
+}
+
+void BbCameraMediaRecorderControl::setMuted(bool muted)
+{
+#ifndef Q_OS_BLACKBERRY_TABLET
+ const int result = audio_manager_set_input_mute(currentAudioInputDevice(), muted);
+ if (result != EOK) {
+ emit error(QMediaRecorder::ResourceError, tr("Unable to set mute status"));
+ } else {
+ emit mutedChanged(muted);
+ }
+#endif
+}
+
+void BbCameraMediaRecorderControl::setVolume(qreal volume)
+{
+#ifndef Q_OS_BLACKBERRY_TABLET
+ const int result = audio_manager_set_input_level(currentAudioInputDevice(), (volume * 100));
+ if (result != EOK) {
+ emit error(QMediaRecorder::ResourceError, tr("Unable to set audio input volume"));
+ } else {
+ emit volumeChanged(volume);
+ }
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameramediarecordercontrol.h b/src/plugins/qnx/camera/bbcameramediarecordercontrol.h
new file mode 100644
index 000000000..dffd18be5
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameramediarecordercontrol.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAMEDIARECORDERCONTROL_H
+#define BBCAMERAMEDIARECORDERCONTROL_H
+
+#include <qmediarecordercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraMediaRecorderControl : public QMediaRecorderControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent = 0);
+
+ QUrl outputLocation() const Q_DECL_OVERRIDE;
+ bool setOutputLocation(const QUrl &location) Q_DECL_OVERRIDE;
+ QMediaRecorder::State state() const Q_DECL_OVERRIDE;
+ QMediaRecorder::Status status() const Q_DECL_OVERRIDE;
+ qint64 duration() const Q_DECL_OVERRIDE;
+ bool isMuted() const Q_DECL_OVERRIDE;
+ qreal volume() const Q_DECL_OVERRIDE;
+ void applySettings() Q_DECL_OVERRIDE;
+
+public Q_SLOTS:
+ void setState(QMediaRecorder::State state) Q_DECL_OVERRIDE;
+ void setMuted(bool muted) Q_DECL_OVERRIDE;
+ void setVolume(qreal volume) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraorientationhandler.cpp b/src/plugins/qnx/camera/bbcameraorientationhandler.cpp
new file mode 100644
index 000000000..b715249f9
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraorientationhandler.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraorientationhandler.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QDebug>
+
+#include <bps/orientation.h>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraOrientationHandler::BbCameraOrientationHandler(QObject *parent)
+ : QObject(parent)
+ , m_orientation(0)
+{
+ QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+ int result = orientation_request_events(0);
+ if (result == BPS_FAILURE)
+ qWarning() << "Unable to register for orientation change events";
+
+ orientation_direction_t direction = ORIENTATION_FACE_UP;
+ int angle = 0;
+
+ result = orientation_get(&direction, &angle);
+ if (result == BPS_FAILURE) {
+ qWarning() << "Unable to retrieve initial orientation";
+ } else {
+ m_orientation = angle;
+ }
+}
+
+BbCameraOrientationHandler::~BbCameraOrientationHandler()
+{
+#ifndef Q_OS_BLACKBERRY_TABLET
+ const int result = orientation_stop_events(0);
+ if (result == BPS_FAILURE)
+ qWarning() << "Unable to unregister for orientation change events";
+#endif
+
+ QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+bool BbCameraOrientationHandler::nativeEventFilter(const QByteArray&, void *message, long*)
+{
+ bps_event_t* const event = static_cast<bps_event_t*>(message);
+ if (!event || bps_event_get_domain(event) != orientation_get_domain())
+ return false;
+
+ const int angle = orientation_event_get_angle(event);
+ if (angle != m_orientation) {
+ m_orientation = angle;
+ emit orientationChanged(m_orientation);
+ }
+
+ return false; // do not drop the event
+}
+
+int BbCameraOrientationHandler::orientation() const
+{
+ return m_orientation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraorientationhandler.h b/src/plugins/qnx/camera/bbcameraorientationhandler.h
new file mode 100644
index 000000000..3d236b884
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraorientationhandler.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAORIENTATIONHANDLER_H
+#define BBCAMERAORIENTATIONHANDLER_H
+
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraOrientationHandler : public QObject, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+public:
+ explicit BbCameraOrientationHandler(QObject *parent = 0);
+ ~BbCameraOrientationHandler();
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+ int orientation() const;
+
+Q_SIGNALS:
+ void orientationChanged(int degree);
+
+private:
+ int m_orientation;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraservice.cpp b/src/plugins/qnx/camera/bbcameraservice.cpp
new file mode 100644
index 000000000..d9adc7c9d
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraservice.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraservice.h"
+
+#include "bbcameraaudioencodersettingscontrol.h"
+#include "bbcameracapturebufferformatcontrol.h"
+#include "bbcameracapturedestinationcontrol.h"
+#include "bbcameracontrol.h"
+#include "bbcameraexposurecontrol.h"
+#include "bbcameraflashcontrol.h"
+#include "bbcamerafocuscontrol.h"
+#include "bbcameraimagecapturecontrol.h"
+#include "bbcameraimageprocessingcontrol.h"
+#include "bbcameralockscontrol.h"
+#include "bbcameramediarecordercontrol.h"
+#include "bbcamerasession.h"
+#include "bbcameravideoencodersettingscontrol.h"
+#include "bbcameraviewfindersettingscontrol.h"
+#include "bbcamerazoomcontrol.h"
+#include "bbimageencodercontrol.h"
+#include "bbvideodeviceselectorcontrol.h"
+#include "bbvideorenderercontrol.h"
+
+#include <QDebug>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraService::BbCameraService(QObject *parent)
+ : QMediaService(parent)
+ , m_cameraSession(new BbCameraSession(this))
+ , m_cameraAudioEncoderSettingsControl(new BbCameraAudioEncoderSettingsControl(m_cameraSession, this))
+ , m_cameraCaptureBufferFormatControl(new BbCameraCaptureBufferFormatControl(this))
+ , m_cameraCaptureDestinationControl(new BbCameraCaptureDestinationControl(m_cameraSession, this))
+ , m_cameraControl(new BbCameraControl(m_cameraSession, this))
+ , m_cameraExposureControl(new BbCameraExposureControl(m_cameraSession, this))
+ , m_cameraFlashControl(new BbCameraFlashControl(m_cameraSession, this))
+ , m_cameraFocusControl(new BbCameraFocusControl(m_cameraSession, this))
+ , m_cameraImageCaptureControl(new BbCameraImageCaptureControl(m_cameraSession, this))
+ , m_cameraImageProcessingControl(new BbCameraImageProcessingControl(m_cameraSession, this))
+ , m_cameraLocksControl(new BbCameraLocksControl(m_cameraSession, this))
+ , m_cameraMediaRecorderControl(new BbCameraMediaRecorderControl(m_cameraSession, this))
+ , m_cameraVideoEncoderSettingsControl(new BbCameraVideoEncoderSettingsControl(m_cameraSession, this))
+ , m_cameraViewfinderSettingsControl(new BbCameraViewfinderSettingsControl(m_cameraSession, this))
+ , m_cameraZoomControl(new BbCameraZoomControl(m_cameraSession, this))
+ , m_imageEncoderControl(new BbImageEncoderControl(m_cameraSession, this))
+ , m_videoDeviceSelectorControl(new BbVideoDeviceSelectorControl(m_cameraSession, this))
+ , m_videoRendererControl(new BbVideoRendererControl(m_cameraSession, this))
+{
+}
+
+BbCameraService::~BbCameraService()
+{
+}
+
+QMediaControl* BbCameraService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0)
+ return m_cameraAudioEncoderSettingsControl;
+ else if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0)
+ return m_cameraCaptureBufferFormatControl;
+ else if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
+ return m_cameraCaptureDestinationControl;
+ else if (qstrcmp(name, QCameraControl_iid) == 0)
+ return m_cameraControl;
+ else if (qstrcmp(name, QCameraExposureControl_iid) == 0)
+ return m_cameraExposureControl;
+ else if (qstrcmp(name, QCameraFlashControl_iid) == 0)
+ return m_cameraFlashControl;
+ else if (qstrcmp(name, QCameraFocusControl_iid) == 0)
+ return m_cameraFocusControl;
+ else if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
+ return m_cameraImageCaptureControl;
+ else if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
+ return m_cameraImageProcessingControl;
+ else if (qstrcmp(name, QCameraLocksControl_iid) == 0)
+ return m_cameraLocksControl;
+ else if (qstrcmp(name, QMediaRecorderControl_iid) == 0)
+ return m_cameraMediaRecorderControl;
+ else if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0)
+ return m_cameraVideoEncoderSettingsControl;
+ else if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0)
+ return m_cameraViewfinderSettingsControl;
+ else if (qstrcmp(name, QCameraZoomControl_iid) == 0)
+ return m_cameraZoomControl;
+ else if (qstrcmp(name, QImageEncoderControl_iid) == 0)
+ return m_imageEncoderControl;
+ else if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0)
+ return m_videoDeviceSelectorControl;
+ else if (qstrcmp(name, QVideoRendererControl_iid) == 0)
+ return m_videoRendererControl;
+
+ return 0;
+}
+
+void BbCameraService::releaseControl(QMediaControl *control)
+{
+ Q_UNUSED(control)
+
+ // Implemented as a singleton, so we do nothing.
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraservice.h b/src/plugins/qnx/camera/bbcameraservice.h
new file mode 100644
index 000000000..374d03c36
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraservice.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERASERVICE_H
+#define BBCAMERASERVICE_H
+
+#include <QObject>
+
+#include <qmediaservice.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraAudioEncoderSettingsControl;
+class BbCameraCaptureBufferFormatControl;
+class BbCameraCaptureDestinationControl;
+class BbCameraControl;
+class BbCameraExposureControl;
+class BbCameraFlashControl;
+class BbCameraFocusControl;
+class BbCameraImageCaptureControl;
+class BbCameraImageProcessingControl;
+class BbCameraLocksControl;
+class BbCameraMediaRecorderControl;
+class BbCameraSession;
+class BbCameraVideoEncoderSettingsControl;
+class BbCameraViewfinderSettingsControl;
+class BbCameraZoomControl;
+class BbImageEncoderControl;
+class BbVideoDeviceSelectorControl;
+class BbVideoRendererControl;
+
+class BbCameraService : public QMediaService
+{
+ Q_OBJECT
+
+public:
+ explicit BbCameraService(QObject *parent = 0);
+ ~BbCameraService();
+
+ virtual QMediaControl* requestControl(const char *name);
+ virtual void releaseControl(QMediaControl *control);
+
+private:
+ BbCameraSession* m_cameraSession;
+
+ BbCameraAudioEncoderSettingsControl* m_cameraAudioEncoderSettingsControl;
+ BbCameraCaptureBufferFormatControl* m_cameraCaptureBufferFormatControl;
+ BbCameraCaptureDestinationControl* m_cameraCaptureDestinationControl;
+ BbCameraControl* m_cameraControl;
+ BbCameraExposureControl* m_cameraExposureControl;
+ BbCameraFlashControl* m_cameraFlashControl;
+ BbCameraFocusControl* m_cameraFocusControl;
+ BbCameraImageCaptureControl* m_cameraImageCaptureControl;
+ BbCameraImageProcessingControl* m_cameraImageProcessingControl;
+ BbCameraLocksControl* m_cameraLocksControl;
+ BbCameraMediaRecorderControl* m_cameraMediaRecorderControl;
+ BbCameraVideoEncoderSettingsControl* m_cameraVideoEncoderSettingsControl;
+ BbCameraViewfinderSettingsControl* m_cameraViewfinderSettingsControl;
+ BbCameraZoomControl* m_cameraZoomControl;
+ BbImageEncoderControl* m_imageEncoderControl;
+ BbVideoDeviceSelectorControl* m_videoDeviceSelectorControl;
+ BbVideoRendererControl* m_videoRendererControl;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcamerasession.cpp b/src/plugins/qnx/camera/bbcamerasession.cpp
new file mode 100644
index 000000000..59db66f4a
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerasession.cpp
@@ -0,0 +1,1164 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerasession.h"
+
+#include "bbcameraorientationhandler.h"
+#include "bbcameraviewfindersettingscontrol.h"
+#include "windowgrabber.h"
+
+#include <QAbstractVideoSurface>
+#include <QBuffer>
+#include <QDebug>
+#include <QImage>
+#include <QUrl>
+#include <QVideoSurfaceFormat>
+#include <qmath.h>
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+static QString errorToString(camera_error_t error)
+{
+ switch (error) {
+ case CAMERA_EOK:
+ return QLatin1String("No error");
+ case CAMERA_EAGAIN:
+ return QLatin1String("Camera unavailable");
+ case CAMERA_EINVAL:
+ return QLatin1String("Inavlid argument");
+ case CAMERA_ENODEV:
+ return QLatin1String("Camera not found");
+ case CAMERA_EMFILE:
+ return QLatin1String("File table overflow");
+ case CAMERA_EBADF:
+ return QLatin1String("Invalid handle passed");
+ case CAMERA_EACCESS:
+ return QLatin1String("No permission");
+ case CAMERA_EBADR:
+ return QLatin1String("Invalid file descriptor");
+ case CAMERA_ENOENT:
+ return QLatin1String("File or directory does not exists");
+ case CAMERA_ENOMEM:
+ return QLatin1String("Memory allocation failed");
+ case CAMERA_EOPNOTSUPP:
+ return QLatin1String("Operation not supported");
+ case CAMERA_ETIMEDOUT:
+ return QLatin1String("Communication timeout");
+ case CAMERA_EALREADY:
+ return QLatin1String("Operation already in progress");
+ case CAMERA_EUNINIT:
+ return QLatin1String("Camera library not initialized");
+ case CAMERA_EREGFAULT:
+ return QLatin1String("Callback registration failed");
+ case CAMERA_EMICINUSE:
+ return QLatin1String("Microphone in use already");
+#ifndef Q_OS_BLACKBERRY_TABLET
+ case CAMERA_ENODATA:
+ return QLatin1String("Data does not exist");
+ case CAMERA_EBUSY:
+ return QLatin1String("Camera busy");
+ case CAMERA_EDESKTOPCAMERAINUSE:
+ return QLatin1String("Desktop camera in use already");
+ case CAMERA_ENOSPC:
+ return QLatin1String("Disk is full");
+ case CAMERA_EPOWERDOWN:
+ return QLatin1String("Camera in power down state");
+ case CAMERA_3ALOCKED:
+ return QLatin1String("3A have been locked");
+// case CAMERA_EVIEWFINDERFROZEN: // not yet available in 10.2 NDK
+// return QLatin1String("Freeze flag set");
+#endif
+ default:
+ return QLatin1String("Unknown error");
+ }
+}
+
+QDebug operator<<(QDebug debug, camera_error_t error)
+{
+ debug.nospace() << errorToString(error);
+ return debug.space();
+}
+
+BbCameraSession::BbCameraSession(QObject *parent)
+ : QObject(parent)
+ , m_nativeCameraOrientation(0)
+ , m_orientationHandler(new BbCameraOrientationHandler(this))
+ , m_status(QCamera::UnloadedStatus)
+ , m_state(QCamera::UnloadedState)
+ , m_captureMode(QCamera::CaptureStillImage)
+ , m_device("bb:RearCamera")
+ , m_previewIsVideo(true)
+ , m_surface(0)
+ , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture)
+ , m_lastImageCaptureId(0)
+ , m_captureDestination(QCameraImageCapture::CaptureToFile)
+ , m_videoState(QMediaRecorder::StoppedState)
+ , m_videoStatus(QMediaRecorder::LoadedStatus)
+ , m_handle(CAMERA_HANDLE_INVALID)
+ , m_windowGrabber(new WindowGrabber(this))
+{
+ connect(this, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyForCapture()));
+ connect(this, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyForCapture()));
+ connect(m_orientationHandler, SIGNAL(orientationChanged(int)), SLOT(deviceOrientationChanged(int)));
+
+ connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage)), SLOT(viewfinderFrameGrabbed(QImage)));
+}
+
+BbCameraSession::~BbCameraSession()
+{
+ stopViewFinder();
+ closeCamera();
+}
+
+camera_handle_t BbCameraSession::handle() const
+{
+ return m_handle;
+}
+
+QCamera::State BbCameraSession::state() const
+{
+ return m_state;
+}
+
+void BbCameraSession::setState(QCamera::State state)
+{
+ if (m_state == state)
+ return;
+
+ const QCamera::State previousState = m_state;
+
+ if (previousState == QCamera::UnloadedState) {
+ if (state == QCamera::LoadedState) {
+ if (openCamera()) {
+ m_state = state;
+ }
+ } else if (state == QCamera::ActiveState) {
+ if (openCamera()) {
+ QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection);
+ m_state = state;
+ }
+ }
+ } else if (previousState == QCamera::LoadedState) {
+ if (state == QCamera::UnloadedState) {
+ closeCamera();
+ m_state = state;
+ } else if (state == QCamera::ActiveState) {
+ QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection);
+ m_state = state;
+ }
+ } else if (previousState == QCamera::ActiveState) {
+ if (state == QCamera::LoadedState) {
+ stopViewFinder();
+ m_state = state;
+ } else if (state == QCamera::UnloadedState) {
+ stopViewFinder();
+ closeCamera();
+ m_state = state;
+ }
+ }
+
+ if (m_state != previousState)
+ emit stateChanged(m_state);
+}
+
+QCamera::Status BbCameraSession::status() const
+{
+ return m_status;
+}
+
+QCamera::CaptureModes BbCameraSession::captureMode() const
+{
+ return m_captureMode;
+}
+
+void BbCameraSession::setCaptureMode(QCamera::CaptureModes captureMode)
+{
+ if (m_captureMode == captureMode)
+ return;
+
+ m_captureMode = captureMode;
+ emit captureModeChanged(m_captureMode);
+}
+
+bool BbCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+ if (m_handle == CAMERA_HANDLE_INVALID) {
+ // the camera has not been loaded yet via QCamera::load(), so
+ // we open it temporarily to peek for the supported capture modes
+
+ camera_unit_t unit = CAMERA_UNIT_REAR;
+ if (m_device == cameraIdentifierFront())
+ unit = CAMERA_UNIT_FRONT;
+ else if (m_device == cameraIdentifierRear())
+ unit = CAMERA_UNIT_REAR;
+ else if (m_device == cameraIdentifierDesktop())
+ unit = CAMERA_UNIT_DESKTOP;
+
+ camera_handle_t handle;
+ const camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &handle);
+ if (result != CAMERA_EOK)
+ return true;
+
+ const bool supported = isCaptureModeSupported(handle, mode);
+
+ camera_close(handle);
+
+ return supported;
+ } else {
+ return isCaptureModeSupported(m_handle, mode);
+ }
+}
+
+QByteArray BbCameraSession::cameraIdentifierFront()
+{
+ return "bb:FrontCamera";
+}
+
+QByteArray BbCameraSession::cameraIdentifierRear()
+{
+ return "bb:RearCamera";
+}
+
+QByteArray BbCameraSession::cameraIdentifierDesktop()
+{
+ return "bb:DesktopCamera";
+}
+
+void BbCameraSession::setDevice(const QByteArray &device)
+{
+ m_device = device;
+}
+
+QByteArray BbCameraSession::device() const
+{
+ return m_device;
+}
+
+QAbstractVideoSurface* BbCameraSession::surface() const
+{
+ return m_surface;
+}
+
+void BbCameraSession::setSurface(QAbstractVideoSurface *surface)
+{
+ QMutexLocker locker(&m_surfaceMutex);
+
+ if (m_surface == surface)
+ return;
+
+ m_surface = surface;
+}
+
+bool BbCameraSession::isReadyForCapture() const
+{
+ if (m_captureMode & QCamera::CaptureStillImage)
+ return (m_status == QCamera::ActiveStatus);
+
+ if (m_captureMode & QCamera::CaptureVideo)
+ return (m_status == QCamera::ActiveStatus);
+
+ return false;
+}
+
+QCameraImageCapture::DriveMode BbCameraSession::driveMode() const
+{
+ return m_captureImageDriveMode;
+}
+
+void BbCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+ m_captureImageDriveMode = mode;
+}
+
+/**
+ * A helper structure that keeps context data for image capture callbacks.
+ */
+struct ImageCaptureData
+{
+ int requestId;
+ QString fileName;
+ BbCameraSession *session;
+};
+
+static void imageCaptureShutterCallback(camera_handle_t handle, void *context)
+{
+ Q_UNUSED(handle)
+
+ const ImageCaptureData *data = static_cast<ImageCaptureData*>(context);
+
+ // We are inside a worker thread here, so emit imageExposed inside the main thread
+ QMetaObject::invokeMethod(data->session, "imageExposed", Qt::QueuedConnection,
+ Q_ARG(int, data->requestId));
+}
+
+static void imageCaptureImageCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context)
+{
+ Q_UNUSED(handle)
+
+ QScopedPointer<ImageCaptureData> data(static_cast<ImageCaptureData*>(context));
+
+ if (buffer->frametype != CAMERA_FRAMETYPE_JPEG) {
+ // We are inside a worker thread here, so emit error signal inside the main thread
+ QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
+ Q_ARG(int, data->requestId),
+ Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
+ Q_ARG(QString, BbCameraSession::tr("Camera provides image in unsupported format")));
+ return;
+ }
+
+ const QByteArray rawData((const char*)buffer->framebuf, buffer->framedesc.jpeg.bufsize);
+
+ QImage image;
+ const bool ok = image.loadFromData(rawData, "JPG");
+ if (!ok) {
+ const QString errorMessage = BbCameraSession::tr("Could not load JPEG data from frame");
+ // We are inside a worker thread here, so emit error signal inside the main thread
+ QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
+ Q_ARG(int, data->requestId),
+ Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
+ Q_ARG(QString, errorMessage));
+ return;
+ }
+
+
+ // We are inside a worker thread here, so invoke imageCaptured inside the main thread
+ QMetaObject::invokeMethod(data->session, "imageCaptured", Qt::QueuedConnection,
+ Q_ARG(int, data->requestId),
+ Q_ARG(QImage, image),
+ Q_ARG(QString, data->fileName));
+}
+
+int BbCameraSession::capture(const QString &fileName)
+{
+ m_lastImageCaptureId++;
+
+ if (!isReadyForCapture()) {
+ emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
+ return m_lastImageCaptureId;
+ }
+
+ if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) {
+ // prepare context object for callback
+ ImageCaptureData *context = new ImageCaptureData;
+ context->requestId = m_lastImageCaptureId;
+ context->fileName = fileName;
+ context->session = this;
+
+ const camera_error_t result = camera_take_photo(m_handle,
+ imageCaptureShutterCallback,
+ 0,
+ 0,
+ imageCaptureImageCallback,
+ context, false);
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to take photo:" << result;
+ } else {
+ // TODO: implement burst mode when available in Qt API
+ }
+
+ return m_lastImageCaptureId;
+}
+
+void BbCameraSession::cancelCapture()
+{
+ // BB10 API doesn't provide functionality for that
+}
+
+bool BbCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+ // capture to buffer, file and both are supported.
+ return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer);
+}
+
+QCameraImageCapture::CaptureDestinations BbCameraSession::captureDestination() const
+{
+ return m_captureDestination;
+}
+
+void BbCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+ if (m_captureDestination != destination) {
+ m_captureDestination = destination;
+ emit captureDestinationChanged(m_captureDestination);
+ }
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(const QImageEncoderSettings&, bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ if (m_status == QCamera::UnloadedStatus)
+ return QList<QSize>();
+
+ if (m_captureMode & QCamera::CaptureStillImage) {
+ return supportedResolutions(QCamera::CaptureStillImage);
+ } else if (m_captureMode & QCamera::CaptureVideo) {
+ return supportedResolutions(QCamera::CaptureVideo);
+ }
+
+ return QList<QSize>();
+}
+
+QImageEncoderSettings BbCameraSession::imageSettings() const
+{
+ return m_imageEncoderSettings;
+}
+
+void BbCameraSession::setImageSettings(const QImageEncoderSettings &settings)
+{
+ m_imageEncoderSettings = settings;
+ if (m_imageEncoderSettings.codec().isEmpty())
+ m_imageEncoderSettings.setCodec(QLatin1String("jpeg"));
+}
+
+QUrl BbCameraSession::outputLocation() const
+{
+ return QUrl::fromLocalFile(m_videoOutputLocation);
+}
+
+bool BbCameraSession::setOutputLocation(const QUrl &location)
+{
+ m_videoOutputLocation = location.toLocalFile();
+
+ return true;
+}
+
+QMediaRecorder::State BbCameraSession::videoState() const
+{
+ return m_videoState;
+}
+
+void BbCameraSession::setVideoState(QMediaRecorder::State state)
+{
+ if (m_videoState == state)
+ return;
+
+ const QMediaRecorder::State previousState = m_videoState;
+
+ if (previousState == QMediaRecorder::StoppedState) {
+ if (state == QMediaRecorder::RecordingState) {
+ if (startVideoRecording()) {
+ m_videoState = state;
+ }
+ } else if (state == QMediaRecorder::PausedState) {
+ // do nothing
+ }
+ } else if (previousState == QMediaRecorder::RecordingState) {
+ if (state == QMediaRecorder::StoppedState) {
+ stopVideoRecording();
+ m_videoState = state;
+ } else if (state == QMediaRecorder::PausedState) {
+ //TODO: (pause) not supported by BB10 API yet
+ }
+ } else if (previousState == QMediaRecorder::PausedState) {
+ if (state == QMediaRecorder::StoppedState) {
+ stopVideoRecording();
+ m_videoState = state;
+ } else if (state == QMediaRecorder::RecordingState) {
+ //TODO: (resume) not supported by BB10 API yet
+ }
+ }
+
+ emit videoStateChanged(m_videoState);
+}
+
+QMediaRecorder::Status BbCameraSession::videoStatus() const
+{
+ return m_videoStatus;
+}
+
+qint64 BbCameraSession::duration() const
+{
+ return (m_videoRecordingDuration.isValid() ? m_videoRecordingDuration.elapsed() : 0);
+}
+
+void BbCameraSession::applyVideoSettings()
+{
+ if (m_handle == CAMERA_HANDLE_INVALID)
+ return;
+
+ // apply viewfinder configuration
+ const QList<QSize> videoOutputResolutions = supportedResolutions(QCamera::CaptureVideo);
+
+ if (!m_videoEncoderSettings.resolution().isValid() || !videoOutputResolutions.contains(m_videoEncoderSettings.resolution()))
+ m_videoEncoderSettings.setResolution(videoOutputResolutions.first());
+
+ QSize viewfinderResolution;
+
+ if (m_previewIsVideo) {
+ // The viewfinder is responsible for encoding the video frames, so the resolutions must match.
+ viewfinderResolution = m_videoEncoderSettings.resolution();
+ } else {
+ // The frames are encoded separately from the viewfinder, so only the aspect ratio must match.
+ const QSize videoResolution = m_videoEncoderSettings.resolution();
+ const qreal aspectRatio = static_cast<qreal>(videoResolution.width())/static_cast<qreal>(videoResolution.height());
+
+ QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureVideo);
+ std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
+ foreach (const QSize &size, sizes) {
+ // search for viewfinder resolution with the same aspect ratio
+ if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
+ viewfinderResolution = size;
+ break;
+ }
+ }
+ }
+
+ Q_ASSERT(viewfinderResolution.isValid());
+
+ const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1();
+ m_windowGrabber->setWindowId(windowId);
+
+ const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
+
+ const int rotationAngle = (360 - m_nativeCameraOrientation);
+
+ camera_error_t result = CAMERA_EOK;
+ result = camera_set_videovf_property(m_handle,
+ CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(),
+ CAMERA_IMGPROP_WIN_ID, windowId.data(),
+ CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
+ CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
+ CAMERA_IMGPROP_ROTATION, rotationAngle);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to apply video viewfinder settings:" << result;
+ return;
+ }
+
+ const QSize resolution = m_videoEncoderSettings.resolution();
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+ QString videoCodec = m_videoEncoderSettings.codec();
+ if (videoCodec.isEmpty())
+ videoCodec = QLatin1String("h264");
+
+ camera_videocodec_t cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
+ if (videoCodec == QLatin1String("none"))
+ cameraVideoCodec = CAMERA_VIDEOCODEC_NONE;
+ else if (videoCodec == QLatin1String("avc1"))
+ cameraVideoCodec = CAMERA_VIDEOCODEC_AVC1;
+ else if (videoCodec == QLatin1String("h264"))
+ cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
+
+ qreal frameRate = m_videoEncoderSettings.frameRate();
+ if (frameRate == 0) {
+ const QList<qreal> frameRates = supportedFrameRates(QVideoEncoderSettings(), 0);
+ if (!frameRates.isEmpty())
+ frameRate = frameRates.last();
+ }
+
+ QString audioCodec = m_audioEncoderSettings.codec();
+ if (audioCodec.isEmpty())
+ audioCodec = QLatin1String("aac");
+
+ camera_audiocodec_t cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
+ if (audioCodec == QLatin1String("none"))
+ cameraAudioCodec = CAMERA_AUDIOCODEC_NONE;
+ else if (audioCodec == QLatin1String("aac"))
+ cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
+ else if (audioCodec == QLatin1String("raw"))
+ cameraAudioCodec = CAMERA_AUDIOCODEC_RAW;
+
+ result = camera_set_video_property(m_handle,
+ CAMERA_IMGPROP_WIDTH, resolution.width(),
+ CAMERA_IMGPROP_HEIGHT, resolution.height(),
+ CAMERA_IMGPROP_ROTATION, rotationAngle,
+ CAMERA_IMGPROP_VIDEOCODEC, cameraVideoCodec,
+ CAMERA_IMGPROP_AUDIOCODEC, cameraAudioCodec);
+#else
+ result = camera_set_video_property(m_handle,
+ CAMERA_IMGPROP_WIDTH, resolution.width(),
+ CAMERA_IMGPROP_HEIGHT, resolution.height());
+#endif
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to apply video settings:" << result;
+ emit videoError(QMediaRecorder::ResourceError, tr("Unable to apply video settings"));
+ }
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ Q_UNUSED(settings);
+
+ if (continuous)
+ *continuous = false;
+
+ return supportedResolutions(QCamera::CaptureVideo);
+}
+
+QList<qreal> BbCameraSession::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ Q_UNUSED(settings);
+
+ if (m_handle == CAMERA_HANDLE_INVALID)
+ return QList<qreal>();
+
+ int supported = 0;
+ double rates[20];
+ bool maxmin = false;
+
+ /**
+ * Since in current version of the BB10 platform the video viewfinder encodes the video frames, we use
+ * the values as returned by camera_get_video_vf_framerates().
+ */
+ const camera_error_t result = camera_get_video_vf_framerates(m_handle, 20, &supported, rates, &maxmin);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve supported viewfinder framerates:" << result;
+ return QList<qreal>();
+ }
+
+ QList<qreal> frameRates;
+ for (int i = 0; i < supported; ++i)
+ frameRates << rates[i];
+
+ if (continuous)
+ *continuous = maxmin;
+
+ return frameRates;
+}
+
+QVideoEncoderSettings BbCameraSession::videoSettings() const
+{
+ return m_videoEncoderSettings;
+}
+
+void BbCameraSession::setVideoSettings(const QVideoEncoderSettings &settings)
+{
+ m_videoEncoderSettings = settings;
+}
+
+QAudioEncoderSettings BbCameraSession::audioSettings() const
+{
+ return m_audioEncoderSettings;
+}
+
+void BbCameraSession::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ m_audioEncoderSettings = settings;
+}
+
+void BbCameraSession::updateReadyForCapture()
+{
+ emit readyForCaptureChanged(isReadyForCapture());
+}
+
+void BbCameraSession::imageCaptured(int requestId, const QImage &rawImage, const QString &fileName)
+{
+ QTransform transform;
+
+ // subtract out the native rotation
+ transform.rotate(m_nativeCameraOrientation);
+
+ // subtract out the current device orientation
+ if (m_device == cameraIdentifierRear())
+ transform.rotate(360 - m_orientationHandler->orientation());
+ else
+ transform.rotate(m_orientationHandler->orientation());
+
+ const QImage image = rawImage.transformed(transform);
+
+ // Generate snap preview as downscaled image
+ {
+ QSize previewSize = image.size();
+ int downScaleSteps = 0;
+ while (previewSize.width() > 800 && downScaleSteps < 8) {
+ previewSize.rwidth() /= 2;
+ previewSize.rheight() /= 2;
+ downScaleSteps++;
+ }
+
+ const QImage snapPreview = image.scaled(previewSize);
+
+ emit imageCaptured(requestId, snapPreview);
+ }
+
+ if (m_captureDestination & QCameraImageCapture::CaptureToBuffer) {
+ QVideoFrame frame(image);
+
+ emit imageAvailable(requestId, frame);
+ }
+
+ if (m_captureDestination & QCameraImageCapture::CaptureToFile) {
+ const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName,
+ QCamera::CaptureStillImage,
+ QLatin1String("IMG_"),
+ QLatin1String("jpg"));
+
+ QFile file(actualFileName);
+ if (file.open(QFile::WriteOnly)) {
+ if (image.save(&file, "JPG")) {
+ emit imageSaved(requestId, actualFileName);
+ } else {
+ emit imageCaptureError(requestId, QCameraImageCapture::OutOfSpaceError, file.errorString());
+ }
+ } else {
+ const QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName);
+ emit imageCaptureError(requestId, QCameraImageCapture::ResourceError, errorMessage);
+ }
+ }
+}
+
+void BbCameraSession::handleVideoRecordingPaused()
+{
+ //TODO: implement once BB10 API supports pausing a video
+}
+
+void BbCameraSession::handleVideoRecordingResumed()
+{
+ if (m_videoStatus == QMediaRecorder::StartingStatus) {
+ m_videoStatus = QMediaRecorder::RecordingStatus;
+ emit videoStatusChanged(m_videoStatus);
+
+ m_videoRecordingDuration.restart();
+ }
+}
+
+void BbCameraSession::deviceOrientationChanged(int angle)
+{
+ if (m_handle != CAMERA_HANDLE_INVALID)
+ camera_set_device_orientation(m_handle, angle);
+}
+
+void BbCameraSession::handleCameraPowerUp()
+{
+ stopViewFinder();
+ startViewFinder();
+}
+
+void BbCameraSession::viewfinderFrameGrabbed(const QImage &image)
+{
+ QTransform transform;
+
+ transform.rotate(m_nativeCameraOrientation);
+
+ QImage frame = image.copy().transformed(transform);
+ if (m_device == cameraIdentifierFront())
+ frame = frame.mirrored(true, false);
+
+ QMutexLocker locker(&m_surfaceMutex);
+ if (m_surface) {
+ if (frame.size() != m_surface->surfaceFormat().frameSize()) {
+ m_surface->stop();
+ m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
+ }
+
+ QVideoFrame videoFrame(frame);
+
+ m_surface->present(videoFrame);
+ }
+}
+
+bool BbCameraSession::openCamera()
+{
+ if (m_handle != CAMERA_HANDLE_INVALID) // camera is already open
+ return true;
+
+ m_status = QCamera::LoadingStatus;
+ emit statusChanged(m_status);
+
+ camera_unit_t unit = CAMERA_UNIT_REAR;
+ if (m_device == cameraIdentifierFront())
+ unit = CAMERA_UNIT_FRONT;
+ else if (m_device == cameraIdentifierRear())
+ unit = CAMERA_UNIT_REAR;
+ else if (m_device == cameraIdentifierDesktop())
+ unit = CAMERA_UNIT_DESKTOP;
+
+ camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &m_handle);
+ if (result != CAMERA_EOK) {
+ m_handle = CAMERA_HANDLE_INVALID;
+ m_status = QCamera::UnloadedStatus;
+ emit statusChanged(m_status);
+
+ qWarning() << "Unable to open camera:" << result;
+ emit error(QCamera::CameraError, tr("Unable to open camera"));
+ return false;
+ }
+
+ result = camera_get_native_orientation(m_handle, &m_nativeCameraOrientation);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve native camera orientation:" << result;
+ emit error(QCamera::CameraError, tr("Unable to retrieve native camera orientation"));
+ return false;
+ }
+
+ m_previewIsVideo = camera_has_feature(m_handle, CAMERA_FEATURE_PREVIEWISVIDEO);
+
+ m_status = QCamera::LoadedStatus;
+ emit statusChanged(m_status);
+
+ emit cameraOpened();
+
+ return true;
+}
+
+void BbCameraSession::closeCamera()
+{
+ if (m_handle == CAMERA_HANDLE_INVALID) // camera is closed already
+ return;
+
+ m_status = QCamera::UnloadingStatus;
+ emit statusChanged(m_status);
+
+ const camera_error_t result = camera_close(m_handle);
+ if (result != CAMERA_EOK) {
+ m_status = QCamera::LoadedStatus;
+ emit statusChanged(m_status);
+
+ qWarning() << "Unable to close camera:" << result;
+ emit error(QCamera::CameraError, tr("Unable to close camera"));
+ return;
+ }
+
+ m_handle = CAMERA_HANDLE_INVALID;
+
+ m_status = QCamera::UnloadedStatus;
+ emit statusChanged(m_status);
+}
+
+static void viewFinderStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
+{
+ Q_UNUSED(handle)
+
+ if (status == CAMERA_STATUS_FOCUS_CHANGE) {
+ BbCameraSession *session = static_cast<BbCameraSession*>(context);
+ QMetaObject::invokeMethod(session, "focusStatusChanged", Qt::QueuedConnection, Q_ARG(int, value));
+ return;
+ }
+#ifndef Q_OS_BLACKBERRY_TABLET
+ else if (status == CAMERA_STATUS_POWERUP) {
+ BbCameraSession *session = static_cast<BbCameraSession*>(context);
+ QMetaObject::invokeMethod(session, "handleCameraPowerUp", Qt::QueuedConnection);
+ }
+#endif
+}
+
+bool BbCameraSession::startViewFinder()
+{
+ m_status = QCamera::StartingStatus;
+ emit statusChanged(m_status);
+
+ QSize viewfinderResolution;
+ camera_error_t result = CAMERA_EOK;
+ if (m_captureMode & QCamera::CaptureStillImage) {
+ result = camera_start_photo_viewfinder(m_handle, 0, viewFinderStatusCallback, this);
+ viewfinderResolution = currentViewfinderResolution(QCamera::CaptureStillImage);
+ } else if (m_captureMode & QCamera::CaptureVideo) {
+ result = camera_start_video_viewfinder(m_handle, 0, viewFinderStatusCallback, this);
+ viewfinderResolution = currentViewfinderResolution(QCamera::CaptureVideo);
+ }
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to start viewfinder:" << result;
+ return false;
+ }
+
+ const int angle = m_orientationHandler->orientation();
+
+ const QSize rotatedSize = ((angle == 0 || angle == 180) ? viewfinderResolution
+ : viewfinderResolution.transposed());
+
+ m_surfaceMutex.lock();
+ if (m_surface) {
+ const bool ok = m_surface->start(QVideoSurfaceFormat(rotatedSize, QVideoFrame::Format_ARGB32));
+ if (!ok)
+ qWarning() << "Unable to start camera viewfinder surface";
+ }
+ m_surfaceMutex.unlock();
+
+ m_status = QCamera::ActiveStatus;
+ emit statusChanged(m_status);
+
+ return true;
+}
+
+void BbCameraSession::stopViewFinder()
+{
+ m_windowGrabber->stop();
+
+ m_status = QCamera::StoppingStatus;
+ emit statusChanged(m_status);
+
+ m_surfaceMutex.lock();
+ if (m_surface) {
+ m_surface->stop();
+ }
+ m_surfaceMutex.unlock();
+
+ camera_error_t result = CAMERA_EOK;
+ if (m_captureMode & QCamera::CaptureStillImage)
+ result = camera_stop_photo_viewfinder(m_handle);
+ else if (m_captureMode & QCamera::CaptureVideo)
+ result = camera_stop_video_viewfinder(m_handle);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to stop viewfinder:" << result;
+ return;
+ }
+
+ m_status = QCamera::LoadedStatus;
+ emit statusChanged(m_status);
+}
+
+void BbCameraSession::applyConfiguration()
+{
+ if (m_captureMode & QCamera::CaptureStillImage) {
+ const QList<QSize> photoOutputResolutions = supportedResolutions(QCamera::CaptureStillImage);
+
+ if (!m_imageEncoderSettings.resolution().isValid() || !photoOutputResolutions.contains(m_imageEncoderSettings.resolution()))
+ m_imageEncoderSettings.setResolution(photoOutputResolutions.first());
+
+ const QSize photoResolution = m_imageEncoderSettings.resolution();
+ const qreal aspectRatio = static_cast<qreal>(photoResolution.width())/static_cast<qreal>(photoResolution.height());
+
+ // apply viewfinder configuration
+ QSize viewfinderResolution;
+ QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureStillImage);
+ std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
+ foreach (const QSize &size, sizes) {
+ // search for viewfinder resolution with the same aspect ratio
+ if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
+ viewfinderResolution = size;
+ break;
+ }
+ }
+
+ Q_ASSERT(viewfinderResolution.isValid());
+
+ const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1();
+ m_windowGrabber->setWindowId(windowId);
+
+ const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
+
+ camera_error_t result = camera_set_photovf_property(m_handle,
+ CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(),
+ CAMERA_IMGPROP_WIN_ID, windowId.data(),
+ CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
+ CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
+ CAMERA_IMGPROP_FORMAT, CAMERA_FRAMETYPE_NV12,
+ CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to apply photo viewfinder settings:" << result;
+ return;
+ }
+
+
+ int jpegQuality = 100;
+ switch (m_imageEncoderSettings.quality()) {
+ case QMultimedia::VeryLowQuality:
+ jpegQuality = 20;
+ break;
+ case QMultimedia::LowQuality:
+ jpegQuality = 40;
+ break;
+ case QMultimedia::NormalQuality:
+ jpegQuality = 60;
+ break;
+ case QMultimedia::HighQuality:
+ jpegQuality = 80;
+ break;
+ case QMultimedia::VeryHighQuality:
+ jpegQuality = 100;
+ break;
+ }
+
+ // apply photo configuration
+ result = camera_set_photo_property(m_handle,
+ CAMERA_IMGPROP_WIDTH, photoResolution.width(),
+ CAMERA_IMGPROP_HEIGHT, photoResolution.height(),
+ CAMERA_IMGPROP_JPEGQFACTOR, jpegQuality,
+ CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to apply photo settings:" << result;
+ return;
+ }
+
+ } else if (m_captureMode & QCamera::CaptureVideo) {
+ applyVideoSettings();
+ }
+
+ startViewFinder();
+}
+
+static void videoRecordingStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
+{
+ Q_UNUSED(handle)
+ Q_UNUSED(value)
+
+#ifndef Q_OS_BLACKBERRY_TABLET
+ if (status == CAMERA_STATUS_VIDEO_PAUSE) {
+ BbCameraSession *session = static_cast<BbCameraSession*>(context);
+ QMetaObject::invokeMethod(session, "handleVideoRecordingPaused", Qt::QueuedConnection);
+ } else if (status == CAMERA_STATUS_VIDEO_RESUME) {
+ BbCameraSession *session = static_cast<BbCameraSession*>(context);
+ QMetaObject::invokeMethod(session, "handleVideoRecordingResumed", Qt::QueuedConnection);
+ }
+#endif
+}
+
+bool BbCameraSession::startVideoRecording()
+{
+ m_videoRecordingDuration.invalidate();
+
+ m_videoStatus = QMediaRecorder::StartingStatus;
+ emit videoStatusChanged(m_videoStatus);
+
+ if (m_videoOutputLocation.isEmpty())
+ m_videoOutputLocation = m_mediaStorageLocation.generateFileName(QLatin1String("VID_"), m_mediaStorageLocation.defaultDir(QCamera::CaptureVideo), QLatin1String("mp4"));
+
+ emit actualLocationChanged(m_videoOutputLocation);
+
+ const camera_error_t result = camera_start_video(m_handle, QFile::encodeName(m_videoOutputLocation), 0, videoRecordingStatusCallback, this);
+ if (result != CAMERA_EOK) {
+ m_videoStatus = QMediaRecorder::LoadedStatus;
+ emit videoStatusChanged(m_videoStatus);
+
+ emit videoError(QMediaRecorder::ResourceError, tr("Unable to start video recording"));
+ return false;
+ }
+
+ return true;
+}
+
+void BbCameraSession::stopVideoRecording()
+{
+ m_videoStatus = QMediaRecorder::FinalizingStatus;
+ emit videoStatusChanged(m_videoStatus);
+
+ const camera_error_t result = camera_stop_video(m_handle);
+ if (result != CAMERA_EOK) {
+ emit videoError(QMediaRecorder::ResourceError, tr("Unable to stop video recording"));
+ }
+
+ m_videoStatus = QMediaRecorder::LoadedStatus;
+ emit videoStatusChanged(m_videoStatus);
+
+ m_videoRecordingDuration.invalidate();
+}
+
+bool BbCameraSession::isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const
+{
+ if (mode & QCamera::CaptureStillImage)
+ return camera_has_feature(handle, CAMERA_FEATURE_PHOTO);
+
+ if (mode & QCamera::CaptureVideo)
+ return camera_has_feature(handle, CAMERA_FEATURE_VIDEO);
+
+ return false;
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(QCamera::CaptureMode mode) const
+{
+ Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+ QList<QSize> list;
+
+ camera_error_t result = CAMERA_EOK;
+ camera_res_t resolutions[20];
+ unsigned int supported = 0;
+
+ if (mode == QCamera::CaptureStillImage)
+ result = camera_get_photo_output_resolutions(m_handle, CAMERA_FRAMETYPE_JPEG, 20, &supported, resolutions);
+ else if (mode == QCamera::CaptureVideo)
+ result = camera_get_video_output_resolutions(m_handle, 20, &supported, resolutions);
+
+ if (result != CAMERA_EOK)
+ return list;
+
+ for (unsigned int i = 0; i < supported; ++i)
+ list << QSize(resolutions[i].width, resolutions[i].height);
+
+ return list;
+}
+
+QList<QSize> BbCameraSession::supportedViewfinderResolutions(QCamera::CaptureMode mode) const
+{
+ Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+ QList<QSize> list;
+
+ camera_error_t result = CAMERA_EOK;
+ camera_res_t resolutions[20];
+ unsigned int supported = 0;
+
+ if (mode == QCamera::CaptureStillImage)
+ result = camera_get_photo_vf_resolutions(m_handle, 20, &supported, resolutions);
+ else if (mode == QCamera::CaptureVideo)
+ result = camera_get_video_vf_resolutions(m_handle, 20, &supported, resolutions);
+
+ if (result != CAMERA_EOK)
+ return list;
+
+ for (unsigned int i = 0; i < supported; ++i)
+ list << QSize(resolutions[i].width, resolutions[i].height);
+
+ return list;
+}
+
+QSize BbCameraSession::currentViewfinderResolution(QCamera::CaptureMode mode) const
+{
+ Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+ camera_error_t result = CAMERA_EOK;
+ int width = 0;
+ int height = 0;
+
+ if (mode == QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
+ CAMERA_IMGPROP_HEIGHT, &height);
+ else if (mode == QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
+ CAMERA_IMGPROP_HEIGHT, &height);
+
+ if (result != CAMERA_EOK)
+ return QSize();
+
+ return QSize(width, height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcamerasession.h b/src/plugins/qnx/camera/bbcamerasession.h
new file mode 100644
index 000000000..e757a83c3
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerasession.h
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERASESSION_H
+#define BBCAMERASESSION_H
+
+#include "bbmediastoragelocation.h"
+
+#include <QCamera>
+#include <QCameraImageCapture>
+#include <QCameraViewfinderSettingsControl>
+#include <QElapsedTimer>
+#include <QMediaRecorder>
+#include <QMutex>
+#include <QObject>
+#include <QPointer>
+
+#include <camera/camera_api.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraOrientationHandler;
+class WindowGrabber;
+
+class BbCameraSession : public QObject
+{
+ Q_OBJECT
+public:
+ explicit BbCameraSession(QObject *parent = 0);
+ ~BbCameraSession();
+
+ camera_handle_t handle() const;
+
+ // camera control
+ QCamera::State state() const;
+ void setState(QCamera::State state);
+ QCamera::Status status() const;
+ QCamera::CaptureModes captureMode() const;
+ void setCaptureMode(QCamera::CaptureModes);
+ bool isCaptureModeSupported(QCamera::CaptureModes mode) const;
+
+ // video device selector control
+ static QByteArray cameraIdentifierFront();
+ static QByteArray cameraIdentifierRear();
+ static QByteArray cameraIdentifierDesktop();
+
+ void setDevice(const QByteArray &device);
+ QByteArray device() const;
+
+ // video renderer control
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+ // image capture control
+ bool isReadyForCapture() const;
+ QCameraImageCapture::DriveMode driveMode() const;
+ void setDriveMode(QCameraImageCapture::DriveMode mode);
+ int capture(const QString &fileName);
+ void cancelCapture();
+
+ // capture destination control
+ bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const;
+ QCameraImageCapture::CaptureDestinations captureDestination() const;
+ void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination);
+
+ // image encoder control
+ QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const;
+ QImageEncoderSettings imageSettings() const;
+ void setImageSettings(const QImageEncoderSettings &settings);
+
+ // media recorder control
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &location);
+ QMediaRecorder::State videoState() const;
+ void setVideoState(QMediaRecorder::State state);
+ QMediaRecorder::Status videoStatus() const;
+ qint64 duration() const;
+ void applyVideoSettings();
+
+ // video encoder settings control
+ QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const;
+ QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const;
+ QVideoEncoderSettings videoSettings() const;
+ void setVideoSettings(const QVideoEncoderSettings &settings);
+
+ // audio encoder settings control
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings &settings);
+
+Q_SIGNALS:
+ // camera control
+ void statusChanged(QCamera::Status);
+ void stateChanged(QCamera::State);
+ void error(int error, const QString &errorString);
+ void captureModeChanged(QCamera::CaptureModes);
+
+ // image capture control
+ void readyForCaptureChanged(bool);
+ void imageExposed(int id);
+ void imageCaptured(int id, const QImage &preview);
+ void imageMetadataAvailable(int id, const QString &key, const QVariant &value);
+ void imageAvailable(int id, const QVideoFrame &buffer);
+ void imageSaved(int id, const QString &fileName);
+ void imageCaptureError(int id, int error, const QString &errorString);
+
+ // capture destination control
+ void captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination);
+
+ // media recorder control
+ void videoStateChanged(QMediaRecorder::State state);
+ void videoStatusChanged(QMediaRecorder::Status status);
+ void durationChanged(qint64 duration);
+ void actualLocationChanged(const QUrl &location);
+ void videoError(int error, const QString &errorString);
+
+ void cameraOpened();
+ void focusStatusChanged(int status);
+
+private slots:
+ void updateReadyForCapture();
+ void imageCaptured(int, const QImage&, const QString&);
+ void handleVideoRecordingPaused();
+ void handleVideoRecordingResumed();
+ void deviceOrientationChanged(int);
+ void handleCameraPowerUp();
+ void viewfinderFrameGrabbed(const QImage &image);
+ void applyConfiguration();
+
+private:
+ bool openCamera();
+ void closeCamera();
+ bool startViewFinder();
+ void stopViewFinder();
+ bool startVideoRecording();
+ void stopVideoRecording();
+
+ bool isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const;
+ QList<QSize> supportedResolutions(QCamera::CaptureMode mode) const;
+ QList<QSize> supportedViewfinderResolutions(QCamera::CaptureMode mode) const;
+ QSize currentViewfinderResolution(QCamera::CaptureMode mode) const;
+
+ quint32 m_nativeCameraOrientation;
+ BbCameraOrientationHandler* m_orientationHandler;
+
+ QCamera::Status m_status;
+ QCamera::State m_state;
+ QCamera::CaptureModes m_captureMode;
+
+ QByteArray m_device;
+ bool m_previewIsVideo;
+
+ QPointer<QAbstractVideoSurface> m_surface;
+ QMutex m_surfaceMutex;
+
+ QCameraImageCapture::DriveMode m_captureImageDriveMode;
+ int m_lastImageCaptureId;
+ QCameraImageCapture::CaptureDestinations m_captureDestination;
+
+ QImageEncoderSettings m_imageEncoderSettings;
+
+ QString m_videoOutputLocation;
+ QMediaRecorder::State m_videoState;
+ QMediaRecorder::Status m_videoStatus;
+ QElapsedTimer m_videoRecordingDuration;
+
+ QVideoEncoderSettings m_videoEncoderSettings;
+ QAudioEncoderSettings m_audioEncoderSettings;
+
+ BbMediaStorageLocation m_mediaStorageLocation;
+
+ camera_handle_t m_handle;
+
+ WindowGrabber* m_windowGrabber;
+};
+
+QDebug operator<<(QDebug debug, camera_error_t error);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp
new file mode 100644
index 000000000..eae448e5b
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameravideoencodersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraVideoEncoderSettingsControl::BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent)
+ : QVideoEncoderSettingsControl(parent)
+ , m_session(session)
+{
+}
+
+QList<QSize> BbCameraVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ return m_session->supportedResolutions(settings, continuous);
+}
+
+QList<qreal> BbCameraVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ return m_session->supportedFrameRates(settings, continuous);
+}
+
+QStringList BbCameraVideoEncoderSettingsControl::supportedVideoCodecs() const
+{
+ return QStringList() << QLatin1String("none") << QLatin1String("avc1") << QLatin1String("h264");
+}
+
+QString BbCameraVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const
+{
+ if (codecName == QLatin1String("none"))
+ return tr("No compression");
+ else if (codecName == QLatin1String("avc1"))
+ return tr("AVC1 compression");
+ else if (codecName == QLatin1String("h264"))
+ return tr("H264 compression");
+
+ return QString();
+}
+
+QVideoEncoderSettings BbCameraVideoEncoderSettingsControl::videoSettings() const
+{
+ return m_session->videoSettings();
+}
+
+void BbCameraVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings)
+{
+ m_session->setVideoSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h
new file mode 100644
index 000000000..8ecf49c85
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameravideoencodersettingscontrol.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAVIDEOENCODERSETTINGSCONTROL_H
+#define BBCAMERAVIDEOENCODERSETTINGSCONTROL_H
+
+#include <qvideoencodersettingscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraVideoEncoderSettingsControl : public QVideoEncoderSettingsControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0);
+
+ QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+ QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+ QStringList supportedVideoCodecs() const Q_DECL_OVERRIDE;
+ QString videoCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+ QVideoEncoderSettings videoSettings() const Q_DECL_OVERRIDE;
+ void setVideoSettings(const QVideoEncoderSettings &settings) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp
new file mode 100644
index 000000000..5c7671e80
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraviewfindersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraViewfinderSettingsControl::BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent)
+ : QCameraViewfinderSettingsControl(parent)
+ , m_session(session)
+{
+}
+
+bool BbCameraViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const
+{
+ switch (parameter) {
+ case QCameraViewfinderSettingsControl::Resolution:
+ return true;
+ case QCameraViewfinderSettingsControl::PixelAspectRatio:
+ return false;
+ case QCameraViewfinderSettingsControl::MinimumFrameRate:
+ return true;
+ case QCameraViewfinderSettingsControl::MaximumFrameRate:
+ return true;
+ case QCameraViewfinderSettingsControl::PixelFormat:
+ return true;
+ default:
+ return false;
+ }
+}
+
+QVariant BbCameraViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const
+{
+ if (parameter == QCameraViewfinderSettingsControl::Resolution) {
+ camera_error_t result = CAMERA_EOK;
+ unsigned int width = 0;
+ unsigned int height = 0;
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage) {
+ result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width,
+ CAMERA_IMGPROP_HEIGHT, &height);
+ } else if (m_session->captureMode() & QCamera::CaptureVideo) {
+ result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width,
+ CAMERA_IMGPROP_HEIGHT, &height);
+ }
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve resolution of viewfinder:" << result;
+ return QVariant();
+ }
+
+ return QSize(width, height);
+
+ } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) {
+ camera_error_t result = CAMERA_EOK;
+ double minimumFrameRate = 0;
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve minimum framerate of viewfinder:" << result;
+ return QVariant();
+ }
+
+ return QVariant(static_cast<qreal>(minimumFrameRate));
+
+ } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) {
+ camera_error_t result = CAMERA_EOK;
+ double maximumFrameRate = 0;
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve maximum framerate of viewfinder:" << result;
+ return QVariant();
+ }
+
+ return QVariant(static_cast<qreal>(maximumFrameRate));
+ } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) {
+ camera_error_t result = CAMERA_EOK;
+ camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED;
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve pixel format of viewfinder:" << result;
+ return QVariant();
+ }
+
+ switch (format) {
+ case CAMERA_FRAMETYPE_UNSPECIFIED:
+ return QVideoFrame::Format_Invalid;
+ case CAMERA_FRAMETYPE_NV12:
+ return QVideoFrame::Format_NV12;
+ case CAMERA_FRAMETYPE_RGB8888:
+ return QVideoFrame::Format_ARGB32;
+ case CAMERA_FRAMETYPE_RGB888:
+ return QVideoFrame::Format_RGB24;
+ case CAMERA_FRAMETYPE_JPEG:
+ return QVideoFrame::Format_Jpeg;
+ case CAMERA_FRAMETYPE_GRAY8:
+ return QVideoFrame::Format_Y8;
+ case CAMERA_FRAMETYPE_METADATA:
+ return QVideoFrame::Format_Invalid;
+ case CAMERA_FRAMETYPE_BAYER:
+ return QVideoFrame::Format_Invalid;
+ case CAMERA_FRAMETYPE_CBYCRY:
+ return QVideoFrame::Format_Invalid;
+#ifndef Q_OS_BLACKBERRY_TABLET
+ case CAMERA_FRAMETYPE_COMPRESSEDVIDEO:
+ return QVideoFrame::Format_Invalid;
+ case CAMERA_FRAMETYPE_COMPRESSEDAUDIO:
+ return QVideoFrame::Format_Invalid;
+#endif
+ default:
+ return QVideoFrame::Format_Invalid;
+ }
+ }
+
+ return QVariant();
+}
+
+void BbCameraViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value)
+{
+ if (parameter == QCameraViewfinderSettingsControl::Resolution) {
+ camera_error_t result = CAMERA_EOK;
+ const QSize size = value.toSize();
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage) {
+ result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(),
+ CAMERA_IMGPROP_HEIGHT, size.height());
+ } else if (m_session->captureMode() & QCamera::CaptureVideo) {
+ result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(),
+ CAMERA_IMGPROP_HEIGHT, size.height());
+ }
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to set resolution of viewfinder:" << result;
+
+ } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) {
+ camera_error_t result = CAMERA_EOK;
+ const double minimumFrameRate = value.toReal();
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate);
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to set minimum framerate of viewfinder:" << result;
+
+ } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) {
+ camera_error_t result = CAMERA_EOK;
+ const double maximumFrameRate = value.toReal();
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate);
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to set maximum framerate of viewfinder:" << result;
+
+ } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) {
+ camera_error_t result = CAMERA_EOK;
+ camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED;
+
+ switch (value.value<QVideoFrame::PixelFormat>()) {
+ case QVideoFrame::Format_NV12:
+ format = CAMERA_FRAMETYPE_NV12;
+ break;
+ case QVideoFrame::Format_ARGB32:
+ format = CAMERA_FRAMETYPE_RGB8888;
+ break;
+ case QVideoFrame::Format_RGB24:
+ format = CAMERA_FRAMETYPE_RGB888;
+ break;
+ case QVideoFrame::Format_Jpeg:
+ format = CAMERA_FRAMETYPE_JPEG;
+ break;
+ case QVideoFrame::Format_Y8:
+ format = CAMERA_FRAMETYPE_GRAY8;
+ break;
+ default:
+ format = CAMERA_FRAMETYPE_UNSPECIFIED;
+ break;
+ }
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format);
+
+ if (result != CAMERA_EOK)
+ qWarning() << "Unable to set pixel format of viewfinder:" << result;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h
new file mode 100644
index 000000000..f1434c31c
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcameraviewfindersettingscontrol.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAVIEWVINDERSETTINGSCONTROL_H
+#define BBCAMERAVIEWVINDERSETTINGSCONTROL_H
+
+#include <qcameraviewfindersettingscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraViewfinderSettingsControl : public QCameraViewfinderSettingsControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent = 0);
+
+ bool isViewfinderParameterSupported(ViewfinderParameter parameter) const Q_DECL_OVERRIDE;
+ QVariant viewfinderParameter(ViewfinderParameter parameter) const Q_DECL_OVERRIDE;
+ void setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbcamerazoomcontrol.cpp b/src/plugins/qnx/camera/bbcamerazoomcontrol.cpp
new file mode 100644
index 000000000..f73cf000a
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerazoomcontrol.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerazoomcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraZoomControl::BbCameraZoomControl(BbCameraSession *session, QObject *parent)
+ : QCameraZoomControl(parent)
+ , m_session(session)
+ , m_minimumZoomFactor(1.0)
+ , m_maximumZoomFactor(1.0)
+ , m_supportsSmoothZoom(false)
+ , m_requestedZoomFactor(1.0)
+{
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
+}
+
+qreal BbCameraZoomControl::maximumOpticalZoom() const
+{
+ //TODO: optical zoom support not available in BB10 API yet
+ return 1.0;
+}
+
+qreal BbCameraZoomControl::maximumDigitalZoom() const
+{
+ return m_maximumZoomFactor;
+}
+
+qreal BbCameraZoomControl::requestedOpticalZoom() const
+{
+ //TODO: optical zoom support not available in BB10 API yet
+ return 1.0;
+}
+
+qreal BbCameraZoomControl::requestedDigitalZoom() const
+{
+ return currentDigitalZoom();
+}
+
+qreal BbCameraZoomControl::currentOpticalZoom() const
+{
+ //TODO: optical zoom support not available in BB10 API yet
+ return 1.0;
+}
+
+qreal BbCameraZoomControl::currentDigitalZoom() const
+{
+ if (m_session->status() != QCamera::ActiveStatus)
+ return 1.0;
+
+ unsigned int zoomFactor = 0;
+ camera_error_t result = CAMERA_EOK;
+
+ if (m_session->captureMode() & QCamera::CaptureStillImage)
+ result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor);
+ else if (m_session->captureMode() & QCamera::CaptureVideo)
+ result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor);
+
+ if (result != CAMERA_EOK)
+ return 1.0;
+
+ return zoomFactor;
+}
+
+void BbCameraZoomControl::zoomTo(qreal optical, qreal digital)
+{
+ Q_UNUSED(optical)
+
+ if (m_session->status() != QCamera::ActiveStatus)
+ return;
+
+ const qreal actualZoom = qBound(m_minimumZoomFactor, digital, m_maximumZoomFactor);
+
+ const camera_error_t result = camera_set_zoom(m_session->handle(), actualZoom, false);
+
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to change zoom factor:" << result;
+ return;
+ }
+
+ if (m_requestedZoomFactor != digital) {
+ m_requestedZoomFactor = digital;
+ emit requestedDigitalZoomChanged(m_requestedZoomFactor);
+ }
+
+ emit currentDigitalZoomChanged(actualZoom);
+}
+
+void BbCameraZoomControl::statusChanged(QCamera::Status status)
+{
+ if (status == QCamera::ActiveStatus) {
+ // retrieve information about zoom limits
+ unsigned int maximumZoomLimit = 0;
+ unsigned int minimumZoomLimit = 0;
+ bool smoothZoom = false;
+
+ const camera_error_t result = camera_get_zoom_limits(m_session->handle(), &maximumZoomLimit, &minimumZoomLimit, &smoothZoom);
+ if (result == CAMERA_EOK) {
+ const qreal oldMaximumZoomFactor = m_maximumZoomFactor;
+ m_maximumZoomFactor = maximumZoomLimit;
+
+ if (oldMaximumZoomFactor != m_maximumZoomFactor)
+ emit maximumDigitalZoomChanged(m_maximumZoomFactor);
+
+ m_minimumZoomFactor = minimumZoomLimit;
+ m_supportsSmoothZoom = smoothZoom;
+ } else {
+ m_maximumZoomFactor = 1.0;
+ m_minimumZoomFactor = 1.0;
+ m_supportsSmoothZoom = false;
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbcamerazoomcontrol.h b/src/plugins/qnx/camera/bbcamerazoomcontrol.h
new file mode 100644
index 000000000..a1fecab89
--- /dev/null
+++ b/src/plugins/qnx/camera/bbcamerazoomcontrol.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAZOOMCONTROL_H
+#define BBCAMERAZOOMCONTROL_H
+
+#include <qcamera.h>
+#include <qcamerazoomcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraZoomControl : public QCameraZoomControl
+{
+ Q_OBJECT
+public:
+ explicit BbCameraZoomControl(BbCameraSession *session, QObject *parent = 0);
+
+ qreal maximumOpticalZoom() const Q_DECL_OVERRIDE;
+ qreal maximumDigitalZoom() const Q_DECL_OVERRIDE;
+ qreal requestedOpticalZoom() const Q_DECL_OVERRIDE;
+ qreal requestedDigitalZoom() const Q_DECL_OVERRIDE;
+ qreal currentOpticalZoom() const Q_DECL_OVERRIDE;
+ qreal currentDigitalZoom() const Q_DECL_OVERRIDE;
+ void zoomTo(qreal optical, qreal digital) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+ void statusChanged(QCamera::Status status);
+
+private:
+ BbCameraSession *m_session;
+
+ qreal m_minimumZoomFactor;
+ qreal m_maximumZoomFactor;
+ bool m_supportsSmoothZoom;
+ qreal m_requestedZoomFactor;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/audio/qnxaudioplugin.cpp b/src/plugins/qnx/camera/bbimageencodercontrol.cpp
index f63474f90..1265b9ca4 100644
--- a/src/plugins/qnx/audio/qnxaudioplugin.cpp
+++ b/src/plugins/qnx/camera/bbimageencodercontrol.cpp
@@ -38,51 +38,44 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "bbimageencodercontrol.h"
-#include "qnxaudioplugin.h"
-
-#include "qnxaudiodeviceinfo.h"
-#include "qnxaudioinput.h"
-#include "qnxaudiooutput.h"
-
-#include <sys/asoundlib.h>
-
-static const char *INPUT_ID = "QnxAudioInput";
-static const char *OUTPUT_ID = "QnxAudioOutput";
+#include "bbcamerasession.h"
QT_BEGIN_NAMESPACE
-QnxAudioPlugin::QnxAudioPlugin(QObject *parent)
- : QAudioSystemPlugin(parent)
+BbImageEncoderControl::BbImageEncoderControl(BbCameraSession *session, QObject *parent)
+ : QImageEncoderControl(parent)
+ , m_session(session)
{
}
-QList<QByteArray> QnxAudioPlugin::availableDevices(QAudio::Mode mode) const
+QStringList BbImageEncoderControl::supportedImageCodecs() const
{
- if (mode == QAudio::AudioOutput)
- return QList<QByteArray>() << OUTPUT_ID;
- else
- return QList<QByteArray>() << INPUT_ID;
+ return QStringList() << QLatin1String("jpeg");
+}
+
+QString BbImageEncoderControl::imageCodecDescription(const QString &codecName) const
+{
+ if (codecName == QLatin1String("jpeg"))
+ return tr("JPEG image");
+
+ return QString();
}
-QAbstractAudioInput *QnxAudioPlugin::createInput(const QByteArray &device)
+QList<QSize> BbImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
{
- Q_ASSERT(device == INPUT_ID);
- Q_UNUSED(device);
- return new QnxAudioInput();
+ return m_session->supportedResolutions(settings, continuous);
}
-QAbstractAudioOutput *QnxAudioPlugin::createOutput(const QByteArray &device)
+QImageEncoderSettings BbImageEncoderControl::imageSettings() const
{
- Q_ASSERT(device == OUTPUT_ID);
- Q_UNUSED(device);
- return new QnxAudioOutput();
+ return m_session->imageSettings();
}
-QAbstractAudioDeviceInfo *QnxAudioPlugin::createDeviceInfo(const QByteArray &device, QAudio::Mode mode)
+void BbImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
{
- Q_ASSERT(device == OUTPUT_ID || device == INPUT_ID);
- return new QnxAudioDeviceInfo(device, mode);
+ m_session->setImageSettings(settings);
}
QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbimageencodercontrol.h b/src/plugins/qnx/camera/bbimageencodercontrol.h
new file mode 100644
index 000000000..4db2e7def
--- /dev/null
+++ b/src/plugins/qnx/camera/bbimageencodercontrol.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBIMAGEENCODERCONTROL_H
+#define BBIMAGEENCODERCONTROL_H
+
+#include <qimageencodercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbImageEncoderControl : public QImageEncoderControl
+{
+ Q_OBJECT
+public:
+ explicit BbImageEncoderControl(BbCameraSession *session, QObject *parent = 0);
+
+ QStringList supportedImageCodecs() const Q_DECL_OVERRIDE;
+ QString imageCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+ QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+ QImageEncoderSettings imageSettings() const Q_DECL_OVERRIDE;
+ void setImageSettings(const QImageEncoderSettings &settings) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbmediastoragelocation.cpp b/src/plugins/qnx/camera/bbmediastoragelocation.cpp
new file mode 100644
index 000000000..3d939ce4f
--- /dev/null
+++ b/src/plugins/qnx/camera/bbmediastoragelocation.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbmediastoragelocation.h"
+
+#include <QStandardPaths>
+
+QT_BEGIN_NAMESPACE
+
+BbMediaStorageLocation::BbMediaStorageLocation()
+{
+}
+
+QDir BbMediaStorageLocation::defaultDir(QCamera::CaptureMode mode) const
+{
+ QStringList dirCandidates;
+
+ dirCandidates << QLatin1String("shared/camera");
+
+ if (mode == QCamera::CaptureVideo) {
+ dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
+ } else {
+ dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
+ }
+
+ dirCandidates << QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
+ dirCandidates << QDir::homePath();
+ dirCandidates << QDir::currentPath();
+ dirCandidates << QDir::tempPath();
+
+ Q_FOREACH (const QString &path, dirCandidates) {
+ if (QFileInfo(path).isWritable())
+ return QDir(path);
+ }
+
+ return QDir();
+}
+
+QString BbMediaStorageLocation::generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const
+{
+ if (requestedName.isEmpty())
+ return generateFileName(prefix, defaultDir(mode), extension);
+
+ if (QFileInfo(requestedName).isDir())
+ return generateFileName(prefix, QDir(requestedName), extension);
+
+ return requestedName;
+}
+
+QString BbMediaStorageLocation::generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const
+{
+ const QString lastMediaKey = dir.absolutePath() + QLatin1Char(' ') + prefix + QLatin1Char(' ') + extension;
+ qint64 lastMediaIndex = m_lastUsedIndex.value(lastMediaKey, 0);
+
+ if (lastMediaIndex == 0) {
+ // first run, find the maximum media number during the fist capture
+ Q_FOREACH (const QString &fileName, dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(extension))) {
+ const qint64 mediaIndex = fileName.mid(prefix.length(), fileName.size() - prefix.length() - extension.length() - 1).toInt();
+ lastMediaIndex = qMax(lastMediaIndex, mediaIndex);
+ }
+ }
+
+ // don't just rely on cached lastMediaIndex value,
+ // someone else may create a file after camera started
+ while (true) {
+ const QString name = QString("%1%2.%3").arg(prefix)
+ .arg(lastMediaIndex + 1, 8, 10, QLatin1Char('0'))
+ .arg(extension);
+
+ const QString path = dir.absoluteFilePath(name);
+ if (!QFileInfo(path).exists()) {
+ m_lastUsedIndex[lastMediaKey] = lastMediaIndex + 1;
+ return path;
+ }
+
+ lastMediaIndex++;
+ }
+
+ return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbmediastoragelocation.h b/src/plugins/qnx/camera/bbmediastoragelocation.h
new file mode 100644
index 000000000..efa89c8ed
--- /dev/null
+++ b/src/plugins/qnx/camera/bbmediastoragelocation.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBMEDIASTORAGELOCATION_H
+#define BBMEDIASTORAGELOCATION_H
+
+#include <QCamera>
+#include <QDir>
+#include <QHash>
+
+QT_BEGIN_NAMESPACE
+
+class BbMediaStorageLocation
+{
+public:
+ BbMediaStorageLocation();
+
+ QDir defaultDir(QCamera::CaptureMode mode) const;
+
+ QString generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const;
+ QString generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const;
+
+private:
+ mutable QHash<QString, qint64> m_lastUsedIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp
new file mode 100644
index 000000000..6a6e9d3cd
--- /dev/null
+++ b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbvideodeviceselectorcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbVideoDeviceSelectorControl::BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent)
+ : QVideoDeviceSelectorControl(parent)
+ , m_session(session)
+ , m_selected(0)
+{
+ enumerateDevices(&m_devices, &m_descriptions);
+
+ // pre-select the rear camera
+ const int index = m_devices.indexOf(BbCameraSession::cameraIdentifierRear());
+ if (index != -1)
+ m_selected = index;
+}
+
+int BbVideoDeviceSelectorControl::deviceCount() const
+{
+ return m_devices.count();
+}
+
+QString BbVideoDeviceSelectorControl::deviceName(int index) const
+{
+ if (index < 0 || index >= m_devices.count())
+ return QString();
+
+ return QString::fromUtf8(m_devices.at(index));
+}
+
+QString BbVideoDeviceSelectorControl::deviceDescription(int index) const
+{
+ if (index < 0 || index >= m_descriptions.count())
+ return QString();
+
+ return m_descriptions.at(index);
+}
+
+int BbVideoDeviceSelectorControl::defaultDevice() const
+{
+ return 0;
+}
+
+int BbVideoDeviceSelectorControl::selectedDevice() const
+{
+ return m_selected;
+}
+
+void BbVideoDeviceSelectorControl::enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions)
+{
+ devices->clear();
+ descriptions->clear();
+
+ camera_unit_t cameras[10];
+
+ unsigned int knownCameras = 0;
+ const camera_error_t result = camera_get_supported_cameras(10, &knownCameras, cameras);
+ if (result != CAMERA_EOK) {
+ qWarning() << "Unable to retrieve supported camera types:" << result;
+ return;
+ }
+
+ for (unsigned int i = 0; i < knownCameras; ++i) {
+ switch (cameras[i]) {
+ case CAMERA_UNIT_FRONT:
+ devices->append(BbCameraSession::cameraIdentifierFront());
+ descriptions->append(tr("Front Camera"));
+ break;
+ case CAMERA_UNIT_REAR:
+ devices->append(BbCameraSession::cameraIdentifierRear());
+ descriptions->append(tr("Rear Camera"));
+ break;
+ case CAMERA_UNIT_DESKTOP:
+ devices->append(BbCameraSession::cameraIdentifierDesktop());
+ descriptions->append(tr("Desktop Camera"));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void BbVideoDeviceSelectorControl::setSelectedDevice(int index)
+{
+ if (index < 0 || index >= m_devices.count())
+ return;
+
+ if (!m_session)
+ return;
+
+ const QByteArray device = m_devices.at(index);
+ if (device == m_session->device())
+ return;
+
+ m_session->setDevice(device);
+ m_selected = index;
+
+ emit selectedDeviceChanged(QString::fromUtf8(device));
+ emit selectedDeviceChanged(index);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h
new file mode 100644
index 000000000..1987f5491
--- /dev/null
+++ b/src/plugins/qnx/camera/bbvideodeviceselectorcontrol.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBVIDEODEVICESELECTORCONTROL_H
+#define BBVIDEODEVICESELECTORCONTROL_H
+
+#include <qvideodeviceselectorcontrol.h>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbVideoDeviceSelectorControl : public QVideoDeviceSelectorControl
+{
+ Q_OBJECT
+public:
+ explicit BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent = 0);
+
+ int deviceCount() const Q_DECL_OVERRIDE;
+ QString deviceName(int index) const Q_DECL_OVERRIDE;
+ QString deviceDescription(int index) const Q_DECL_OVERRIDE;
+ int defaultDevice() const Q_DECL_OVERRIDE;
+ int selectedDevice() const Q_DECL_OVERRIDE;
+
+ static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions);
+
+public Q_SLOTS:
+ void setSelectedDevice(int index) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession* m_session;
+
+ QList<QByteArray> m_devices;
+ QStringList m_descriptions;
+
+ int m_selected;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/bbvideorenderercontrol.cpp b/src/plugins/qnx/camera/bbvideorenderercontrol.cpp
new file mode 100644
index 000000000..4fadf9afb
--- /dev/null
+++ b/src/plugins/qnx/camera/bbvideorenderercontrol.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bbvideorenderercontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbVideoRendererControl::BbVideoRendererControl(BbCameraSession *session, QObject *parent)
+ : QVideoRendererControl(parent)
+ , m_session(session)
+{
+}
+
+QAbstractVideoSurface* BbVideoRendererControl::surface() const
+{
+ return m_session->surface();
+}
+
+void BbVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+{
+ m_session->setSurface(surface);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/camera/bbvideorenderercontrol.h b/src/plugins/qnx/camera/bbvideorenderercontrol.h
new file mode 100644
index 000000000..93b2b6475
--- /dev/null
+++ b/src/plugins/qnx/camera/bbvideorenderercontrol.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBVIDEORENDERERCONTROL_H
+#define BBVIDEORENDERERCONTROL_H
+
+#include <qvideorenderercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbVideoRendererControl : public QVideoRendererControl
+{
+ Q_OBJECT
+public:
+ explicit BbVideoRendererControl(BbCameraSession *session, QObject *parent = 0);
+
+ QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE;
+ void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE;
+
+private:
+ BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/camera/camera.pri b/src/plugins/qnx/camera/camera.pri
new file mode 100644
index 000000000..6665573b0
--- /dev/null
+++ b/src/plugins/qnx/camera/camera.pri
@@ -0,0 +1,53 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/bbcameraaudioencodersettingscontrol.h \
+ $$PWD/bbcameracapturebufferformatcontrol.h \
+ $$PWD/bbcameracapturedestinationcontrol.h \
+ $$PWD/bbcameracontrol.h \
+ $$PWD/bbcameraexposurecontrol.h \
+ $$PWD/bbcameraflashcontrol.h \
+ $$PWD/bbcamerafocuscontrol.h \
+ $$PWD/bbcameraimagecapturecontrol.h \
+ $$PWD/bbcameraimageprocessingcontrol.h \
+ $$PWD/bbcameralockscontrol.h \
+ $$PWD/bbcameramediarecordercontrol.h \
+ $$PWD/bbcameraorientationhandler.h \
+ $$PWD/bbcameraservice.h \
+ $$PWD/bbcamerasession.h \
+ $$PWD/bbcameravideoencodersettingscontrol.h \
+ $$PWD/bbcameraviewfindersettingscontrol.h \
+ $$PWD/bbcamerazoomcontrol.h \
+ $$PWD/bbimageencodercontrol.h \
+ $$PWD/bbmediastoragelocation.h \
+ $$PWD/bbvideodeviceselectorcontrol.h \
+ $$PWD/bbvideorenderercontrol.h
+
+SOURCES += \
+ $$PWD/bbcameraaudioencodersettingscontrol.cpp \
+ $$PWD/bbcameracapturebufferformatcontrol.cpp \
+ $$PWD/bbcameracapturedestinationcontrol.cpp \
+ $$PWD/bbcameracontrol.cpp \
+ $$PWD/bbcameraexposurecontrol.cpp \
+ $$PWD/bbcameraflashcontrol.cpp \
+ $$PWD/bbcamerafocuscontrol.cpp \
+ $$PWD/bbcameraimagecapturecontrol.cpp \
+ $$PWD/bbcameraimageprocessingcontrol.cpp \
+ $$PWD/bbcameralockscontrol.cpp \
+ $$PWD/bbcameramediarecordercontrol.cpp \
+ $$PWD/bbcameraorientationhandler.cpp \
+ $$PWD/bbcameraservice.cpp \
+ $$PWD/bbcamerasession.cpp \
+ $$PWD/bbcameravideoencodersettingscontrol.cpp \
+ $$PWD/bbcameraviewfindersettingscontrol.cpp \
+ $$PWD/bbcamerazoomcontrol.cpp \
+ $$PWD/bbimageencodercontrol.cpp \
+ $$PWD/bbmediastoragelocation.cpp \
+ $$PWD/bbvideodeviceselectorcontrol.cpp \
+ $$PWD/bbvideorenderercontrol.cpp
+
+LIBS += -lcamapi
+
+!blackberry-playbook {
+ LIBS += -laudio_manager
+}
diff --git a/src/plugins/qnx/common/common.pri b/src/plugins/qnx/common/common.pri
new file mode 100644
index 000000000..1a6693474
--- /dev/null
+++ b/src/plugins/qnx/common/common.pri
@@ -0,0 +1,7 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/windowgrabber.h
+
+SOURCES += \
+ $$PWD/windowgrabber.cpp
diff --git a/src/plugins/qnx/common/windowgrabber.cpp b/src/plugins/qnx/common/windowgrabber.cpp
new file mode 100644
index 000000000..5ed54b87e
--- /dev/null
+++ b/src/plugins/qnx/common/windowgrabber.cpp
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "windowgrabber.h"
+
+#include <QAbstractEventDispatcher>
+#include <QDebug>
+#include <QGuiApplication>
+#include <QImage>
+#include <qpa/qplatformnativeinterface.h>
+
+#ifdef Q_OS_BLACKBERRY
+#include <bps/event.h>
+#include <bps/screen.h>
+#endif
+#include <errno.h>
+
+QT_BEGIN_NAMESPACE
+
+WindowGrabber::WindowGrabber(QObject *parent)
+ : QObject(parent),
+ m_screenBuffer(0),
+ m_screenBufferWidth(-1),
+ m_screenBufferHeight(-1),
+ m_active(false),
+ m_screenContextInitialized(false),
+ m_screenPixmapInitialized(false),
+ m_screenPixmapBufferInitialized(false)
+{
+ // grab the window frame with 60 frames per second
+ m_timer.setInterval(1000/60);
+
+ connect(&m_timer, SIGNAL(timeout()), SLOT(grab()));
+
+ QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+}
+
+WindowGrabber::~WindowGrabber()
+{
+ QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+void WindowGrabber::setFrameRate(int frameRate)
+{
+ m_timer.setInterval(1000/frameRate);
+}
+
+void WindowGrabber::setWindowId(const QByteArray &windowId)
+{
+ m_windowId = windowId;
+}
+
+void WindowGrabber::start()
+{
+ int result = 0;
+
+#ifdef Q_OS_BLACKBERRY_TABLET
+
+ // HACK: On the Playbook, screen_read_window() will fail for invisible windows.
+ // To workaround this, make the window visible again, but set a global
+ // alpha of less than 255. The global alpha makes the window completely invisible
+ // (due to a bug?), but screen_read_window() will work again.
+
+ errno = 0;
+ int val = 200; // anything less than 255
+ result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
+ if (result != 0) {
+ qWarning() << "WindowGrabber: unable to set global alpha:" << strerror(errno);
+ return;
+ }
+
+ errno = 0;
+ val = 1;
+ result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
+ if (result != 0) {
+ qWarning() << "WindowGrabber: unable to make window visible:" << strerror(errno);
+ return;
+ }
+#endif
+
+ result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT);
+ if (result != 0) {
+ qWarning() << "WindowGrabber: cannot create screen context:" << strerror(errno);
+ return;
+ } else {
+ m_screenContextInitialized = true;
+ }
+
+ result = screen_create_pixmap(&m_screenPixmap, m_screenContext);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot create pixmap:" << strerror(errno);
+ return;
+ } else {
+ m_screenPixmapInitialized = true;
+ }
+
+ const int usage = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
+ result = screen_set_pixmap_property_iv(m_screenPixmap, SCREEN_PROPERTY_USAGE, &usage);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot set pixmap usage:" << strerror(errno);
+ return;
+ }
+
+ const int format = SCREEN_FORMAT_RGBA8888;
+ result = screen_set_pixmap_property_iv(m_screenPixmap, SCREEN_PROPERTY_FORMAT, &format);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot set pixmap format:" << strerror(errno);
+ return;
+ }
+
+ int size[2] = { 0, 0 };
+
+ result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot get window size:" << strerror(errno);
+ return;
+ }
+
+ m_screenBufferWidth = size[0];
+ m_screenBufferHeight = size[1];
+
+ updateFrameSize();
+
+ m_timer.start();
+
+ m_active = true;
+}
+
+void WindowGrabber::updateFrameSize()
+{
+ int size[2] = { m_screenBufferWidth, m_screenBufferHeight };
+
+ int result = screen_set_pixmap_property_iv(m_screenPixmap, SCREEN_PROPERTY_BUFFER_SIZE, size);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot set pixmap size:" << strerror(errno);
+ return;
+ }
+
+ result = screen_create_pixmap_buffer(m_screenPixmap);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot create pixmap buffer:" << strerror(errno);
+ return;
+ }
+
+ result = screen_get_pixmap_property_pv(m_screenPixmap, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)&m_screenPixmapBuffer);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot get pixmap buffer:" << strerror(errno);
+ return;
+ } else {
+ m_screenPixmapBufferInitialized = true;
+ }
+
+ result = screen_get_buffer_property_pv(m_screenPixmapBuffer, SCREEN_PROPERTY_POINTER, (void**)&m_screenBuffer);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot get pixmap buffer pointer:" << strerror(errno);
+ return;
+ }
+
+ result = screen_get_buffer_property_iv(m_screenPixmapBuffer, SCREEN_PROPERTY_STRIDE, &m_screenBufferStride);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot get pixmap buffer stride:" << strerror(errno);
+ return;
+ }
+}
+
+void WindowGrabber::stop()
+{
+ if (!m_active)
+ return;
+
+ cleanup();
+
+ m_timer.stop();
+
+ m_active = false;
+}
+
+void WindowGrabber::pause()
+{
+ m_timer.stop();
+}
+
+void WindowGrabber::resume()
+{
+ if (!m_active)
+ return;
+
+ m_timer.start();
+}
+
+bool WindowGrabber::handleScreenEvent(screen_event_t screen_event)
+{
+
+ int eventType;
+ if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
+ qWarning() << "WindowGrabber: Failed to query screen event type";
+ return false;
+ }
+
+ if (eventType != SCREEN_EVENT_CREATE)
+ return false;
+
+ screen_window_t window = 0;
+ if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
+ qWarning() << "WindowGrabber: Failed to query window property";
+ return false;
+ }
+
+ const int maxIdStrLength = 128;
+ char idString[maxIdStrLength];
+ if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
+ qWarning() << "WindowGrabber: Failed to query window ID string";
+ return false;
+ }
+
+ if (m_windowId == idString) {
+ m_window = window;
+ start();
+ }
+
+ return false;
+}
+
+bool WindowGrabber::nativeEventFilter(const QByteArray &eventType, void *message, long*)
+{
+#ifdef Q_OS_BLACKBERRY
+ Q_UNUSED(eventType)
+ bps_event_t * const event = static_cast<bps_event_t *>(message);
+
+ if (event && bps_event_get_domain(event) == screen_get_domain()) {
+ const screen_event_t screen_event = screen_event_get_event(event);
+ return handleScreenEvent(screen_event);
+ }
+#else
+ if (eventType == "screen_event_t") {
+ const screen_event_t event = static_cast<screen_event_t>(message);
+ return handleScreenEvent(event);
+ }
+#endif
+
+ return false;
+}
+
+QByteArray WindowGrabber::windowGroupId() const
+{
+ QWindow *window = QGuiApplication::allWindows().isEmpty() ? 0 : QGuiApplication::allWindows().first();
+ if (!window)
+ return QByteArray();
+
+ QPlatformNativeInterface * const nativeInterface = QGuiApplication::platformNativeInterface();
+ if (!nativeInterface) {
+ qWarning() << "WindowGrabber: Unable to get platform native interface";
+ return QByteArray();
+ }
+
+ const char * const groupIdData = static_cast<const char *>(
+ nativeInterface->nativeResourceForWindow("windowGroup", window));
+ if (!groupIdData) {
+ qWarning() << "WindowGrabber: Unable to find window group for window" << window;
+ return QByteArray();
+ }
+
+ return QByteArray(groupIdData);
+}
+
+void WindowGrabber::grab()
+{
+ int size[2] = { 0, 0 };
+
+ int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size);
+ if (result != 0) {
+ cleanup();
+ qWarning() << "WindowGrabber: cannot get window size:" << strerror(errno);
+ return;
+ }
+
+ if (m_screenBufferWidth != size[0] || m_screenBufferHeight != size[1]) {
+ // The source viewport size changed, so we have to adapt our buffers
+
+ if (m_screenPixmapBufferInitialized) {
+ screen_destroy_pixmap_buffer(m_screenPixmap);
+ m_screenPixmapBufferInitialized = false;
+ }
+
+ m_screenBufferWidth = size[0];
+ m_screenBufferHeight = size[1];
+
+ updateFrameSize();
+ }
+
+ const int rect[] = { 0, 0, m_screenBufferWidth, m_screenBufferHeight };
+ result = screen_read_window(m_window, m_screenPixmapBuffer, 1, rect, 0);
+ if (result != 0)
+ return;
+
+ const QImage frame((unsigned char*)m_screenBuffer, m_screenBufferWidth, m_screenBufferHeight,
+ m_screenBufferStride, QImage::Format_ARGB32);
+
+ emit frameGrabbed(frame);
+}
+
+void WindowGrabber::cleanup()
+{
+ if (m_screenPixmapBufferInitialized) {
+ screen_destroy_buffer(m_screenPixmapBuffer);
+ m_screenPixmapBufferInitialized = false;
+ }
+
+ if (m_screenPixmapInitialized) {
+ screen_destroy_pixmap(m_screenPixmap);
+ m_screenPixmapInitialized = false;
+ }
+
+ if (m_screenContextInitialized) {
+ screen_destroy_context(m_screenContext);
+ m_screenContextInitialized = false;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/common/windowgrabber.h b/src/plugins/qnx/common/windowgrabber.h
new file mode 100644
index 000000000..7ec4202a2
--- /dev/null
+++ b/src/plugins/qnx/common/windowgrabber.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef WINDOWGRABBER_H
+#define WINDOWGRABBER_H
+
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+#include <QTimer>
+
+#include <screen/screen.h>
+
+QT_BEGIN_NAMESPACE
+
+class WindowGrabber : public QObject, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+
+public:
+ explicit WindowGrabber(QObject *parent = 0);
+ ~WindowGrabber();
+
+ void setFrameRate(int frameRate);
+
+ void setWindowId(const QByteArray &windowId);
+
+ void start();
+ void stop();
+
+ void pause();
+ void resume();
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+ bool handleScreenEvent(screen_event_t event);
+
+ QByteArray windowGroupId() const;
+
+signals:
+ void frameGrabbed(const QImage &frame);
+
+private slots:
+ void grab();
+
+private:
+ void cleanup();
+ void updateFrameSize();
+
+ QTimer m_timer;
+
+ QByteArray m_windowId;
+
+ screen_window_t m_window;
+ screen_context_t m_screenContext;
+ screen_pixmap_t m_screenPixmap;
+ screen_buffer_t m_screenPixmapBuffer;
+
+ char* m_screenBuffer;
+
+ int m_screenBufferWidth;
+ int m_screenBufferHeight;
+ int m_screenBufferStride;
+
+ bool m_active : 1;
+ bool m_screenContextInitialized : 1;
+ bool m_screenPixmapInitialized : 1;
+ bool m_screenPixmapBufferInitialized : 1;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp
new file mode 100644
index 000000000..dde03ad59
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bpsmediaplayercontrol.h"
+#include "mmrenderervideowindowcontrol.h"
+
+#include <bps/mmrenderer.h>
+#include <bps/screen.h>
+
+QT_BEGIN_NAMESPACE
+
+BpsMediaPlayerControl::BpsMediaPlayerControl(QObject *parent)
+ : MmRendererMediaPlayerControl(parent),
+ m_eventMonitor(0)
+{
+ openConnection();
+}
+
+BpsMediaPlayerControl::~BpsMediaPlayerControl()
+{
+ destroy();
+}
+
+void BpsMediaPlayerControl::startMonitoring(int contextId, const QString &contextName)
+{
+ m_eventMonitor = mmrenderer_request_events(contextName.toLatin1().constData(), 0, contextId);
+ if (!m_eventMonitor) {
+ qDebug() << "Unable to request multimedia events";
+ emit error(0, "Unable to request multimedia events");
+ }
+}
+
+void BpsMediaPlayerControl::stopMonitoring()
+{
+ if (m_eventMonitor) {
+ mmrenderer_stop_events(m_eventMonitor);
+ m_eventMonitor = 0;
+ }
+}
+
+bool BpsMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+{
+ Q_UNUSED(result)
+ Q_UNUSED(eventType)
+
+ bps_event_t * const event = static_cast<bps_event_t *>(message);
+ if (!event ||
+ (bps_event_get_domain(event) != mmrenderer_get_domain() &&
+ bps_event_get_domain(event) != screen_get_domain()))
+ return false;
+
+ if (event && bps_event_get_domain(event) == screen_get_domain()) {
+ const screen_event_t screen_event = screen_event_get_event(event);
+ if (MmRendererVideoWindowControl *control = videoWindowControl())
+ control->screenEventHandler(screen_event);
+ }
+
+ if (bps_event_get_domain(event) == mmrenderer_get_domain()) {
+ if (bps_event_get_code(event) == MMRENDERER_STATE_CHANGE) {
+ const mmrenderer_state_t newState = mmrenderer_event_get_state(event);
+ if (newState == MMR_STOPPED) {
+ handleMmStopped();
+ return false;
+ }
+ }
+
+ if (bps_event_get_code(event) == MMRENDERER_STATUS_UPDATE) {
+ const qint64 newPosition = QString::fromLatin1(mmrenderer_event_get_position(event)).toLongLong();
+ handleMmStatusUpdate(newPosition);
+
+ const QString bufferStatus = QString::fromLatin1(mmrenderer_event_get_bufferlevel(event));
+ setMmBufferStatus(bufferStatus);
+ }
+ }
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h b/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h
new file mode 100644
index 000000000..f0c132346
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BPSMEDIAPLAYERCONTROL_H
+#define BPSMEDIAPLAYERCONTROL_H
+
+#include "mmrenderermediaplayercontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+class BpsMediaPlayerControl Q_DECL_FINAL : public MmRendererMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ explicit BpsMediaPlayerControl(QObject *parent = 0);
+ ~BpsMediaPlayerControl();
+
+ void startMonitoring(int contextId, const QString &contextName) Q_DECL_OVERRIDE;
+ void stopMonitoring() Q_DECL_OVERRIDE;
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+private:
+ mmrenderer_monitor_t *m_eventMonitor;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mediaplayer.pri b/src/plugins/qnx/mediaplayer/mediaplayer.pri
new file mode 100644
index 000000000..9dedab0fd
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mediaplayer.pri
@@ -0,0 +1,31 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/mmrenderermediaplayercontrol.h \
+ $$PWD/mmrenderermediaplayerservice.h \
+ $$PWD/mmrenderermetadata.h \
+ $$PWD/mmrenderermetadatareadercontrol.h \
+ $$PWD/mmrendererplayervideorenderercontrol.h \
+ $$PWD/mmrendererutil.h \
+ $$PWD/mmrenderervideowindowcontrol.h
+
+SOURCES += \
+ $$PWD/mmrenderermediaplayercontrol.cpp \
+ $$PWD/mmrenderermediaplayerservice.cpp \
+ $$PWD/mmrenderermetadata.cpp \
+ $$PWD/mmrenderermetadatareadercontrol.cpp \
+ $$PWD/mmrendererplayervideorenderercontrol.cpp \
+ $$PWD/mmrendererutil.cpp \
+ $$PWD/mmrenderervideowindowcontrol.cpp
+
+LIBS += -lmmrndclient -lstrm
+
+blackberry {
+ HEADERS += $$PWD/bpsmediaplayercontrol.h
+ SOURCES += $$PWD/bpsmediaplayercontrol.cpp
+} else {
+ HEADERS += $$PWD/ppsmediaplayercontrol.h
+ SOURCES += $$PWD/ppsmediaplayercontrol.cpp
+ QT += core-private
+ LIBS += -lpps
+}
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
new file mode 100644
index 000000000..2a376198b
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
@@ -0,0 +1,634 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrenderermediaplayercontrol.h"
+#include "mmrenderermetadatareadercontrol.h"
+#include "mmrendererplayervideorenderercontrol.h"
+#include "mmrendererutil.h"
+#include "mmrenderervideowindowcontrol.h"
+#include <QtCore/qabstracteventdispatcher.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/quuid.h>
+#include <mm/renderer.h>
+
+#include <errno.h>
+#include <sys/strm.h>
+#include <sys/stat.h>
+
+QT_BEGIN_NAMESPACE
+
+static int idCounter = 0;
+
+MmRendererMediaPlayerControl::MmRendererMediaPlayerControl(QObject *parent)
+ : QMediaPlayerControl(parent),
+ m_connection(0),
+ m_context(0),
+ m_audioId(-1),
+ m_state(QMediaPlayer::StoppedState),
+ m_volume(100),
+ m_muted(false),
+ m_rate(1),
+ m_id(-1),
+ m_position(0),
+ m_mediaStatus(QMediaPlayer::NoMedia),
+ m_playAfterMediaLoaded(false),
+ m_inputAttached(false),
+ m_stopEventsToIgnore(0),
+ m_bufferStatus(0)
+{
+ m_loadingTimer.setSingleShot(true);
+ m_loadingTimer.setInterval(0);
+ connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia()));
+ QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+}
+
+void MmRendererMediaPlayerControl::destroy()
+{
+ stop();
+ detach();
+ closeConnection();
+ QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+void MmRendererMediaPlayerControl::openConnection()
+{
+ m_connection = mmr_connect(NULL);
+ if (!m_connection) {
+ emitPError("Unable to connect to the multimedia renderer");
+ return;
+ }
+
+ m_id = idCounter++;
+ m_contextName = QString("MmRendererMediaPlayerControl_%1_%2").arg(m_id)
+ .arg(QCoreApplication::applicationPid());
+ m_context = mmr_context_create(m_connection, m_contextName.toLatin1(),
+ 0, S_IRWXU|S_IRWXG|S_IRWXO);
+ if (!m_context) {
+ emitPError("Unable to create context");
+ closeConnection();
+ return;
+ }
+
+ startMonitoring(m_id, m_contextName);
+}
+
+void MmRendererMediaPlayerControl::handleMmStatusUpdate(qint64 newPosition)
+{
+ // Prevent spurious position change events from overriding our own position, for example
+ // when setting the position to 0 in stop().
+ // Also, don't change the position while we're loading the media, as then play() would
+ // set a wrong initial position.
+ if (m_state != QMediaPlayer::PlayingState ||
+ m_mediaStatus == QMediaPlayer::LoadingMedia ||
+ m_mediaStatus == QMediaPlayer::NoMedia ||
+ m_mediaStatus == QMediaPlayer::InvalidMedia)
+ return;
+
+ setMmPosition(newPosition);
+}
+
+void MmRendererMediaPlayerControl::handleMmStopped()
+{
+ // Only react to stop events that happen when the end of the stream is reached and
+ // playback is stopped because of this.
+ // Ignore other stop event sources, souch as calling mmr_stop() ourselves and
+ // mmr_input_attach().
+ if (m_stopEventsToIgnore > 0) {
+ --m_stopEventsToIgnore;
+ } else {
+ setMediaStatus(QMediaPlayer::EndOfMedia);
+ stopInternal(IgnoreMmRenderer);
+ }
+}
+
+void MmRendererMediaPlayerControl::closeConnection()
+{
+ stopMonitoring();
+
+ if (m_context) {
+ mmr_context_destroy(m_context);
+ m_context = 0;
+ m_contextName.clear();
+ }
+
+ if (m_connection) {
+ mmr_disconnect(m_connection);
+ m_connection = 0;
+ }
+}
+
+QByteArray MmRendererMediaPlayerControl::resourcePathForUrl(const QUrl &url)
+{
+ // If this is a local file, mmrenderer expects the file:// prefix and an absolute path.
+ // We treat URLs without scheme as local files, most likely someone just forgot to set the
+ // file:// prefix when constructing the URL.
+ if (url.isLocalFile() || url.scheme().isEmpty()) {
+ QString relativeFilePath;
+ if (!url.scheme().isEmpty())
+ relativeFilePath = url.toLocalFile();
+ else
+ relativeFilePath = url.path();
+ const QFileInfo fileInfo(relativeFilePath);
+ return QFile::encodeName(QStringLiteral("file://") + fileInfo.absoluteFilePath());
+
+ // QRC, copy to temporary file, as mmrenderer does not support resource files
+ } else if (url.scheme() == QStringLiteral("qrc")) {
+ const QString qrcPath = ':' + url.path();
+ const QFileInfo resourceFileInfo(qrcPath);
+ m_tempMediaFileName = QDir::tempPath() + QStringLiteral("/qtmedia_") +
+ QUuid::createUuid().toString() + QStringLiteral(".") +
+ resourceFileInfo.suffix();
+ if (!QFile::copy(qrcPath, m_tempMediaFileName)) {
+ const QString errorMsg = QString("Failed to copy resource file to temporary file "
+ "%1 for playback").arg(m_tempMediaFileName);
+ qDebug() << errorMsg;
+ emit error(0, errorMsg);
+ return QByteArray();
+ }
+ return QFile::encodeName(m_tempMediaFileName);
+
+ // HTTP or similar URL
+ } else {
+ return url.toEncoded();
+ }
+}
+
+void MmRendererMediaPlayerControl::attach()
+{
+ // Should only be called in detached state
+ Q_ASSERT(m_audioId == -1 && !m_inputAttached && m_tempMediaFileName.isEmpty());
+
+ if (m_media.isNull() || !m_context) {
+ setMediaStatus(QMediaPlayer::NoMedia);
+ return;
+ }
+
+ if (m_videoRendererControl)
+ m_videoRendererControl->attachDisplay(m_context);
+
+ if (m_videoWindowControl)
+ m_videoWindowControl->attachDisplay(m_context);
+
+ m_audioId = mmr_output_attach(m_context, "audio:default", "audio");
+ if (m_audioId == -1) {
+ emitMmError("mmr_output_attach() for audio failed");
+ return;
+ }
+
+ const QByteArray resourcePath = resourcePathForUrl(m_media.canonicalUrl());
+ if (resourcePath.isEmpty()) {
+ detach();
+ return;
+ }
+
+ if (mmr_input_attach(m_context, resourcePath.constData(), "track") != 0) {
+ emitMmError(QStringLiteral("mmr_input_attach() failed for ") + QString(resourcePath));
+ setMediaStatus(QMediaPlayer::InvalidMedia);
+ detach();
+ return;
+ }
+
+ // For whatever reason, the mmrenderer sends out a MMR_STOPPED event when calling
+ // mmr_input_attach() above. Ignore it, as otherwise we'll trigger stopping right after we
+ // started.
+ m_stopEventsToIgnore++;
+
+ m_inputAttached = true;
+ setMediaStatus(QMediaPlayer::LoadedMedia);
+ m_bufferStatus = 0;
+ emit bufferStatusChanged(m_bufferStatus);
+}
+
+void MmRendererMediaPlayerControl::detach()
+{
+ if (m_context) {
+ if (m_inputAttached) {
+ mmr_input_detach(m_context);
+ m_inputAttached = false;
+ }
+ if (m_videoRendererControl)
+ m_videoRendererControl->detachDisplay();
+ if (m_videoWindowControl)
+ m_videoWindowControl->detachDisplay();
+ if (m_audioId != -1 && m_context) {
+ mmr_output_detach(m_context, m_audioId);
+ m_audioId = -1;
+ }
+ }
+
+ if (!m_tempMediaFileName.isEmpty()) {
+ QFile::remove(m_tempMediaFileName);
+ m_tempMediaFileName.clear();
+ }
+ m_loadingTimer.stop();
+}
+
+QMediaPlayer::State MmRendererMediaPlayerControl::state() const
+{
+ return m_state;
+}
+
+QMediaPlayer::MediaStatus MmRendererMediaPlayerControl::mediaStatus() const
+{
+ return m_mediaStatus;
+}
+
+qint64 MmRendererMediaPlayerControl::duration() const
+{
+ return m_metaData.duration();
+}
+
+qint64 MmRendererMediaPlayerControl::position() const
+{
+ return m_position;
+}
+
+void MmRendererMediaPlayerControl::setPosition(qint64 position)
+{
+ if (m_position != position) {
+ m_position = position;
+
+ // Don't update in stopped state, it would not have any effect. Instead, the position is
+ // updated in play().
+ if (m_state != QMediaPlayer::StoppedState)
+ setPositionInternal(m_position);
+
+ emit positionChanged(m_position);
+ }
+}
+
+int MmRendererMediaPlayerControl::volume() const
+{
+ return m_volume;
+}
+
+void MmRendererMediaPlayerControl::setVolumeInternal(int newVolume)
+{
+ if (!m_context)
+ return;
+
+ newVolume = qBound(0, newVolume, 100);
+ if (m_audioId != -1) {
+ strm_dict_t * dict = strm_dict_new();
+ dict = strm_dict_set(dict, "volume", QString::number(newVolume).toLatin1());
+ if (mmr_output_parameters(m_context, m_audioId, dict) != 0)
+ emitMmError("mmr_output_parameters: Setting volume failed");
+ }
+}
+
+void MmRendererMediaPlayerControl::setPlaybackRateInternal(qreal rate)
+{
+ if (!m_context)
+ return;
+
+ const int mmRate = rate * 1000;
+ if (mmr_speed_set(m_context, mmRate) != 0)
+ emitMmError("mmr_speed_set failed");
+}
+
+void MmRendererMediaPlayerControl::setPositionInternal(qint64 position)
+{
+ if (!m_context)
+ return;
+
+ if (m_metaData.isSeekable()) {
+ if (mmr_seek(m_context, QString::number(position).toLatin1()) != 0)
+ emitMmError("Seeking failed");
+ }
+}
+
+void MmRendererMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
+{
+ if (m_mediaStatus != status) {
+ m_mediaStatus = status;
+ emit mediaStatusChanged(m_mediaStatus);
+ }
+}
+
+void MmRendererMediaPlayerControl::setState(QMediaPlayer::State state)
+{
+ if (m_state != state) {
+ if (m_videoRendererControl) {
+ if (state == QMediaPlayer::PausedState)
+ m_videoRendererControl->pause();
+ else if ((state == QMediaPlayer::PlayingState)
+ && (m_state == QMediaPlayer::PausedState)) {
+ m_videoRendererControl->resume();
+ }
+ }
+
+ m_state = state;
+ emit stateChanged(m_state);
+ }
+}
+
+void MmRendererMediaPlayerControl::stopInternal(StopCommand stopCommand)
+{
+ if (m_state != QMediaPlayer::StoppedState) {
+
+ if (stopCommand == StopMmRenderer) {
+ ++m_stopEventsToIgnore;
+ mmr_stop(m_context);
+ }
+
+ setState(QMediaPlayer::StoppedState);
+ }
+
+ if (m_position != 0) {
+ m_position = 0;
+ emit positionChanged(0);
+ }
+}
+
+void MmRendererMediaPlayerControl::setVolume(int volume)
+{
+ const int newVolume = qBound(0, volume, 100);
+ if (m_volume != newVolume) {
+ m_volume = newVolume;
+ if (!m_muted)
+ setVolumeInternal(m_volume);
+ emit volumeChanged(m_volume);
+ }
+}
+
+bool MmRendererMediaPlayerControl::isMuted() const
+{
+ return m_muted;
+}
+
+void MmRendererMediaPlayerControl::setMuted(bool muted)
+{
+ if (m_muted != muted) {
+ m_muted = muted;
+ setVolumeInternal(muted ? 0 : m_volume);
+ emit mutedChanged(muted);
+ }
+}
+
+int MmRendererMediaPlayerControl::bufferStatus() const
+{
+ return m_bufferStatus;
+}
+
+bool MmRendererMediaPlayerControl::isAudioAvailable() const
+{
+ return m_metaData.hasAudio();
+}
+
+bool MmRendererMediaPlayerControl::isVideoAvailable() const
+{
+ return m_metaData.hasVideo();
+}
+
+bool MmRendererMediaPlayerControl::isSeekable() const
+{
+ return m_metaData.isSeekable();
+}
+
+QMediaTimeRange MmRendererMediaPlayerControl::availablePlaybackRanges() const
+{
+ // We can't get this information from the mmrenderer API yet, so pretend we can seek everywhere
+ return QMediaTimeRange(0, m_metaData.duration());
+}
+
+qreal MmRendererMediaPlayerControl::playbackRate() const
+{
+ return m_rate;
+}
+
+void MmRendererMediaPlayerControl::setPlaybackRate(qreal rate)
+{
+ if (m_rate != rate) {
+ m_rate = rate;
+ setPlaybackRateInternal(m_rate);
+ emit playbackRateChanged(m_rate);
+ }
+}
+
+QMediaContent MmRendererMediaPlayerControl::media() const
+{
+ return m_media;
+}
+
+const QIODevice *MmRendererMediaPlayerControl::mediaStream() const
+{
+ // Always 0, we don't support QIODevice streams
+ return 0;
+}
+
+void MmRendererMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
+{
+ Q_UNUSED(stream); // not supported
+
+ stop();
+ detach();
+
+ m_media = media;
+ emit mediaChanged(m_media);
+
+ // Slight hack: With MediaPlayer QtQuick elements that have autoPlay set to true, playback
+ // would start before the QtQuick canvas is propagated to all elements, and therefore our
+ // video output would not work. Therefore, delay actually playing the media a bit so that the
+ // canvas is ready.
+ // The mmrenderer doesn't allow to attach video outputs after playing has started, otherwise
+ // this would be unnecessary.
+ if (!m_media.isNull()) {
+ setMediaStatus(QMediaPlayer::LoadingMedia);
+ m_loadingTimer.start(); // singleshot timer to continueLoadMedia()
+ } else {
+ continueLoadMedia(); // still needed, as it will update the media status and clear metadata
+ }
+}
+
+void MmRendererMediaPlayerControl::continueLoadMedia()
+{
+ attach();
+ updateMetaData();
+ if (m_playAfterMediaLoaded)
+ play();
+}
+
+QString MmRendererMediaPlayerControl::contextName() const
+{
+ return m_contextName;
+}
+
+MmRendererVideoWindowControl *MmRendererMediaPlayerControl::videoWindowControl() const
+{
+ return m_videoWindowControl;
+}
+
+void MmRendererMediaPlayerControl::play()
+{
+ if (m_playAfterMediaLoaded)
+ m_playAfterMediaLoaded = false;
+
+ // No-op if we are already playing, except if we were called from continueLoadMedia(), in which
+ // case m_playAfterMediaLoaded is true (hence the 'else').
+ else if (m_state == QMediaPlayer::PlayingState)
+ return;
+
+ if (m_mediaStatus == QMediaPlayer::LoadingMedia) {
+
+ // State changes are supposed to be synchronous
+ setState(QMediaPlayer::PlayingState);
+
+ // Defer playing to later, when the timer triggers continueLoadMedia()
+ m_playAfterMediaLoaded = true;
+ return;
+ }
+
+ // Un-pause the state when it is paused
+ if (m_state == QMediaPlayer::PausedState) {
+ setPlaybackRateInternal(m_rate);
+ setState(QMediaPlayer::PlayingState);
+ return;
+ }
+
+ if (m_media.isNull() || !m_connection || !m_context || m_audioId == -1) {
+ setState(QMediaPlayer::StoppedState);
+ return;
+ }
+
+ setPositionInternal(m_position);
+ setVolumeInternal(m_volume);
+ setPlaybackRateInternal(m_rate);
+
+ if (mmr_play(m_context) != 0) {
+ setState(QMediaPlayer::StoppedState);
+ emitMmError("mmr_play() failed");
+ return;
+ }
+
+ setState( QMediaPlayer::PlayingState);
+}
+
+void MmRendererMediaPlayerControl::pause()
+{
+ if (m_state == QMediaPlayer::PlayingState) {
+ setPlaybackRateInternal(0);
+ setState(QMediaPlayer::PausedState);
+ }
+}
+
+void MmRendererMediaPlayerControl::stop()
+{
+ stopInternal(StopMmRenderer);
+}
+
+MmRendererPlayerVideoRendererControl *MmRendererMediaPlayerControl::videoRendererControl() const
+{
+ return m_videoRendererControl;
+}
+
+void MmRendererMediaPlayerControl::setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl)
+{
+ m_videoRendererControl = videoControl;
+}
+
+void MmRendererMediaPlayerControl::setVideoWindowControl(MmRendererVideoWindowControl *videoControl)
+{
+ m_videoWindowControl = videoControl;
+}
+
+void MmRendererMediaPlayerControl::setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl)
+{
+ m_metaDataReaderControl = metaDataReaderControl;
+}
+
+void MmRendererMediaPlayerControl::setMmPosition(qint64 newPosition)
+{
+ if (newPosition != 0 && newPosition != m_position) {
+ m_position = newPosition;
+ emit positionChanged(m_position);
+ }
+}
+
+void MmRendererMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus)
+{
+ const int slashPos = bufferStatus.indexOf('/');
+ if (slashPos != -1) {
+ const int fill = bufferStatus.left(slashPos).toInt();
+ const int capacity = bufferStatus.mid(slashPos + 1).toInt();
+ if (capacity != 0) {
+ m_bufferStatus = fill / static_cast<float>(capacity) * 100.0f;
+ emit bufferStatusChanged(m_bufferStatus);
+ }
+ }
+}
+
+void MmRendererMediaPlayerControl::updateMetaData()
+{
+ if (m_mediaStatus == QMediaPlayer::LoadedMedia)
+ m_metaData.parse(m_contextName);
+ else
+ m_metaData.clear();
+
+ if (m_videoWindowControl)
+ m_videoWindowControl->setMetaData(m_metaData);
+
+ if (m_metaDataReaderControl)
+ m_metaDataReaderControl->setMetaData(m_metaData);
+
+ emit durationChanged(m_metaData.duration());
+ emit audioAvailableChanged(m_metaData.hasAudio());
+ emit videoAvailableChanged(m_metaData.hasVideo());
+ emit availablePlaybackRangesChanged(availablePlaybackRanges());
+ emit seekableChanged(m_metaData.isSeekable());
+}
+
+void MmRendererMediaPlayerControl::emitMmError(const QString &msg)
+{
+ int errorCode = MMR_ERROR_NONE;
+ const QString errorMessage = mmErrorMessage(msg, m_context, &errorCode);
+ qDebug() << errorMessage;
+ emit error(errorCode, errorMessage);
+}
+
+void MmRendererMediaPlayerControl::emitPError(const QString &msg)
+{
+ const QString errorMessage = QString("%1: %2").arg(msg).arg(strerror(errno));
+ qDebug() << errorMessage;
+ emit error(errno, errorMessage);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
new file mode 100644
index 000000000..a22e71bfc
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERMEDIAPLAYERCONTROL_H
+#define MMRENDERERMEDIAPLAYERCONTROL_H
+
+#include "mmrenderermetadata.h"
+#include <qmediaplayercontrol.h>
+#include <QtCore/qabstractnativeeventfilter.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qtimer.h>
+
+typedef struct mmr_connection mmr_connection_t;
+typedef struct mmr_context mmr_context_t;
+typedef struct mmrenderer_monitor mmrenderer_monitor_t;
+
+QT_BEGIN_NAMESPACE
+
+class MmRendererMetaDataReaderControl;
+class MmRendererPlayerVideoRendererControl;
+class MmRendererVideoWindowControl;
+
+class MmRendererMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+public:
+ explicit MmRendererMediaPlayerControl(QObject *parent = 0);
+
+ QMediaPlayer::State state() const Q_DECL_OVERRIDE;
+
+ QMediaPlayer::MediaStatus mediaStatus() const Q_DECL_OVERRIDE;
+
+ qint64 duration() const Q_DECL_OVERRIDE;
+
+ qint64 position() const Q_DECL_OVERRIDE;
+ void setPosition(qint64 position) Q_DECL_OVERRIDE;
+
+ int volume() const Q_DECL_OVERRIDE;
+ void setVolume(int volume) Q_DECL_OVERRIDE;
+
+ bool isMuted() const Q_DECL_OVERRIDE;
+ void setMuted(bool muted) Q_DECL_OVERRIDE;
+
+ int bufferStatus() const Q_DECL_OVERRIDE;
+
+ bool isAudioAvailable() const Q_DECL_OVERRIDE;
+ bool isVideoAvailable() const Q_DECL_OVERRIDE;
+
+ bool isSeekable() const Q_DECL_OVERRIDE;
+
+ QMediaTimeRange availablePlaybackRanges() const Q_DECL_OVERRIDE;
+
+ qreal playbackRate() const Q_DECL_OVERRIDE;
+ void setPlaybackRate(qreal rate) Q_DECL_OVERRIDE;
+
+ QMediaContent media() const Q_DECL_OVERRIDE;
+ const QIODevice *mediaStream() const Q_DECL_OVERRIDE;
+ void setMedia(const QMediaContent &media, QIODevice *stream) Q_DECL_OVERRIDE;
+
+ void play() Q_DECL_OVERRIDE;
+ void pause() Q_DECL_OVERRIDE;
+ void stop() Q_DECL_OVERRIDE;
+
+ MmRendererPlayerVideoRendererControl *videoRendererControl() const;
+ void setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl);
+
+ MmRendererVideoWindowControl *videoWindowControl() const;
+ void setVideoWindowControl(MmRendererVideoWindowControl *videoControl);
+ void setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl);
+
+protected:
+ virtual void startMonitoring(int contextId, const QString &contextName) = 0;
+ virtual void stopMonitoring() = 0;
+
+ QString contextName() const;
+ void openConnection();
+ void emitMmError(const QString &msg);
+ void emitPError(const QString &msg);
+ void setMmPosition(qint64 newPosition);
+ void setMmBufferStatus(const QString &bufferStatus);
+ void handleMmStopped();
+ void handleMmStatusUpdate(qint64 position);
+
+ // must be called from subclass dtors (calls virtual function stopMonitoring())
+ void destroy();
+
+private Q_SLOTS:
+ void continueLoadMedia();
+
+private:
+ QByteArray resourcePathForUrl(const QUrl &url);
+ void closeConnection();
+ void attach();
+ void detach();
+ void updateMetaData();
+
+ // All these set the specified value to the backend, but neither emit changed signals
+ // nor change the member value.
+ void setVolumeInternal(int newVolume);
+ void setPlaybackRateInternal(qreal rate);
+ void setPositionInternal(qint64 position);
+
+ void setMediaStatus(QMediaPlayer::MediaStatus status);
+ void setState(QMediaPlayer::State state);
+
+ enum StopCommand { StopMmRenderer, IgnoreMmRenderer };
+ void stopInternal(StopCommand stopCommand);
+
+ QMediaContent m_media;
+ mmr_connection_t *m_connection;
+ mmr_context_t *m_context;
+ QString m_contextName;
+ int m_audioId;
+ QMediaPlayer::State m_state;
+ int m_volume;
+ bool m_muted;
+ qreal m_rate;
+ QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl;
+ QPointer<MmRendererVideoWindowControl> m_videoWindowControl;
+ QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl;
+ MmRendererMetaData m_metaData;
+ int m_id;
+ qint64 m_position;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ bool m_playAfterMediaLoaded;
+ bool m_inputAttached;
+ int m_stopEventsToIgnore;
+ int m_bufferStatus;
+ QString m_tempMediaFileName;
+ QTimer m_loadingTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp
new file mode 100644
index 000000000..1e75674e3
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrenderermediaplayerservice.h"
+
+#include "mmrenderermediaplayercontrol.h"
+#include "mmrenderermetadatareadercontrol.h"
+#include "mmrendererplayervideorenderercontrol.h"
+#include "mmrendererutil.h"
+#include "mmrenderervideowindowcontrol.h"
+
+#ifdef Q_OS_BLACKBERRY
+#include "bpsmediaplayercontrol.h"
+typedef BpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
+#else
+#include "ppsmediaplayercontrol.h"
+typedef PpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+MmRendererMediaPlayerService::MmRendererMediaPlayerService(QObject *parent)
+ : QMediaService(parent),
+ m_videoRendererControl(0),
+ m_videoWindowControl(0),
+ m_mediaPlayerControl(0),
+ m_metaDataReaderControl(0),
+ m_appHasDrmPermission(false),
+ m_appHasDrmPermissionChecked(false)
+{
+}
+
+MmRendererMediaPlayerService::~MmRendererMediaPlayerService()
+{
+ // Someone should have called releaseControl(), but better be safe
+ delete m_videoRendererControl;
+ delete m_videoWindowControl;
+ delete m_mediaPlayerControl;
+ delete m_metaDataReaderControl;
+}
+
+QMediaControl *MmRendererMediaPlayerService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
+ if (!m_mediaPlayerControl) {
+ m_mediaPlayerControl = new PlatformSpecificMediaPlayerControl;
+ updateControls();
+ }
+ return m_mediaPlayerControl;
+ }
+ else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) {
+ if (!m_metaDataReaderControl) {
+ m_metaDataReaderControl = new MmRendererMetaDataReaderControl();
+ updateControls();
+ }
+ return m_metaDataReaderControl;
+ }
+ else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ if (!m_appHasDrmPermissionChecked) {
+ m_appHasDrmPermission = checkForDrmPermission();
+ m_appHasDrmPermissionChecked = true;
+ }
+
+ if (m_appHasDrmPermission) {
+ // When the application wants to play back DRM secured media, we can't use
+ // the QVideoRendererControl, because we won't have access to the pixel data
+ // in this case.
+ return 0;
+ }
+
+ if (!m_videoRendererControl) {
+ m_videoRendererControl = new MmRendererPlayerVideoRendererControl();
+ updateControls();
+ }
+ return m_videoRendererControl;
+ }
+ else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+ if (!m_videoWindowControl) {
+ m_videoWindowControl = new MmRendererVideoWindowControl();
+ updateControls();
+ }
+ return m_videoWindowControl;
+ }
+ return 0;
+}
+
+void MmRendererMediaPlayerService::releaseControl(QMediaControl *control)
+{
+ if (control == m_videoRendererControl)
+ m_videoRendererControl = 0;
+ if (control == m_videoWindowControl)
+ m_videoWindowControl = 0;
+ if (control == m_mediaPlayerControl)
+ m_mediaPlayerControl = 0;
+ if (control == m_metaDataReaderControl)
+ m_metaDataReaderControl = 0;
+ delete control;
+}
+
+void MmRendererMediaPlayerService::updateControls()
+{
+ if (m_videoRendererControl && m_mediaPlayerControl)
+ m_mediaPlayerControl->setVideoRendererControl(m_videoRendererControl);
+
+ if (m_videoWindowControl && m_mediaPlayerControl)
+ m_mediaPlayerControl->setVideoWindowControl(m_videoWindowControl);
+
+ if (m_metaDataReaderControl && m_mediaPlayerControl)
+ m_mediaPlayerControl->setMetaDataReaderControl(m_metaDataReaderControl);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h
new file mode 100644
index 000000000..3d55de8d5
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERMEDIAPLAYERSERVICE_H
+#define MMRENDERERMEDIAPLAYERSERVICE_H
+
+#include <qmediaservice.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class MmRendererMediaPlayerControl;
+class MmRendererMetaDataReaderControl;
+class MmRendererPlayerVideoRendererControl;
+class MmRendererVideoWindowControl;
+
+class MmRendererMediaPlayerService : public QMediaService
+{
+ Q_OBJECT
+public:
+ explicit MmRendererMediaPlayerService(QObject *parent = 0);
+ ~MmRendererMediaPlayerService();
+
+ QMediaControl *requestControl(const char *name) Q_DECL_OVERRIDE;
+ void releaseControl(QMediaControl *control) Q_DECL_OVERRIDE;
+
+private:
+ void updateControls();
+
+ QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl;
+ QPointer<MmRendererVideoWindowControl> m_videoWindowControl;
+ QPointer<MmRendererMediaPlayerControl> m_mediaPlayerControl;
+ QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl;
+
+ bool m_appHasDrmPermission : 1;
+ bool m_appHasDrmPermissionChecked : 1;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp b/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp
new file mode 100644
index 000000000..07f5ddd62
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp
@@ -0,0 +1,269 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrenderermetadata.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+MmRendererMetaData::MmRendererMetaData()
+{
+ clear();
+}
+
+static const char * titleKey = "md_title_name";
+static const char * artistKey = "md_title_artist";
+static const char * commentKey = "md_title_comment";
+static const char * genreKey = "md_title_genre";
+static const char * yearKey = "md_title_year";
+static const char * durationKey = "md_title_duration";
+static const char * bitRateKey = "md_title_bitrate";
+static const char * sampleKey = "md_title_samplerate";
+static const char * albumKey = "md_title_album";
+static const char * trackKey = "md_title_track";
+static const char * widthKey = "md_video_width";
+static const char * heightKey = "md_video_height";
+static const char * mediaTypeKey = "md_title_mediatype";
+static const char * pixelWidthKey = "md_video_pixel_width";
+static const char * pixelHeightKey = "md_video_pixel_height";
+static const char * seekableKey = "md_title_seekable";
+
+static const int mediaTypeAudioFlag = 4;
+static const int mediaTypeVideoFlag = 2;
+
+bool MmRendererMetaData::parse(const QString &contextName)
+{
+ clear();
+ QString fileName =
+ QString("/pps/services/multimedia/renderer/context/%1/metadata").arg(contextName);
+
+ // In newer OS versions, the filename is "metadata0", not metadata, so try both.
+ if (!QFile::exists(fileName))
+ fileName += '0';
+
+ QFile metaDataFile(fileName);
+ if (!metaDataFile.open(QFile::ReadOnly)) {
+ qWarning() << "Unable to open media metadata file" << fileName << ":"
+ << metaDataFile.errorString();
+ return false;
+ }
+
+ const QString separator("::");
+ QTextStream stream(&metaDataFile);
+ Q_FOREVER {
+ const QString line = stream.readLine();
+ if (line.isNull())
+ break;
+
+ const int separatorPos = line.indexOf(separator);
+ if (separatorPos != -1) {
+ const QString key = line.left(separatorPos);
+ const QString value = line.mid(separatorPos + separator.length());
+
+ if (key == durationKey)
+ m_duration = value.toLongLong();
+ else if (key == widthKey)
+ m_width = value.toInt();
+ else if (key == heightKey)
+ m_height = value.toInt();
+ else if (key == mediaTypeKey)
+ m_mediaType = value.toInt();
+ else if (key == pixelWidthKey)
+ m_pixelWidth = value.toFloat();
+ else if (key == pixelHeightKey)
+ m_pixelHeight = value.toFloat();
+ else if (key == titleKey)
+ m_title = value;
+ else if (key == seekableKey)
+ m_seekable = !(value == QLatin1String("0"));
+ else if (key == artistKey)
+ m_artist = value;
+ else if (key == commentKey)
+ m_comment = value;
+ else if (key == genreKey)
+ m_genre = value;
+ else if (key == yearKey)
+ m_year = value.toInt();
+ else if (key == bitRateKey)
+ m_audioBitRate = value.toInt();
+ else if (key == sampleKey)
+ m_sampleRate = value.toInt();
+ else if (key == albumKey)
+ m_album = value;
+ else if (key == trackKey)
+ m_track = value.toInt();
+ }
+ }
+
+ return true;
+}
+
+void MmRendererMetaData::clear()
+{
+ m_duration = 0;
+ m_height = 0;
+ m_width = 0;
+ m_mediaType = -1;
+ m_pixelWidth = 1;
+ m_pixelHeight = 1;
+ m_seekable = true;
+ m_title.clear();
+ m_artist.clear();
+ m_comment.clear();
+ m_genre.clear();
+ m_year = 0;
+ m_audioBitRate = 0;
+ m_sampleRate = 0;
+ m_album.clear();
+ m_track = 0;
+}
+
+qlonglong MmRendererMetaData::duration() const
+{
+ return m_duration;
+}
+
+// Handling of pixel aspect ratio
+//
+// If the pixel aspect ratio is different from 1:1, it means the video needs to be stretched in
+// order to look natural.
+// For example, if the pixel width is 2, and the pixel height is 1, it means a video of 300x200
+// pixels needs to be displayed as 600x200 to look correct.
+// In order to support this the easiest way, we simply pretend that the actual size of the video
+// is 600x200, which will cause the video to be displayed in an aspect ratio of 3:1 instead of 3:2,
+// and therefore look correct.
+
+int MmRendererMetaData::height() const
+{
+ return m_height * m_pixelHeight;
+}
+
+int MmRendererMetaData::width() const
+{
+ return m_width * m_pixelWidth;
+}
+
+bool MmRendererMetaData::hasVideo() const
+{
+ // By default, assume no video if we can't extract the information
+ if (m_mediaType == -1)
+ return false;
+
+ return (m_mediaType & mediaTypeVideoFlag);
+}
+
+bool MmRendererMetaData::hasAudio() const
+{
+ // By default, assume audio only if we can't extract the information
+ if (m_mediaType == -1)
+ return true;
+
+ return (m_mediaType & mediaTypeAudioFlag);
+}
+
+QString MmRendererMetaData::title() const
+{
+ return m_title;
+}
+
+bool MmRendererMetaData::isSeekable() const
+{
+ return m_seekable;
+}
+
+QString MmRendererMetaData::artist() const
+{
+ return m_artist;
+}
+
+QString MmRendererMetaData::comment() const
+{
+ return m_comment;
+}
+
+QString MmRendererMetaData::genre() const
+{
+ return m_genre;
+}
+
+int MmRendererMetaData::year() const
+{
+ return m_year;
+}
+
+QString MmRendererMetaData::mediaType() const
+{
+ if (hasVideo())
+ return QLatin1String("video");
+ else if (hasAudio())
+ return QLatin1String("audio");
+ else
+ return QString();
+}
+
+int MmRendererMetaData::audioBitRate() const
+{
+ return m_audioBitRate;
+}
+
+int MmRendererMetaData::sampleRate() const
+{
+ return m_sampleRate;
+}
+
+QString MmRendererMetaData::album() const
+{
+ return m_album;
+}
+
+int MmRendererMetaData::track() const
+{
+ return m_track;
+}
+
+QSize MmRendererMetaData::resolution() const
+{
+ return QSize(width(), height());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadata.h b/src/plugins/qnx/mediaplayer/mmrenderermetadata.h
new file mode 100644
index 000000000..deb848a80
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermetadata.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERMETADATA_H
+#define MMRENDERERMETADATA_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QSize>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class MmRendererMetaData
+{
+public:
+ MmRendererMetaData();
+ bool parse(const QString &contextName);
+ void clear();
+
+ // Duration in milliseconds
+ qlonglong duration() const;
+
+ int height() const;
+ int width() const;
+ bool hasVideo() const;
+ bool hasAudio() const;
+ bool isSeekable() const;
+
+ QString title() const;
+ QString artist() const;
+ QString comment() const;
+ QString genre() const;
+ int year() const;
+ QString mediaType() const;
+ int audioBitRate() const;
+ int sampleRate() const;
+ QString album() const;
+ int track() const;
+ QSize resolution() const;
+
+private:
+ qlonglong m_duration;
+ int m_height;
+ int m_width;
+ int m_mediaType;
+ float m_pixelWidth;
+ float m_pixelHeight;
+ bool m_seekable;
+ QString m_title;
+ QString m_artist;
+ QString m_comment;
+ QString m_genre;
+ int m_year;
+ int m_audioBitRate;
+ int m_sampleRate;
+ QString m_album;
+ int m_track;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp
new file mode 100644
index 000000000..c0fe7d085
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrenderermetadatareadercontrol.h"
+#include <QtMultimedia/qmediametadata.h>
+
+QT_BEGIN_NAMESPACE
+
+MmRendererMetaDataReaderControl::MmRendererMetaDataReaderControl(QObject *parent)
+ : QMetaDataReaderControl(parent)
+{
+}
+
+bool MmRendererMetaDataReaderControl::isMetaDataAvailable() const
+{
+ return !availableMetaData().isEmpty();
+}
+
+QVariant MmRendererMetaDataReaderControl::metaData(const QString &key) const
+{
+ if (key == QMediaMetaData::Title)
+ return m_metaData.title();
+ else if (key == QMediaMetaData::Author)
+ return m_metaData.artist();
+ else if (key == QMediaMetaData::Comment)
+ return m_metaData.comment();
+ else if (key == QMediaMetaData::Genre)
+ return m_metaData.genre();
+ else if (key == QMediaMetaData::Year)
+ return m_metaData.year();
+ else if (key == QMediaMetaData::MediaType)
+ return m_metaData.mediaType();
+ else if (key == QMediaMetaData::Duration)
+ return m_metaData.duration();
+ else if (key == QMediaMetaData::AudioBitRate)
+ return m_metaData.audioBitRate();
+ else if (key == QMediaMetaData::SampleRate)
+ return m_metaData.sampleRate();
+ else if (key == QMediaMetaData::AlbumTitle)
+ return m_metaData.album();
+ else if (key == QMediaMetaData::TrackNumber)
+ return m_metaData.track();
+ else if (key == QMediaMetaData::Resolution)
+ return m_metaData.resolution();
+
+ return QVariant();
+}
+
+QStringList MmRendererMetaDataReaderControl::availableMetaData() const
+{
+ QStringList metaData;
+
+ if (!m_metaData.title().isEmpty())
+ metaData << QMediaMetaData::Title;
+ if (!m_metaData.artist().isEmpty())
+ metaData << QMediaMetaData::Author;
+ if (!m_metaData.comment().isEmpty())
+ metaData << QMediaMetaData::Comment;
+ if (!m_metaData.genre().isEmpty())
+ metaData << QMediaMetaData::Genre;
+ if (m_metaData.year() != 0)
+ metaData << QMediaMetaData::Year;
+ if (!m_metaData.mediaType().isEmpty())
+ metaData << QMediaMetaData::MediaType;
+ if (m_metaData.duration() != 0)
+ metaData << QMediaMetaData::Duration;
+ if (m_metaData.audioBitRate() != 0)
+ metaData << QMediaMetaData::AudioBitRate;
+ if (m_metaData.sampleRate() != 0)
+ metaData << QMediaMetaData::SampleRate;
+ if (!m_metaData.album().isEmpty())
+ metaData << QMediaMetaData::AlbumTitle;
+ if (m_metaData.track() != 0)
+ metaData << QMediaMetaData::TrackNumber;
+ if (m_metaData.resolution().isValid())
+ metaData << QMediaMetaData::Resolution;
+
+ return metaData;
+}
+
+void MmRendererMetaDataReaderControl::setMetaData(const MmRendererMetaData &data)
+{
+ const MmRendererMetaData oldMetaData = m_metaData;
+ const bool oldMetaDataAvailable = isMetaDataAvailable();
+
+ m_metaData = data;
+
+ bool changed = false;
+ if (m_metaData.title() != oldMetaData.title()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Title, m_metaData.title());
+ } else if (m_metaData.artist() != oldMetaData.artist()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Author, m_metaData.artist());
+ } else if (m_metaData.comment() != oldMetaData.comment()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Comment, m_metaData.comment());
+ } else if (m_metaData.genre() != oldMetaData.genre()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Genre, m_metaData.genre());
+ } else if (m_metaData.year() != oldMetaData.year()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Year, m_metaData.year());
+ } else if (m_metaData.mediaType() != oldMetaData.mediaType()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::MediaType, m_metaData.mediaType());
+ } else if (m_metaData.duration() != oldMetaData.duration()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Duration, m_metaData.duration());
+ } else if (m_metaData.audioBitRate() != oldMetaData.audioBitRate()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::AudioBitRate, m_metaData.audioBitRate());
+ } else if (m_metaData.sampleRate() != oldMetaData.sampleRate()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::SampleRate, m_metaData.sampleRate());
+ } else if (m_metaData.album() != oldMetaData.album()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::AlbumTitle, m_metaData.album());
+ } else if (m_metaData.track() != oldMetaData.track()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::TrackNumber, m_metaData.track());
+ } else if (m_metaData.resolution() != oldMetaData.resolution()) {
+ changed = true;
+ emit metaDataChanged(QMediaMetaData::Resolution, m_metaData.resolution());
+ }
+
+ if (changed)
+ emit metaDataChanged();
+
+ const bool metaDataAvailable = isMetaDataAvailable();
+ if (metaDataAvailable != oldMetaDataAvailable)
+ emit metaDataAvailableChanged(metaDataAvailable);
+}
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h
new file mode 100644
index 000000000..f824ca4d0
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERMETADATAREADERCONTROL_H
+#define MMRENDERERMETADATAREADERCONTROL_H
+
+#include "mmrenderermetadata.h"
+#include <qmetadatareadercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class MmRendererMetaDataReaderControl : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ explicit MmRendererMetaDataReaderControl(QObject *parent = 0);
+
+ bool isMetaDataAvailable() const Q_DECL_OVERRIDE;
+
+ QVariant metaData(const QString &key) const Q_DECL_OVERRIDE;
+ QStringList availableMetaData() const Q_DECL_OVERRIDE;
+
+ void setMetaData(const MmRendererMetaData &data);
+
+private:
+ MmRendererMetaData m_metaData;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
new file mode 100644
index 000000000..0abdfec49
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mmrendererplayervideorenderercontrol.h"
+
+#include "windowgrabber.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QVideoSurfaceFormat>
+
+#include <mm/renderer.h>
+
+QT_BEGIN_NAMESPACE
+
+static int winIdCounter = 0;
+
+MmRendererPlayerVideoRendererControl::MmRendererPlayerVideoRendererControl(QObject *parent)
+ : QVideoRendererControl(parent)
+ , m_windowGrabber(new WindowGrabber(this))
+ , m_context(0)
+ , m_videoId(-1)
+{
+ connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage)), SLOT(frameGrabbed(QImage)));
+}
+
+MmRendererPlayerVideoRendererControl::~MmRendererPlayerVideoRendererControl()
+{
+ detachDisplay();
+}
+
+QAbstractVideoSurface *MmRendererPlayerVideoRendererControl::surface() const
+{
+ return m_surface;
+}
+
+void MmRendererPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+{
+ m_surface = QPointer<QAbstractVideoSurface>(surface);
+}
+
+void MmRendererPlayerVideoRendererControl::attachDisplay(mmr_context_t *context)
+{
+ if (m_videoId != -1) {
+ qWarning() << "MmRendererPlayerVideoRendererControl: Video output already attached!";
+ return;
+ }
+
+ if (!context) {
+ qWarning() << "MmRendererPlayerVideoRendererControl: No media player context!";
+ return;
+ }
+
+ const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
+ if (windowGroupId.isEmpty()) {
+ qWarning() << "MmRendererPlayerVideoRendererControl: Unable to find window group";
+ return;
+ }
+
+ const QString windowName = QStringLiteral("MmRendererPlayerVideoRendererControl_%1_%2")
+ .arg(winIdCounter++)
+ .arg(QCoreApplication::applicationPid());
+
+ m_windowGrabber->setWindowId(windowName.toLatin1());
+
+ // Start with an invisible window, because we just want to grab the frames from it.
+ const QString videoDeviceUrl = QStringLiteral("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1")
+ .arg(windowName)
+ .arg(QString::fromLatin1(windowGroupId));
+
+ m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video");
+ if (m_videoId == -1) {
+ qWarning() << "mmr_output_attach() for video failed";
+ return;
+ }
+
+ m_context = context;
+}
+
+void MmRendererPlayerVideoRendererControl::detachDisplay()
+{
+ m_windowGrabber->stop();
+
+ if (m_surface)
+ m_surface->stop();
+
+ if (m_context && m_videoId != -1)
+ mmr_output_detach(m_context, m_videoId);
+
+ m_context = 0;
+ m_videoId = -1;
+}
+
+void MmRendererPlayerVideoRendererControl::pause()
+{
+ m_windowGrabber->pause();
+}
+
+void MmRendererPlayerVideoRendererControl::resume()
+{
+ m_windowGrabber->resume();
+}
+
+void MmRendererPlayerVideoRendererControl::frameGrabbed(const QImage &frame)
+{
+ if (m_surface) {
+ if (!m_surface->isActive()) {
+ m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
+ } else {
+ if (m_surface->surfaceFormat().frameSize() != frame.size()) {
+ m_surface->stop();
+ m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
+ }
+ }
+
+ m_surface->present(frame.copy());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h
new file mode 100644
index 000000000..4e271ad5d
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERPLAYERVIDEORENDERERCONTROL_H
+#define MMRENDERERPLAYERVIDEORENDERERCONTROL_H
+
+#include <QPointer>
+#include <qabstractvideosurface.h>
+#include <qvideorenderercontrol.h>
+
+typedef struct mmr_context mmr_context_t;
+
+QT_BEGIN_NAMESPACE
+
+class WindowGrabber;
+
+class MmRendererPlayerVideoRendererControl : public QVideoRendererControl
+{
+ Q_OBJECT
+public:
+ explicit MmRendererPlayerVideoRendererControl(QObject *parent = 0);
+ ~MmRendererPlayerVideoRendererControl();
+
+ QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE;
+ void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE;
+
+ // Called by media control
+ void attachDisplay(mmr_context_t *context);
+ void detachDisplay();
+ void pause();
+ void resume();
+
+private Q_SLOTS:
+ void frameGrabbed(const QImage &frame);
+
+private:
+ QPointer<QAbstractVideoSurface> m_surface;
+
+ WindowGrabber* m_windowGrabber;
+ mmr_context_t *m_context;
+
+ int m_videoId;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/mmrendererutil.cpp b/src/plugins/qnx/mediaplayer/mmrendererutil.cpp
new file mode 100644
index 000000000..61f85f3d9
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrendererutil.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrendererutil.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QString>
+#include <QXmlStreamReader>
+
+#include <mm/renderer.h>
+
+QT_BEGIN_NAMESPACE
+
+struct MmError {
+ int errorCode;
+ const char *name;
+};
+
+#define MM_ERROR_ENTRY(error) { error, #error }
+static const MmError mmErrors[] = {
+ MM_ERROR_ENTRY(MMR_ERROR_NONE),
+ MM_ERROR_ENTRY(MMR_ERROR_UNKNOWN ),
+ MM_ERROR_ENTRY(MMR_ERROR_INVALID_PARAMETER ),
+ MM_ERROR_ENTRY(MMR_ERROR_INVALID_STATE),
+ MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_VALUE),
+ MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_MEDIA_TYPE),
+ MM_ERROR_ENTRY(MMR_ERROR_MEDIA_PROTECTED),
+ MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_OPERATION),
+ MM_ERROR_ENTRY(MMR_ERROR_READ),
+ MM_ERROR_ENTRY(MMR_ERROR_WRITE),
+ MM_ERROR_ENTRY(MMR_ERROR_MEDIA_UNAVAILABLE),
+ MM_ERROR_ENTRY(MMR_ERROR_MEDIA_CORRUPTED),
+ MM_ERROR_ENTRY(MMR_ERROR_OUTPUT_UNAVAILABLE),
+ MM_ERROR_ENTRY(MMR_ERROR_NO_MEMORY),
+ MM_ERROR_ENTRY(MMR_ERROR_RESOURCE_UNAVAILABLE),
+ MM_ERROR_ENTRY(MMR_ERROR_MEDIA_DRM_NO_RIGHTS),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_CORRUPTED_DATA_STORE),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OUTPUT_PROTECTION),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_HDMI),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DISPLAYPORT),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DVI),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_VIDEO),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_AUDIO),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_TOSLINK),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_SPDIF),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_BLUETOOTH),
+ MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_WIRELESSHD),
+};
+static const unsigned int numMmErrors = sizeof(mmErrors) / sizeof(MmError);
+
+QString mmErrorMessage(const QString &msg, mmr_context_t *context, int *errorCode)
+{
+ const mmr_error_info_t * const mmError = mmr_error_info(context);
+
+ if (errorCode)
+ *errorCode = mmError->error_code;
+
+ if (mmError->error_code < numMmErrors) {
+ return QString("%1: %2 (code %3)").arg(msg).arg(mmErrors[mmError->error_code].name)
+ .arg(mmError->error_code);
+ } else {
+ return QString("%1: Unknown error code %2").arg(msg).arg(mmError->error_code);
+ }
+}
+
+bool checkForDrmPermission()
+{
+ QDir sandboxDir = QDir::home(); // always returns 'data' directory
+ sandboxDir.cdUp(); // change to app sandbox directory
+
+ QFile file(sandboxDir.filePath("app/native/bar-descriptor.xml"));
+ if (!file.open(QIODevice::ReadOnly)) {
+ qWarning() << "checkForDrmPermission: Unable to open bar-descriptor.xml";
+ return false;
+ }
+
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd()) {
+ reader.readNextStartElement();
+ if (reader.name() == QLatin1String("action")
+ || reader.name() == QLatin1String("permission")) {
+ if (reader.readElementText().trimmed() == QLatin1String("access_protected_media"))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/audio/qnxaudioutils.h b/src/plugins/qnx/mediaplayer/mmrendererutil.h
index ddd30b191..4b9adc27e 100644
--- a/src/plugins/qnx/audio/qnxaudioutils.h
+++ b/src/plugins/qnx/mediaplayer/mmrendererutil.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Research In Motion
+** Copyright (C) 2012 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
@@ -38,19 +38,20 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef MMRENDERERUTIL_H
+#define MMRENDERERUTIL_H
-#ifndef QNXAUDIOUTILS_H
-#define QNXAUDIOUTILS_H
+#include <QtCore/qglobal.h>
-#include "qaudiosystem.h"
-#include <sys/asoundlib.h>
+typedef struct mmr_context mmr_context_t;
QT_BEGIN_NAMESPACE
-namespace QnxAudioUtils
-{
- snd_pcm_channel_params_t formatToChannelParams(const QAudioFormat &format, QAudio::Mode mode, int fragmentSize);
-}
+class QString;
+
+QString mmErrorMessage(const QString &msg, mmr_context_t *context, int * errorCode = 0);
+
+bool checkForDrmPermission();
QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
new file mode 100644
index 000000000..c35c6d1ad
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mmrenderervideowindowcontrol.h"
+#include "mmrendererutil.h"
+#include <QtCore/qdebug.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+#include <mm/renderer.h>
+
+QT_BEGIN_NAMESPACE
+
+static int winIdCounter = 0;
+
+MmRendererVideoWindowControl::MmRendererVideoWindowControl(QObject *parent)
+ : QVideoWindowControl(parent),
+ m_videoId(-1),
+ m_winId(0),
+ m_context(0),
+ m_fullscreen(false),
+ m_aspectRatioMode(Qt::IgnoreAspectRatio),
+ m_window(0),
+ m_hue(0),
+ m_brightness(0),
+ m_contrast(0),
+ m_saturation(0)
+{
+}
+
+MmRendererVideoWindowControl::~MmRendererVideoWindowControl()
+{
+}
+
+WId MmRendererVideoWindowControl::winId() const
+{
+ return m_winId;
+}
+
+void MmRendererVideoWindowControl::setWinId(WId id)
+{
+ m_winId = id;
+}
+
+QRect MmRendererVideoWindowControl::displayRect() const
+{
+ return m_displayRect ;
+}
+
+void MmRendererVideoWindowControl::setDisplayRect(const QRect &rect)
+{
+ if (m_displayRect != rect) {
+ m_displayRect = rect;
+ updateVideoPosition();
+ }
+}
+
+bool MmRendererVideoWindowControl::isFullScreen() const
+{
+ return m_fullscreen;
+}
+
+void MmRendererVideoWindowControl::setFullScreen(bool fullScreen)
+{
+ if (m_fullscreen != fullScreen) {
+ m_fullscreen = fullScreen;
+ updateVideoPosition();
+ emit fullScreenChanged(m_fullscreen);
+ }
+}
+
+void MmRendererVideoWindowControl::repaint()
+{
+ // Nothing we can or should do here
+}
+
+QSize MmRendererVideoWindowControl::nativeSize() const
+{
+ return QSize(m_metaData.width(), m_metaData.height());
+}
+
+Qt::AspectRatioMode MmRendererVideoWindowControl::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void MmRendererVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ m_aspectRatioMode = mode;
+}
+
+int MmRendererVideoWindowControl::brightness() const
+{
+ return m_brightness;
+}
+
+void MmRendererVideoWindowControl::setBrightness(int brightness)
+{
+ if (m_brightness != brightness) {
+ m_brightness = brightness;
+ updateBrightness();
+ emit brightnessChanged(m_brightness);
+ }
+}
+
+int MmRendererVideoWindowControl::contrast() const
+{
+ return m_contrast;
+}
+
+void MmRendererVideoWindowControl::setContrast(int contrast)
+{
+ if (m_contrast != contrast) {
+ m_contrast = contrast;
+ updateContrast();
+ emit contrastChanged(m_contrast);
+ }
+}
+
+int MmRendererVideoWindowControl::hue() const
+{
+ return m_hue;
+}
+
+void MmRendererVideoWindowControl::setHue(int hue)
+{
+ if (m_hue != hue) {
+ m_hue = hue;
+ updateHue();
+ emit hueChanged(m_hue);
+ }
+}
+
+int MmRendererVideoWindowControl::saturation() const
+{
+ return m_saturation;
+}
+
+void MmRendererVideoWindowControl::setSaturation(int saturation)
+{
+ if (m_saturation != saturation) {
+ m_saturation = saturation;
+ updateSaturation();
+ emit saturationChanged(m_saturation);
+ }
+}
+
+void MmRendererVideoWindowControl::attachDisplay(mmr_context_t *context)
+{
+ if (m_videoId != -1) {
+ qDebug() << "MmRendererVideoWindowControl: Video output already attached!";
+ return;
+ }
+
+ if (!context) {
+ qDebug() << "MmRendererVideoWindowControl: No media player context!";
+ return;
+ }
+
+ QWindow *window = findWindow(m_winId);
+ if (!window) {
+ qDebug() << "MmRendererVideoWindowControl: No video window!";
+ return;
+ }
+
+ QPlatformNativeInterface * const nativeInterface = QGuiApplication::platformNativeInterface();
+ if (!nativeInterface) {
+ qDebug() << "MmRendererVideoWindowControl: Unable to get platform native interface";
+ return;
+ }
+
+ const char * const groupNameData = static_cast<const char *>(
+ nativeInterface->nativeResourceForWindow("windowGroup", window));
+ if (!groupNameData) {
+ qDebug() << "MmRendererVideoWindowControl: Unable to find window group for window" << window;
+ return;
+ }
+
+ const QString groupName = QString::fromLatin1(groupNameData);
+ m_windowName = QString("MmRendererVideoWindowControl_%1_%2").arg(winIdCounter++)
+ .arg(QCoreApplication::applicationPid());
+
+ nativeInterface->setWindowProperty(window->handle(),
+ QStringLiteral("mmRendererWindowName"), m_windowName);
+
+ // Start with an invisible window. If it would be visible right away, it would be at the wrong
+ // position, and we can only change the position once we get the window handle.
+ const QString videoDeviceUrl =
+ QString("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1").arg(m_windowName).arg(groupName);
+
+ m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video");
+ if (m_videoId == -1) {
+ qDebug() << mmErrorMessage("mmr_output_attach() for video failed", context);
+ return;
+ }
+
+ m_context = context;
+ updateVideoPosition();
+ updateHue();
+ updateContrast();
+ updateBrightness();
+ updateSaturation();
+}
+
+void MmRendererVideoWindowControl::updateVideoPosition()
+{
+ QWindow * const window = findWindow(m_winId);
+ if (m_context && m_videoId != -1 && window) {
+ QPoint topLeft = m_fullscreen ?
+ QPoint(0,0) :
+ window->mapToGlobal(m_displayRect.topLeft());
+
+ QScreen * const screen = window->screen();
+ int width = m_fullscreen ?
+ screen->size().width() :
+ m_displayRect.width();
+ int height = m_fullscreen ?
+ screen->size().height() :
+ m_displayRect.height();
+
+ if (m_metaData.hasVideo()) { // We need the source size to do aspect ratio scaling
+ const qreal sourceRatio = m_metaData.width() / static_cast<float>(m_metaData.height());
+ const qreal targetRatio = width / static_cast<float>(height);
+
+ if (m_aspectRatioMode == Qt::KeepAspectRatio) {
+ if (targetRatio < sourceRatio) {
+ // Need to make height smaller
+ const int newHeight = width / sourceRatio;
+ const int heightDiff = height - newHeight;
+ topLeft.ry() += heightDiff / 2;
+ height = newHeight;
+ } else {
+ // Need to make width smaller
+ const int newWidth = sourceRatio * height;
+ const int widthDiff = width - newWidth;
+ topLeft.rx() += widthDiff / 2;
+ width = newWidth;
+ }
+
+ } else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
+ if (targetRatio < sourceRatio) {
+ // Need to make width larger
+ const int newWidth = sourceRatio * height;
+ const int widthDiff = newWidth - width;
+ topLeft.rx() -= widthDiff / 2;
+ width = newWidth;
+ } else {
+ // Need to make height larger
+ const int newHeight = width / sourceRatio;
+ const int heightDiff = newHeight - height;
+ topLeft.ry() -= heightDiff / 2;
+ height = newHeight;
+ }
+ }
+ }
+
+ if (m_window != 0) {
+ const int position[2] = { topLeft.x(), topLeft.y() };
+ const int size[2] = { width, height };
+ const int visible = m_displayRect.isValid();
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, position) != 0)
+ perror("Setting video position failed");
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, size) != 0)
+ perror("Setting video size failed");
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visible) != 0)
+ perror("Setting video visibility failed");
+ }
+ }
+}
+
+void MmRendererVideoWindowControl::updateBrightness()
+{
+ if (m_window != 0) {
+ const int backendValue = m_brightness * 2.55f;
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BRIGHTNESS, &backendValue) != 0)
+ perror("Setting brightness failed");
+ }
+}
+
+void MmRendererVideoWindowControl::updateContrast()
+{
+ if (m_window != 0) {
+ const int backendValue = m_contrast * 1.27f;
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_CONTRAST, &backendValue) != 0)
+ perror("Setting contrast failed");
+ }
+}
+
+void MmRendererVideoWindowControl::updateHue()
+{
+ if (m_window != 0) {
+ const int backendValue = m_hue * 1.27f;
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_HUE, &backendValue) != 0)
+ perror("Setting hue failed");
+ }
+}
+
+void MmRendererVideoWindowControl::updateSaturation()
+{
+ if (m_window != 0) {
+ const int backendValue = m_saturation * 1.27f;
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SATURATION, &backendValue) != 0)
+ perror("Setting saturation failed");
+ }
+}
+
+void MmRendererVideoWindowControl::detachDisplay()
+{
+ if (m_context && m_videoId != -1)
+ mmr_output_detach(m_context, m_videoId);
+
+ m_context = 0;
+ m_videoId = -1;
+ m_metaData.clear();
+ m_windowName.clear();
+ m_window = 0;
+ m_hue = 0;
+ m_brightness = 0;
+ m_contrast = 0;
+ m_saturation = 0;
+}
+
+void MmRendererVideoWindowControl::setMetaData(const MmRendererMetaData &metaData)
+{
+ m_metaData = metaData;
+ emit nativeSizeChanged();
+
+ // To handle the updated source size data
+ updateVideoPosition();
+}
+
+void MmRendererVideoWindowControl::screenEventHandler(const screen_event_t &screen_event)
+{
+ int eventType;
+ if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
+ perror("MmRendererVideoWindowControl: Failed to query screen event type");
+ return;
+ }
+
+ if (eventType != SCREEN_EVENT_CREATE)
+ return;
+
+ screen_window_t window = 0;
+ if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
+ perror("MmRendererVideoWindowControl: Failed to query window property");
+ return;
+ }
+
+ const int maxIdStrLength = 128;
+ char idString[maxIdStrLength];
+ if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
+ perror("MmRendererVideoWindowControl: Failed to query window ID string");
+ return;
+ }
+
+ if (m_windowName == idString) {
+ m_window = window;
+ updateVideoPosition();
+
+ const int visibleFlag = 1;
+ if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visibleFlag) != 0) {
+ perror("MmRendererVideoWindowControl: Failed to make window visible");
+ return;
+ }
+ }
+}
+
+QWindow *MmRendererVideoWindowControl::findWindow(WId id) const
+{
+ Q_FOREACH (QWindow *window, QGuiApplication::allWindows())
+ if (window->winId() == id)
+ return window;
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h
new file mode 100644
index 000000000..cfc9603bb
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MMRENDERERVIDEOWINDOWCONTROL_H
+#define MMRENDERERVIDEOWINDOWCONTROL_H
+
+#include "mmrenderermetadata.h"
+#include <qvideowindowcontrol.h>
+#include <screen/screen.h>
+
+typedef struct mmr_context mmr_context_t;
+
+QT_BEGIN_NAMESPACE
+
+class MmRendererVideoWindowControl : public QVideoWindowControl
+{
+ Q_OBJECT
+public:
+ explicit MmRendererVideoWindowControl(QObject *parent = 0);
+ ~MmRendererVideoWindowControl();
+
+ WId winId() const Q_DECL_OVERRIDE;
+ void setWinId(WId id) Q_DECL_OVERRIDE;
+
+ QRect displayRect() const Q_DECL_OVERRIDE;
+ void setDisplayRect(const QRect &rect) Q_DECL_OVERRIDE;
+
+ bool isFullScreen() const Q_DECL_OVERRIDE;
+ void setFullScreen(bool fullScreen) Q_DECL_OVERRIDE;
+
+ void repaint() Q_DECL_OVERRIDE;
+
+ QSize nativeSize() const Q_DECL_OVERRIDE;
+
+ Qt::AspectRatioMode aspectRatioMode() const Q_DECL_OVERRIDE;
+ void setAspectRatioMode(Qt::AspectRatioMode mode) Q_DECL_OVERRIDE;
+
+ int brightness() const Q_DECL_OVERRIDE;
+ void setBrightness(int brightness) Q_DECL_OVERRIDE;
+
+ int contrast() const Q_DECL_OVERRIDE;
+ void setContrast(int contrast) Q_DECL_OVERRIDE;
+
+ int hue() const Q_DECL_OVERRIDE;
+ void setHue(int hue) Q_DECL_OVERRIDE;
+
+ int saturation() const Q_DECL_OVERRIDE;
+ void setSaturation(int saturation) Q_DECL_OVERRIDE;
+
+ //
+ // Called by media control
+ //
+ void detachDisplay();
+ void attachDisplay(mmr_context_t *context);
+ void setMetaData(const MmRendererMetaData &metaData);
+ void screenEventHandler(const screen_event_t &event);
+
+private:
+ QWindow *findWindow(WId id) const;
+ void updateVideoPosition();
+ void updateBrightness();
+ void updateContrast();
+ void updateHue();
+ void updateSaturation();
+
+ int m_videoId;
+ WId m_winId;
+ QRect m_displayRect;
+ mmr_context_t *m_context;
+ bool m_fullscreen;
+ MmRendererMetaData m_metaData;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QString m_windowName;
+ screen_window_t m_window;
+ int m_hue;
+ int m_brightness;
+ int m_contrast;
+ int m_saturation;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp
new file mode 100644
index 000000000..eb0842fb9
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ppsmediaplayercontrol.h"
+#include "mmrenderervideowindowcontrol.h"
+
+#include <QtCore/qfile.h>
+#include <QtCore/qsocketnotifier.h>
+#include <QtCore/private/qcore_unix_p.h>
+
+#include <screen/screen.h>
+#include <sys/pps.h>
+
+QT_BEGIN_NAMESPACE
+
+PpsMediaPlayerControl::PpsMediaPlayerControl(QObject *parent)
+ : MmRendererMediaPlayerControl(parent),
+ m_ppsStatusNotifier(0),
+ m_ppsStatusFd(-1),
+ m_ppsStateNotifier(0),
+ m_ppsStateFd(-1)
+ , m_previouslySeenState("STOPPED")
+{
+ openConnection();
+}
+
+PpsMediaPlayerControl::~PpsMediaPlayerControl()
+{
+ destroy();
+}
+
+void PpsMediaPlayerControl::startMonitoring(int, const QString &contextName)
+{
+ const QString ppsContextPath = QStringLiteral("/pps/services/multimedia/renderer/context/%1/").arg(contextName);
+ const QString ppsStatusPath = ppsContextPath + QStringLiteral("/status");
+
+ Q_ASSERT(m_ppsStatusFd == -1);
+ errno = 0;
+ m_ppsStatusFd = qt_safe_open(QFile::encodeName(ppsStatusPath).constData(), O_RDONLY);
+ if (m_ppsStatusFd == -1) {
+ emitPError(QStringLiteral("Unable to open %1: %2").arg(ppsStatusPath, qt_error_string(errno)));
+ return;
+ }
+
+ Q_ASSERT(!m_ppsStatusNotifier);
+ m_ppsStatusNotifier = new QSocketNotifier(m_ppsStatusFd, QSocketNotifier::Read);
+ connect(m_ppsStatusNotifier, SIGNAL(activated(int)), this, SLOT(ppsReadyRead(int)));
+
+
+ const QString ppsStatePath = ppsContextPath + QStringLiteral("/state");
+
+ Q_ASSERT(m_ppsStateFd == -1);
+ errno = 0;
+ m_ppsStateFd = qt_safe_open(QFile::encodeName(ppsStatePath).constData(), O_RDONLY);
+ if (m_ppsStateFd == -1) {
+ emitPError(QStringLiteral("Unable to open %1: %2").arg(ppsStatePath, qt_error_string(errno)));
+ return;
+ }
+
+ Q_ASSERT(!m_ppsStateNotifier);
+ m_ppsStateNotifier = new QSocketNotifier(m_ppsStateFd, QSocketNotifier::Read);
+ connect(m_ppsStateNotifier, SIGNAL(activated(int)), this, SLOT(ppsReadyRead(int)));
+
+ //ensure we receive any initial state
+ ppsReadyRead(m_ppsStatusFd);
+ ppsReadyRead(m_ppsStateFd);
+}
+
+void PpsMediaPlayerControl::stopMonitoring()
+{
+
+ if (m_ppsStatusFd != -1) {
+ ::close(m_ppsStatusFd);
+ m_ppsStatusFd = -1;
+ }
+
+ delete m_ppsStatusNotifier;
+ m_ppsStatusNotifier = 0;
+
+ if (m_ppsStateFd != -1) {
+ ::close(m_ppsStateFd);
+ m_ppsStateFd = -1;
+ }
+
+ delete m_ppsStateNotifier;
+ m_ppsStateNotifier = 0;
+}
+
+bool PpsMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
+{
+ Q_UNUSED(result)
+ if (eventType == "screen_event_t") {
+ screen_event_t event = static_cast<screen_event_t>(message);
+ if (MmRendererVideoWindowControl *control = videoWindowControl())
+ control->screenEventHandler(event);
+ }
+
+ return false;
+}
+
+void PpsMediaPlayerControl::ppsReadyRead(int fd)
+{
+ Q_ASSERT(fd == m_ppsStateFd || fd == m_ppsStatusFd);
+ const int bufferSize = 2048;
+ char buffer[bufferSize];
+ const ssize_t nread = qt_safe_read(fd, buffer, bufferSize - 1);
+ if (nread < 0) {
+ //TODO emit error?
+ }
+
+ if (nread == 0) {
+ return;
+ }
+
+ // nread is the real space necessary, not the amount read.
+ if (static_cast<size_t>(nread) > bufferSize - 1) {
+ //TODO emit error?
+ qCritical("BBMediaPlayerControl: PPS buffer size too short; need %u.", nread + 1);
+ return;
+ }
+
+ buffer[nread] = 0;
+
+ pps_decoder_t decoder;
+
+ if (pps_decoder_initialize(&decoder, buffer) != PPS_DECODER_OK) {
+ //TODO emit error?
+ qCritical("Could not initialize pps_decoder");
+ pps_decoder_cleanup(&decoder);
+ return;
+ }
+
+ pps_decoder_push(&decoder, 0);
+
+ const char *value = 0;
+ if (pps_decoder_get_string(&decoder, "bufferlevel", &value) == PPS_DECODER_OK) {
+ setMmBufferStatus(QString::fromLatin1(value));
+ }
+
+ if (pps_decoder_get_string(&decoder, "state", &value) == PPS_DECODER_OK) {
+ const QByteArray state = value;
+ if (state != m_previouslySeenState && state == "STOPPED")
+ handleMmStopped();
+ m_previouslySeenState = state;
+ }
+
+ if (pps_decoder_get_string(&decoder, "position", &value) == PPS_DECODER_OK) {
+ const QByteArray valueBa = QByteArray(value);
+ bool ok;
+ const qint64 position = valueBa.toLongLong(&ok);
+ if (!ok) {
+ qCritical("Could not parse position from '%s'", valueBa.constData());
+ } else {
+ setMmPosition(position);
+ }
+ }
+
+ pps_decoder_cleanup(&decoder);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h b/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h
new file mode 100644
index 000000000..e00d44dfd
--- /dev/null
+++ b/src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PPSMEDIAPLAYERCONTROL_H
+#define PPSMEDIAPLAYERCONTROL_H
+
+#include "mmrenderermediaplayercontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSocketNotifier;
+
+class PpsMediaPlayerControl Q_DECL_FINAL : public MmRendererMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ explicit PpsMediaPlayerControl(QObject *parent = 0);
+ ~PpsMediaPlayerControl();
+
+ void startMonitoring(int contextId, const QString &contextName) Q_DECL_OVERRIDE;
+ void stopMonitoring() Q_DECL_OVERRIDE;
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+ void ppsReadyRead(int fd);
+
+private:
+ QSocketNotifier *m_ppsStatusNotifier;
+ int m_ppsStatusFd;
+ QSocketNotifier *m_ppsStateNotifier;
+ int m_ppsStateFd;
+ QByteArray m_previouslySeenState;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/neutrino_mediaservice.json b/src/plugins/qnx/neutrino_mediaservice.json
new file mode 100644
index 000000000..919368d73
--- /dev/null
+++ b/src/plugins/qnx/neutrino_mediaservice.json
@@ -0,0 +1,4 @@
+{
+ "Keys": ["neutrinomultimedia"],
+ "Services": ["org.qt-project.qt.mediaplayer"]
+}
diff --git a/src/plugins/qnx/neutrinoserviceplugin.cpp b/src/plugins/qnx/neutrinoserviceplugin.cpp
new file mode 100644
index 000000000..423af1a84
--- /dev/null
+++ b/src/plugins/qnx/neutrinoserviceplugin.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "neutrinoserviceplugin.h"
+
+#include "mmrenderermediaplayerservice.h"
+
+QT_BEGIN_NAMESPACE
+
+NeutrinoServicePlugin::NeutrinoServicePlugin()
+{
+}
+
+QMediaService *NeutrinoServicePlugin::create(const QString &key)
+{
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
+ return new MmRendererMediaPlayerService();
+
+ return 0;
+}
+
+void NeutrinoServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+QMediaServiceProviderHint::Features NeutrinoServicePlugin::supportedFeatures(const QByteArray &service) const
+{
+ Q_UNUSED(service)
+ return QMediaServiceProviderHint::Features();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qnx/neutrinoserviceplugin.h b/src/plugins/qnx/neutrinoserviceplugin.h
new file mode 100644
index 000000000..2fc28233f
--- /dev/null
+++ b/src/plugins/qnx/neutrinoserviceplugin.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef NEUTRINOSERVICEPLUGIN_H
+#define NEUTRINOSERVICEPLUGIN_H
+
+#include <qmediaserviceproviderplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class NeutrinoServicePlugin
+ : public QMediaServiceProviderPlugin,
+ public QMediaServiceFeaturesInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "neutrino_mediaservice.json")
+public:
+ NeutrinoServicePlugin();
+
+ QMediaService *create(const QString &key) Q_DECL_OVERRIDE;
+ void release(QMediaService *service) Q_DECL_OVERRIDE;
+ QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro
index 3049729b8..f01562116 100644
--- a/src/plugins/qnx/qnx.pro
+++ b/src/plugins/qnx/qnx.pro
@@ -1,3 +1,22 @@
-TEMPLATE = subdirs
+TARGET = qtmedia_qnx
+QT += multimedia-private gui-private
-SUBDIRS = audio
+PLUGIN_TYPE=mediaservice
+PLUGIN_CLASS_NAME = BbServicePlugin
+load(qt_plugin)
+
+LIBS += -lscreen
+
+include(common/common.pri)
+include(mediaplayer/mediaplayer.pri)
+
+blackberry {
+ include(camera/camera.pri)
+ HEADERS += bbserviceplugin.h
+ SOURCES += bbserviceplugin.cpp
+ OTHER_FILES += blackberry_mediaservice.json
+} else {
+ HEADERS += neutrinoserviceplugin.h
+ SOURCES += neutrinoserviceplugin.cpp
+ OTHER_FILES += neutrino_mediaservice.json
+}