QNX: Restructure plugins

Now that the MmRenderer implementation is ported to plain QNX, rename
the directories and files accordingly:

"blackberry" becomes "qnx", replace the Bb prefix with MmRenderer for
classes concerned with mm-renderer. The legacy alsa support for plain qnx
is now "qnx-audio".

Change-Id: I6abd98ecdd713b2d5e554d42224dc30f13772f43
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
This commit is contained in:
Frank Osterfeld
2013-11-05 14:28:08 +01:00
committed by The Qt Project
parent 66219c9a28
commit 99667804e1
88 changed files with 283 additions and 280 deletions

View File

@@ -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

View File

@@ -1,3 +0,0 @@
{
"Keys": ["default"]
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 "bbmediaplayerservice.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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
{
"Keys": ["blackberrymultimedia"],
"Services": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer"]
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
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;
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;
private:
BbCameraSession *m_session;
QCameraExposure::FlashModes m_flashMode;
};
QT_END_NAMESPACE

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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");
}
QAbstractAudioInput *QnxAudioPlugin::createInput(const QByteArray &device)
QString BbImageEncoderControl::imageCodecDescription(const QString &codecName) const
{
Q_ASSERT(device == INPUT_ID);
Q_UNUSED(device);
return new QnxAudioInput();
if (codecName == QLatin1String("jpeg"))
return tr("JPEG image");
return QString();
}
QAbstractAudioOutput *QnxAudioPlugin::createOutput(const QByteArray &device)
QList<QSize> BbImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
{
Q_ASSERT(device == OUTPUT_ID);
Q_UNUSED(device);
return new QnxAudioOutput();
return m_session->supportedResolutions(settings, continuous);
}
QAbstractAudioDeviceInfo *QnxAudioPlugin::createDeviceInfo(const QByteArray &device, QAudio::Mode mode)
QImageEncoderSettings BbImageEncoderControl::imageSettings() const
{
Q_ASSERT(device == OUTPUT_ID || device == INPUT_ID);
return new QnxAudioDeviceInfo(device, mode);
return m_session->imageSettings();
}
void BbImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
{
m_session->setImageSettings(settings);
}
QT_END_NAMESPACE

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -0,0 +1,7 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/windowgrabber.h
SOURCES += \
$$PWD/windowgrabber.cpp

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
{
"Keys": ["neutrinomultimedia"],
"Services": ["org.qt-project.qt.mediaplayer"]
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
}