Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I42587537cadade4b3f45df18385adb760fb24430
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
OBJECTIVE_SOURCES += main.mm
|
OBJECTIVE_SOURCES += main.mm
|
||||||
|
|
||||||
LIBS += -framework AVFoundation
|
LIBS += -framework AVFoundation -framework Foundation
|
||||||
|
|||||||
@@ -39,9 +39,11 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:@"http://doesnotmatter.com"]];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
1
config.tests/gpu_vivante/gpu_vivante.pro
Normal file
1
config.tests/gpu_vivante/gpu_vivante.pro
Normal file
@@ -0,0 +1 @@
|
|||||||
|
SOURCES += main.cpp
|
||||||
50
config.tests/gpu_vivante/main.cpp
Normal file
50
config.tests/gpu_vivante/main.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
||||||
|
const int format = GL_VIV_YV12;
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtMultimedia 5.0
|
import QtMultimedia 5.2
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id : cameraUI
|
id : cameraUI
|
||||||
@@ -129,6 +129,7 @@ Rectangle {
|
|||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
source: camera
|
source: camera
|
||||||
|
autoOrientation: true
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoCaptureControls {
|
PhotoCaptureControls {
|
||||||
|
|||||||
@@ -140,8 +140,8 @@ void Camera::setCamera(const QByteArray &cameraDevice)
|
|||||||
connect(imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)), this,
|
connect(imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)), this,
|
||||||
SLOT(displayCaptureError(int,QCameraImageCapture::Error,QString)));
|
SLOT(displayCaptureError(int,QCameraImageCapture::Error,QString)));
|
||||||
|
|
||||||
connect(camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
|
connect(camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)),
|
||||||
this, SLOT(updateLockStatus(QCamera::LockStatus, QCamera::LockChangeReason)));
|
this, SLOT(updateLockStatus(QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
ui->captureWidget->setTabEnabled(0, (camera->isCaptureModeSupported(QCamera::CaptureStillImage)));
|
ui->captureWidget->setTabEnabled(0, (camera->isCaptureModeSupported(QCamera::CaptureStillImage)));
|
||||||
ui->captureWidget->setTabEnabled(1, (camera->isCaptureModeSupported(QCamera::CaptureVideo)));
|
ui->captureWidget->setTabEnabled(1, (camera->isCaptureModeSupported(QCamera::CaptureVideo)));
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ Player::Player(QWidget *parent)
|
|||||||
histogramLayout->addWidget(histogram, 1);
|
histogramLayout->addWidget(histogram, 1);
|
||||||
|
|
||||||
probe = new QVideoProbe(this);
|
probe = new QVideoProbe(this);
|
||||||
connect(probe, SIGNAL(videoFrameProbed(const QVideoFrame&)), histogram, SLOT(processFrame(QVideoFrame)));
|
connect(probe, SIGNAL(videoFrameProbed(QVideoFrame)), histogram, SLOT(processFrame(QVideoFrame)));
|
||||||
probe->setSource(player);
|
probe->setSource(player);
|
||||||
|
|
||||||
QPushButton *openButton = new QPushButton(tr("Open"), this);
|
QPushButton *openButton = new QPushButton(tr("Open"), this);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ win32 {
|
|||||||
qtCompileTest(gstreamer_appsrc)
|
qtCompileTest(gstreamer_appsrc)
|
||||||
}
|
}
|
||||||
qtCompileTest(resourcepolicy)
|
qtCompileTest(resourcepolicy)
|
||||||
|
qtCompileTest(gpu_vivante)
|
||||||
}
|
}
|
||||||
|
|
||||||
load(qt_parts)
|
load(qt_parts)
|
||||||
|
|||||||
@@ -440,6 +440,18 @@ void QDeclarativeAudio::seek(int position)
|
|||||||
This property holds the source URL of the media.
|
This property holds the source URL of the media.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty int QtMultimedia::Audio::loops
|
||||||
|
|
||||||
|
This property holds the number of times the media is played. A value of \c 0 or \c 1 means
|
||||||
|
the media will be played only once; set to \c Audio.Infinite to enable infinite looping.
|
||||||
|
|
||||||
|
The value can be changed while the media is playing, in which case it will update
|
||||||
|
the remaining loops to the new value.
|
||||||
|
|
||||||
|
The default is \c 1.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty bool QtMultimedia::Audio::autoLoad
|
\qmlproperty bool QtMultimedia::Audio::autoLoad
|
||||||
|
|
||||||
@@ -1232,6 +1244,18 @@ void QDeclarativeAudio::_q_statusChanged()
|
|||||||
This property holds the source URL of the media.
|
This property holds the source URL of the media.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty int QtMultimedia::MediaPlayer::loops
|
||||||
|
|
||||||
|
This property holds the number of times the media is played. A value of \c 0 or \c 1 means
|
||||||
|
the media will be played only once; set to \c MediaPlayer.Infinite to enable infinite looping.
|
||||||
|
|
||||||
|
The value can be changed while the media is playing, in which case it will update
|
||||||
|
the remaining loops to the new value.
|
||||||
|
|
||||||
|
The default is \c 1.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty bool QtMultimedia::MediaPlayer::autoLoad
|
\qmlproperty bool QtMultimedia::MediaPlayer::autoLoad
|
||||||
|
|
||||||
|
|||||||
@@ -184,16 +184,20 @@ void QSoundEffect::setSource(const QUrl &url)
|
|||||||
/*!
|
/*!
|
||||||
\qmlproperty int QtMultimedia::SoundEffect::loops
|
\qmlproperty int QtMultimedia::SoundEffect::loops
|
||||||
|
|
||||||
This property provides a way to control the number of times to repeat the sound on each play().
|
This property holds the number of times the sound is played. A value of 0 or 1 means
|
||||||
|
the sound will be played only once; set to SoundEffect.Infinite to enable infinite looping.
|
||||||
|
|
||||||
Set to SoundEffect.Infinite to enable infinite looping.
|
The value can be changed while the sound effect is playing, in which case it will update
|
||||||
|
the remaining loops to the new value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\property QSoundEffect::loops
|
\property QSoundEffect::loops
|
||||||
This property provides a way to control the number of times to repeat the sound on each play().
|
This property holds the number of times the sound is played. A value of 0 or 1 means
|
||||||
|
the sound will be played only once; set to SoundEffect.Infinite to enable infinite looping.
|
||||||
|
|
||||||
Set to QSoundEffect::Infinite to enable infinite looping.
|
The value can be changed while the sound effect is playing, in which case it will update
|
||||||
|
the remaining loops to the new value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -213,8 +217,14 @@ int QSoundEffect::loopCount() const
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Set the total number of times to repeat playing this sound effect on each play() call to \a loopCount.
|
Set the total number of times to play this sound effect to \a loopCount.
|
||||||
Pass \c QSoundEffect::Infinite to repeat until stop() is called.
|
|
||||||
|
Setting the loop count to 0 or 1 means the sound effect will be played only once;
|
||||||
|
pass \c QSoundEffect::Infinite to repeat indefinitely. The loop count can be changed while
|
||||||
|
the sound effect is playing, in which case it will update the remaining loops to
|
||||||
|
the new \a loopCount.
|
||||||
|
|
||||||
|
\sa loopsRemaining()
|
||||||
*/
|
*/
|
||||||
void QSoundEffect::setLoopCount(int loopCount)
|
void QSoundEffect::setLoopCount(int loopCount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -516,6 +516,8 @@ void QSoundEffectPrivate::setLoopCount(int loopCount)
|
|||||||
if (loopCount == 0)
|
if (loopCount == 0)
|
||||||
loopCount = 1;
|
loopCount = 1;
|
||||||
m_loopCount = loopCount;
|
m_loopCount = loopCount;
|
||||||
|
if (m_playing)
|
||||||
|
setLoopsRemaining(loopCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal QSoundEffectPrivate::volume() const
|
qreal QSoundEffectPrivate::volume() const
|
||||||
@@ -647,7 +649,7 @@ void QSoundEffectPrivate::play()
|
|||||||
emptyStream();
|
emptyStream();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_runningCount = m_loopCount;
|
setLoopsRemaining(m_loopCount);
|
||||||
playSample();
|
playSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ void QSoundEffectPrivate::setLoopCount(int loopCount)
|
|||||||
if (loopCount == 0)
|
if (loopCount == 0)
|
||||||
loopCount = 1;
|
loopCount = 1;
|
||||||
d->m_loopCount = loopCount;
|
d->m_loopCount = loopCount;
|
||||||
d->m_runningCount = loopCount;
|
if (d->m_playing)
|
||||||
|
setLoopsRemaining(loopCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal QSoundEffectPrivate::volume() const
|
qreal QSoundEffectPrivate::volume() const
|
||||||
@@ -228,7 +229,7 @@ QSoundEffect::Status QSoundEffectPrivate::status() const
|
|||||||
void QSoundEffectPrivate::play()
|
void QSoundEffectPrivate::play()
|
||||||
{
|
{
|
||||||
d->m_offset = 0;
|
d->m_offset = 0;
|
||||||
d->m_runningCount = d->m_loopCount;
|
setLoopsRemaining(d->m_loopCount);
|
||||||
#ifdef QT_QAUDIO_DEBUG
|
#ifdef QT_QAUDIO_DEBUG
|
||||||
qDebug() << this << "play";
|
qDebug() << this << "play";
|
||||||
#endif
|
#endif
|
||||||
@@ -283,7 +284,7 @@ void QSoundEffectPrivate::setPlaying(bool playing)
|
|||||||
|
|
||||||
void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining)
|
void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining)
|
||||||
{
|
{
|
||||||
if (!d->m_runningCount && loopsRemaining)
|
if (d->m_runningCount == loopsRemaining)
|
||||||
return;
|
return;
|
||||||
#ifdef QT_QAUDIO_DEBUG
|
#ifdef QT_QAUDIO_DEBUG
|
||||||
qDebug() << this << "setLoopsRemaining " << loopsRemaining;
|
qDebug() << this << "setLoopsRemaining " << loopsRemaining;
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
INCLUDEPATH += camera
|
INCLUDEPATH += camera
|
||||||
|
|
||||||
|
PRIVATE_HEADERS += \
|
||||||
|
camera/qcamera_p.h
|
||||||
|
|
||||||
PUBLIC_HEADERS += \
|
PUBLIC_HEADERS += \
|
||||||
camera/qcamera.h \
|
camera/qcamera.h \
|
||||||
camera/qcameraimagecapture.h \
|
camera/qcameraimagecapture.h \
|
||||||
camera/qcameraexposure.h \
|
camera/qcameraexposure.h \
|
||||||
camera/qcamerafocus.h \
|
camera/qcamerafocus.h \
|
||||||
camera/qcameraimageprocessing.h
|
camera/qcameraimageprocessing.h \
|
||||||
|
camera/qcamerainfo.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
camera/qcamera.cpp \
|
camera/qcamera.cpp \
|
||||||
camera/qcameraexposure.cpp \
|
camera/qcameraexposure.cpp \
|
||||||
camera/qcamerafocus.cpp \
|
camera/qcamerafocus.cpp \
|
||||||
camera/qcameraimageprocessing.cpp \
|
camera/qcameraimageprocessing.cpp \
|
||||||
camera/qcameraimagecapture.cpp
|
camera/qcameraimagecapture.cpp \
|
||||||
|
camera/qcamerainfo.cpp
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,11 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qvideosurfaceoutput_p.h"
|
|
||||||
#include "qmediaobject_p.h"
|
#include "qcamera_p.h"
|
||||||
#include "qmediaserviceprovider_p.h"
|
#include "qmediaserviceprovider_p.h"
|
||||||
|
|
||||||
#include <qcamera.h>
|
#include <qcamerainfo.h>
|
||||||
#include <qcameracontrol.h>
|
#include <qcameracontrol.h>
|
||||||
#include <qcameralockscontrol.h>
|
#include <qcameralockscontrol.h>
|
||||||
#include <qcameraexposurecontrol.h>
|
#include <qcameraexposurecontrol.h>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
#include <qcameraimageprocessingcontrol.h>
|
#include <qcameraimageprocessingcontrol.h>
|
||||||
#include <qcameraimagecapturecontrol.h>
|
#include <qcameraimagecapturecontrol.h>
|
||||||
#include <qvideodeviceselectorcontrol.h>
|
#include <qvideodeviceselectorcontrol.h>
|
||||||
|
#include <qcamerainfocontrol.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ public:
|
|||||||
qRegisterMetaType<QCamera::LockType>("QCamera::LockType");
|
qRegisterMetaType<QCamera::LockType>("QCamera::LockType");
|
||||||
qRegisterMetaType<QCamera::LockStatus>("QCamera::LockStatus");
|
qRegisterMetaType<QCamera::LockStatus>("QCamera::LockStatus");
|
||||||
qRegisterMetaType<QCamera::LockChangeReason>("QCamera::LockChangeReason");
|
qRegisterMetaType<QCamera::LockChangeReason>("QCamera::LockChangeReason");
|
||||||
|
qRegisterMetaType<QCamera::Position>("QCamera::Position");
|
||||||
}
|
}
|
||||||
} _registerCameraMetaTypes;
|
} _registerCameraMetaTypes;
|
||||||
}
|
}
|
||||||
@@ -85,82 +87,16 @@ QT_BEGIN_NAMESPACE
|
|||||||
\ingroup multimedia
|
\ingroup multimedia
|
||||||
\ingroup multimedia_camera
|
\ingroup multimedia_camera
|
||||||
|
|
||||||
QCamera can be used with QVideoWidget for viewfinder display,
|
QCamera can be used with QCameraViewfinder for viewfinder display,
|
||||||
QMediaRecorder for video recording and QCameraImageCapture for image taking.
|
QMediaRecorder for video recording and QCameraImageCapture for image taking.
|
||||||
|
|
||||||
|
You can use QCameraInfo to list available cameras and choose which one to use.
|
||||||
|
|
||||||
|
\snippet multimedia-snippets/camera.cpp Camera selection
|
||||||
|
|
||||||
See the \l{Camera Overview}{camera overview} for more information.
|
See the \l{Camera Overview}{camera overview} for more information.
|
||||||
|
|
||||||
\snippet multimedia-snippets/media.cpp Request control
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class QCameraPrivate : public QMediaObjectPrivate
|
|
||||||
{
|
|
||||||
Q_DECLARE_NON_CONST_PUBLIC(QCamera)
|
|
||||||
public:
|
|
||||||
QCameraPrivate():
|
|
||||||
QMediaObjectPrivate(),
|
|
||||||
provider(0),
|
|
||||||
control(0),
|
|
||||||
deviceControl(0),
|
|
||||||
viewfinder(0),
|
|
||||||
capture(0),
|
|
||||||
state(QCamera::UnloadedState),
|
|
||||||
error(QCamera::NoError),
|
|
||||||
supportedLocks(QCamera::NoLock),
|
|
||||||
requestedLocks(QCamera::NoLock),
|
|
||||||
lockStatus(QCamera::Unlocked),
|
|
||||||
lockChangeReason(QCamera::UserRequest),
|
|
||||||
supressLockChangedSignal(false),
|
|
||||||
restartPending(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void initControls();
|
|
||||||
|
|
||||||
QMediaServiceProvider *provider;
|
|
||||||
|
|
||||||
QCameraControl *control;
|
|
||||||
QVideoDeviceSelectorControl *deviceControl;
|
|
||||||
QCameraLocksControl *locksControl;
|
|
||||||
|
|
||||||
QCameraExposure *cameraExposure;
|
|
||||||
QCameraFocus *cameraFocus;
|
|
||||||
QCameraImageProcessing *imageProcessing;
|
|
||||||
|
|
||||||
QObject *viewfinder;
|
|
||||||
QObject *capture;
|
|
||||||
|
|
||||||
QCamera::State state;
|
|
||||||
|
|
||||||
QCamera::Error error;
|
|
||||||
QString errorString;
|
|
||||||
|
|
||||||
QCamera::LockTypes supportedLocks;
|
|
||||||
QCamera::LockTypes requestedLocks;
|
|
||||||
|
|
||||||
QCamera::LockStatus lockStatus;
|
|
||||||
QCamera::LockChangeReason lockChangeReason;
|
|
||||||
bool supressLockChangedSignal;
|
|
||||||
|
|
||||||
bool restartPending;
|
|
||||||
|
|
||||||
QVideoSurfaceOutput surfaceViewfinder;
|
|
||||||
|
|
||||||
void _q_error(int error, const QString &errorString);
|
|
||||||
void unsetError() { error = QCamera::NoError; errorString.clear(); }
|
|
||||||
|
|
||||||
void setState(QCamera::State);
|
|
||||||
|
|
||||||
void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason);
|
|
||||||
void _q_updateState(QCamera::State newState);
|
|
||||||
void _q_preparePropertyChange(int changeType);
|
|
||||||
void _q_restartCamera();
|
|
||||||
void updateLockStatus();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void QCameraPrivate::_q_error(int error, const QString &errorString)
|
void QCameraPrivate::_q_error(int error, const QString &errorString)
|
||||||
{
|
{
|
||||||
Q_Q(QCamera);
|
Q_Q(QCamera);
|
||||||
@@ -168,8 +104,6 @@ void QCameraPrivate::_q_error(int error, const QString &errorString)
|
|||||||
this->error = QCamera::Error(error);
|
this->error = QCamera::Error(error);
|
||||||
this->errorString = errorString;
|
this->errorString = errorString;
|
||||||
|
|
||||||
qWarning() << "Camera error:" << errorString;
|
|
||||||
|
|
||||||
emit q->error(this->error);
|
emit q->error(this->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +162,16 @@ void QCameraPrivate::_q_restartCamera()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QCameraPrivate::init()
|
||||||
|
{
|
||||||
|
Q_Q(QCamera);
|
||||||
|
provider = QMediaServiceProvider::defaultServiceProvider();
|
||||||
|
initControls();
|
||||||
|
cameraExposure = new QCameraExposure(q);
|
||||||
|
cameraFocus = new QCameraFocus(q);
|
||||||
|
imageProcessing = new QCameraImageProcessing(q);
|
||||||
|
}
|
||||||
|
|
||||||
void QCameraPrivate::initControls()
|
void QCameraPrivate::initControls()
|
||||||
{
|
{
|
||||||
Q_Q(QCamera);
|
Q_Q(QCamera);
|
||||||
@@ -238,6 +182,7 @@ void QCameraPrivate::initControls()
|
|||||||
control = qobject_cast<QCameraControl *>(service->requestControl(QCameraControl_iid));
|
control = qobject_cast<QCameraControl *>(service->requestControl(QCameraControl_iid));
|
||||||
locksControl = qobject_cast<QCameraLocksControl *>(service->requestControl(QCameraLocksControl_iid));
|
locksControl = qobject_cast<QCameraLocksControl *>(service->requestControl(QCameraLocksControl_iid));
|
||||||
deviceControl = qobject_cast<QVideoDeviceSelectorControl*>(service->requestControl(QVideoDeviceSelectorControl_iid));
|
deviceControl = qobject_cast<QVideoDeviceSelectorControl*>(service->requestControl(QVideoDeviceSelectorControl_iid));
|
||||||
|
infoControl = qobject_cast<QCameraInfoControl*>(service->requestControl(QCameraInfoControl_iid));
|
||||||
|
|
||||||
if (control) {
|
if (control) {
|
||||||
q->connect(control, SIGNAL(stateChanged(QCamera::State)), q, SLOT(_q_updateState(QCamera::State)));
|
q->connect(control, SIGNAL(stateChanged(QCamera::State)), q, SLOT(_q_updateState(QCamera::State)));
|
||||||
@@ -259,12 +204,43 @@ void QCameraPrivate::initControls()
|
|||||||
control = 0;
|
control = 0;
|
||||||
locksControl = 0;
|
locksControl = 0;
|
||||||
deviceControl = 0;
|
deviceControl = 0;
|
||||||
|
infoControl = 0;
|
||||||
|
|
||||||
error = QCamera::ServiceMissingError;
|
error = QCamera::ServiceMissingError;
|
||||||
errorString = QCamera::tr("The camera service is missing");
|
errorString = QCamera::tr("The camera service is missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QCameraPrivate::clear()
|
||||||
|
{
|
||||||
|
delete cameraExposure;
|
||||||
|
delete cameraFocus;
|
||||||
|
delete imageProcessing;
|
||||||
|
|
||||||
|
if (service) {
|
||||||
|
if (control)
|
||||||
|
service->releaseControl(control);
|
||||||
|
if (locksControl)
|
||||||
|
service->releaseControl(locksControl);
|
||||||
|
if (deviceControl)
|
||||||
|
service->releaseControl(deviceControl);
|
||||||
|
if (infoControl)
|
||||||
|
service->releaseControl(infoControl);
|
||||||
|
|
||||||
|
provider->releaseService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
cameraExposure = 0;
|
||||||
|
cameraFocus = 0;
|
||||||
|
imageProcessing = 0;
|
||||||
|
control = 0;
|
||||||
|
locksControl = 0;
|
||||||
|
deviceControl = 0;
|
||||||
|
infoControl = 0;
|
||||||
|
service = 0;
|
||||||
|
supportedLocks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void QCameraPrivate::updateLockStatus()
|
void QCameraPrivate::updateLockStatus()
|
||||||
{
|
{
|
||||||
Q_Q(QCamera);
|
Q_Q(QCamera);
|
||||||
@@ -337,42 +313,103 @@ QCamera::QCamera(QObject *parent):
|
|||||||
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA))
|
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA))
|
||||||
{
|
{
|
||||||
Q_D(QCamera);
|
Q_D(QCamera);
|
||||||
d->provider = QMediaServiceProvider::defaultServiceProvider();
|
d->init();
|
||||||
d->initControls();
|
|
||||||
d->cameraExposure = new QCameraExposure(this);
|
// Select the default camera
|
||||||
d->cameraFocus = new QCameraFocus(this);
|
if (d->service != 0 && d->deviceControl)
|
||||||
d->imageProcessing = new QCameraImageProcessing(this);
|
d->deviceControl->setSelectedDevice(d->deviceControl->defaultDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Construct a QCamera from device name \a device and \a parent.
|
Construct a QCamera from \a deviceName and \a parent.
|
||||||
|
|
||||||
|
If no camera with that \a deviceName exists, the camera object will
|
||||||
|
be invalid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QCamera::QCamera(const QByteArray& device, QObject *parent):
|
QCamera::QCamera(const QByteArray& deviceName, QObject *parent):
|
||||||
QMediaObject(*new QCameraPrivate, parent,
|
QMediaObject(*new QCameraPrivate, parent,
|
||||||
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA, QMediaServiceProviderHint(device)))
|
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA,
|
||||||
|
QMediaServiceProviderHint(deviceName)))
|
||||||
{
|
{
|
||||||
Q_D(QCamera);
|
Q_D(QCamera);
|
||||||
d->provider = QMediaServiceProvider::defaultServiceProvider();
|
d->init();
|
||||||
d->initControls();
|
|
||||||
|
|
||||||
if (d->service != 0) {
|
if (d->service != 0) {
|
||||||
//pass device name to service
|
//pass device name to service
|
||||||
if (d->deviceControl) {
|
if (d->deviceControl) {
|
||||||
QString deviceName = QString::fromLatin1(device);
|
const QString name = QString::fromLatin1(deviceName);
|
||||||
|
for (int i = 0; i < d->deviceControl->deviceCount(); i++) {
|
||||||
for (int i=0; i<d->deviceControl->deviceCount(); i++) {
|
if (d->deviceControl->deviceName(i) == name) {
|
||||||
if (d->deviceControl->deviceName(i) == deviceName) {
|
|
||||||
d->deviceControl->setSelectedDevice(i);
|
d->deviceControl->setSelectedDevice(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d->cameraExposure = new QCameraExposure(this);
|
/*!
|
||||||
d->cameraFocus = new QCameraFocus(this);
|
\since 5.3
|
||||||
d->imageProcessing = new QCameraImageProcessing(this);
|
|
||||||
|
Construct a QCamera from a camera description \a cameraInfo and \a parent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QCamera::QCamera(const QCameraInfo &cameraInfo, QObject *parent)
|
||||||
|
: QMediaObject(*new QCameraPrivate,
|
||||||
|
parent,
|
||||||
|
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA,
|
||||||
|
QMediaServiceProviderHint(cameraInfo.deviceName().toLatin1())))
|
||||||
|
{
|
||||||
|
Q_D(QCamera);
|
||||||
|
d->init();
|
||||||
|
|
||||||
|
if (d->service != 0 && d->deviceControl) {
|
||||||
|
for (int i = 0; i < d->deviceControl->deviceCount(); i++) {
|
||||||
|
if (d->deviceControl->deviceName(i) == cameraInfo.deviceName()) {
|
||||||
|
d->deviceControl->setSelectedDevice(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Construct a QCamera which uses a hardware camera located a the specified \a position.
|
||||||
|
|
||||||
|
For example on a mobile phone it can be used to easily choose between front-facing and
|
||||||
|
back-facing cameras.
|
||||||
|
|
||||||
|
If no camera is available at the specified \a position or if \a position is
|
||||||
|
QCamera::UnspecifiedPosition, the default camera is used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QCamera::QCamera(QCamera::Position position, QObject *parent)
|
||||||
|
: QMediaObject(*new QCameraPrivate,
|
||||||
|
parent,
|
||||||
|
QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA, QMediaServiceProviderHint(position)))
|
||||||
|
{
|
||||||
|
Q_D(QCamera);
|
||||||
|
d->init();
|
||||||
|
|
||||||
|
if (d->service != 0 && d->deviceControl) {
|
||||||
|
bool selectDefault = true;
|
||||||
|
|
||||||
|
if (d->infoControl && position != UnspecifiedPosition) {
|
||||||
|
for (int i = 0; i < d->deviceControl->deviceCount(); i++) {
|
||||||
|
if (d->infoControl->cameraPosition(d->deviceControl->deviceName(i)) == position) {
|
||||||
|
d->deviceControl->setSelectedDevice(i);
|
||||||
|
selectDefault = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectDefault)
|
||||||
|
d->deviceControl->setSelectedDevice(d->deviceControl->defaultDevice());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -382,23 +419,7 @@ QCamera::QCamera(const QByteArray& device, QObject *parent):
|
|||||||
QCamera::~QCamera()
|
QCamera::~QCamera()
|
||||||
{
|
{
|
||||||
Q_D(QCamera);
|
Q_D(QCamera);
|
||||||
delete d->cameraExposure;
|
d->clear();
|
||||||
d->cameraExposure = 0;
|
|
||||||
delete d->cameraFocus;
|
|
||||||
d->cameraFocus = 0;
|
|
||||||
delete d->imageProcessing;
|
|
||||||
d->imageProcessing = 0;
|
|
||||||
|
|
||||||
if (d->service) {
|
|
||||||
if (d->control)
|
|
||||||
d->service->releaseControl(d->control);
|
|
||||||
if (d->locksControl)
|
|
||||||
d->service->releaseControl(d->locksControl);
|
|
||||||
if (d->deviceControl)
|
|
||||||
d->service->releaseControl(d->deviceControl);
|
|
||||||
|
|
||||||
d->provider->releaseService(d->service);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -622,9 +643,11 @@ void QCamera::unload()
|
|||||||
d->setState(QCamera::UnloadedState);
|
d->setState(QCamera::UnloadedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 3)
|
||||||
/*!
|
/*!
|
||||||
Returns a list of camera device's available from the default service provider.
|
Returns a list of camera device's available from the default service provider.
|
||||||
|
\deprecated
|
||||||
|
\sa QCameraInfo::availableCameras()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QList<QByteArray> QCamera::availableDevices()
|
QList<QByteArray> QCamera::availableDevices()
|
||||||
@@ -634,12 +657,15 @@ QList<QByteArray> QCamera::availableDevices()
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the description of the \a device.
|
Returns the description of the \a device.
|
||||||
|
\deprecated
|
||||||
|
\sa QCameraInfo::availableCameras(), QCameraInfo::description()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QString QCamera::deviceDescription(const QByteArray &device)
|
QString QCamera::deviceDescription(const QByteArray &device)
|
||||||
{
|
{
|
||||||
return QMediaServiceProvider::defaultServiceProvider()->deviceDescription(QByteArray(Q_MEDIASERVICE_CAMERA), device);
|
return QMediaServiceProvider::defaultServiceProvider()->deviceDescription(QByteArray(Q_MEDIASERVICE_CAMERA), device);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QCamera::State QCamera::state() const
|
QCamera::State QCamera::state() const
|
||||||
{
|
{
|
||||||
@@ -972,6 +998,25 @@ void QCamera::unlock()
|
|||||||
Signal emitted when error state changes to \a value.
|
Signal emitted when error state changes to \a value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum QCamera::Position
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
This enum specifies the physical position of the camera on the system hardware.
|
||||||
|
|
||||||
|
\value UnspecifiedPosition The camera position is unspecified or unknown.
|
||||||
|
|
||||||
|
\value BackFace The camera is on the back face of the system hardware. For example on a
|
||||||
|
mobile device, it means it is on the opposite side to that of the screen.
|
||||||
|
|
||||||
|
\value FrontFace The camera is on the front face of the system hardware. For example on a
|
||||||
|
mobile device, it means it is on the same side as that of the screen. Viewfinder frames of
|
||||||
|
front-facing cameras are mirrored horizontally, so the users can see themselves as looking
|
||||||
|
into a mirror. Captured images or videos are not mirrored.
|
||||||
|
|
||||||
|
\sa QCameraInfo::position()
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void QCamera::captureModeChanged(QCamera::CaptureModes mode)
|
\fn void QCamera::captureModeChanged(QCamera::CaptureModes mode)
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QAbstractVideoSurface;
|
class QAbstractVideoSurface;
|
||||||
class QVideoWidget;
|
class QVideoWidget;
|
||||||
class QGraphicsVideoItem;
|
class QGraphicsVideoItem;
|
||||||
|
class QCameraInfo;
|
||||||
|
|
||||||
class QCameraPrivate;
|
class QCameraPrivate;
|
||||||
class Q_MULTIMEDIA_EXPORT QCamera : public QMediaObject
|
class Q_MULTIMEDIA_EXPORT QCamera : public QMediaObject
|
||||||
@@ -81,6 +82,7 @@ class Q_MULTIMEDIA_EXPORT QCamera : public QMediaObject
|
|||||||
Q_ENUMS(LockStatus)
|
Q_ENUMS(LockStatus)
|
||||||
Q_ENUMS(LockChangeReason)
|
Q_ENUMS(LockChangeReason)
|
||||||
Q_ENUMS(LockType)
|
Q_ENUMS(LockType)
|
||||||
|
Q_ENUMS(Position)
|
||||||
public:
|
public:
|
||||||
enum Status {
|
enum Status {
|
||||||
UnavailableStatus,
|
UnavailableStatus,
|
||||||
@@ -141,12 +143,23 @@ public:
|
|||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(LockTypes, LockType)
|
Q_DECLARE_FLAGS(LockTypes, LockType)
|
||||||
|
|
||||||
|
enum Position
|
||||||
|
{
|
||||||
|
UnspecifiedPosition,
|
||||||
|
BackFace,
|
||||||
|
FrontFace
|
||||||
|
};
|
||||||
|
|
||||||
QCamera(QObject *parent = 0);
|
QCamera(QObject *parent = 0);
|
||||||
QCamera(const QByteArray& device, QObject *parent = 0);
|
QCamera(const QByteArray& deviceName, QObject *parent = 0);
|
||||||
|
QCamera(const QCameraInfo& cameraInfo, QObject *parent = 0);
|
||||||
|
QCamera(QCamera::Position position, QObject *parent = 0);
|
||||||
~QCamera();
|
~QCamera();
|
||||||
|
|
||||||
static QList<QByteArray> availableDevices();
|
#if QT_DEPRECATED_SINCE(5, 3)
|
||||||
static QString deviceDescription(const QByteArray &device);
|
QT_DEPRECATED static QList<QByteArray> availableDevices();
|
||||||
|
QT_DEPRECATED static QString deviceDescription(const QByteArray &device);
|
||||||
|
#endif
|
||||||
|
|
||||||
QMultimedia::AvailabilityStatus availability() const;
|
QMultimedia::AvailabilityStatus availability() const;
|
||||||
|
|
||||||
@@ -209,6 +222,7 @@ private:
|
|||||||
Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
|
Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
|
||||||
Q_PRIVATE_SLOT(d_func(), void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason))
|
Q_PRIVATE_SLOT(d_func(), void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason))
|
||||||
Q_PRIVATE_SLOT(d_func(), void _q_updateState(QCamera::State))
|
Q_PRIVATE_SLOT(d_func(), void _q_updateState(QCamera::State))
|
||||||
|
friend class QCameraInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCamera::LockTypes)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QCamera::LockTypes)
|
||||||
@@ -223,6 +237,7 @@ Q_DECLARE_METATYPE(QCamera::CaptureModes)
|
|||||||
Q_DECLARE_METATYPE(QCamera::LockType)
|
Q_DECLARE_METATYPE(QCamera::LockType)
|
||||||
Q_DECLARE_METATYPE(QCamera::LockStatus)
|
Q_DECLARE_METATYPE(QCamera::LockStatus)
|
||||||
Q_DECLARE_METATYPE(QCamera::LockChangeReason)
|
Q_DECLARE_METATYPE(QCamera::LockChangeReason)
|
||||||
|
Q_DECLARE_METATYPE(QCamera::Position)
|
||||||
|
|
||||||
Q_MEDIA_ENUM_DEBUG(QCamera, State)
|
Q_MEDIA_ENUM_DEBUG(QCamera, State)
|
||||||
Q_MEDIA_ENUM_DEBUG(QCamera, Status)
|
Q_MEDIA_ENUM_DEBUG(QCamera, Status)
|
||||||
@@ -231,5 +246,6 @@ Q_MEDIA_ENUM_DEBUG(QCamera, CaptureMode)
|
|||||||
Q_MEDIA_ENUM_DEBUG(QCamera, LockType)
|
Q_MEDIA_ENUM_DEBUG(QCamera, LockType)
|
||||||
Q_MEDIA_ENUM_DEBUG(QCamera, LockStatus)
|
Q_MEDIA_ENUM_DEBUG(QCamera, LockStatus)
|
||||||
Q_MEDIA_ENUM_DEBUG(QCamera, LockChangeReason)
|
Q_MEDIA_ENUM_DEBUG(QCamera, LockChangeReason)
|
||||||
|
Q_MEDIA_ENUM_DEBUG(QCamera, Position)
|
||||||
|
|
||||||
#endif // QCAMERA_H
|
#endif // QCAMERA_H
|
||||||
|
|||||||
141
src/multimedia/camera/qcamera_p.h
Normal file
141
src/multimedia/camera/qcamera_p.h
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 QCAMERA_P_H
|
||||||
|
#define QCAMERA_P_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Qt API. It exists purely as an
|
||||||
|
// implementation detail. This header file may change from version to
|
||||||
|
// version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "qmediaobject_p.h"
|
||||||
|
#include "qvideosurfaceoutput_p.h"
|
||||||
|
#include "qcamera.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QMediaServiceProvider;
|
||||||
|
class QCameraControl;
|
||||||
|
class QVideoDeviceSelectorControl;
|
||||||
|
class QCameraLocksControl;
|
||||||
|
class QCameraInfoControl;
|
||||||
|
|
||||||
|
class QCameraPrivate : public QMediaObjectPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_NON_CONST_PUBLIC(QCamera)
|
||||||
|
public:
|
||||||
|
QCameraPrivate():
|
||||||
|
QMediaObjectPrivate(),
|
||||||
|
provider(0),
|
||||||
|
control(0),
|
||||||
|
deviceControl(0),
|
||||||
|
locksControl(0),
|
||||||
|
infoControl(0),
|
||||||
|
viewfinder(0),
|
||||||
|
capture(0),
|
||||||
|
state(QCamera::UnloadedState),
|
||||||
|
error(QCamera::NoError),
|
||||||
|
supportedLocks(QCamera::NoLock),
|
||||||
|
requestedLocks(QCamera::NoLock),
|
||||||
|
lockStatus(QCamera::Unlocked),
|
||||||
|
lockChangeReason(QCamera::UserRequest),
|
||||||
|
supressLockChangedSignal(false),
|
||||||
|
restartPending(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void initControls();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
QMediaServiceProvider *provider;
|
||||||
|
|
||||||
|
QCameraControl *control;
|
||||||
|
QVideoDeviceSelectorControl *deviceControl;
|
||||||
|
QCameraLocksControl *locksControl;
|
||||||
|
QCameraInfoControl *infoControl;
|
||||||
|
|
||||||
|
QCameraExposure *cameraExposure;
|
||||||
|
QCameraFocus *cameraFocus;
|
||||||
|
QCameraImageProcessing *imageProcessing;
|
||||||
|
|
||||||
|
QObject *viewfinder;
|
||||||
|
QObject *capture;
|
||||||
|
|
||||||
|
QCamera::State state;
|
||||||
|
|
||||||
|
QCamera::Error error;
|
||||||
|
QString errorString;
|
||||||
|
|
||||||
|
QCamera::LockTypes supportedLocks;
|
||||||
|
QCamera::LockTypes requestedLocks;
|
||||||
|
|
||||||
|
QCamera::LockStatus lockStatus;
|
||||||
|
QCamera::LockChangeReason lockChangeReason;
|
||||||
|
bool supressLockChangedSignal;
|
||||||
|
|
||||||
|
bool restartPending;
|
||||||
|
|
||||||
|
QVideoSurfaceOutput surfaceViewfinder;
|
||||||
|
|
||||||
|
void _q_error(int error, const QString &errorString);
|
||||||
|
void unsetError() { error = QCamera::NoError; errorString.clear(); }
|
||||||
|
|
||||||
|
void setState(QCamera::State);
|
||||||
|
|
||||||
|
void _q_updateLockStatus(QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason);
|
||||||
|
void _q_updateState(QCamera::State newState);
|
||||||
|
void _q_preparePropertyChange(int changeType);
|
||||||
|
void _q_restartCamera();
|
||||||
|
void updateLockStatus();
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCAMERA_P_H
|
||||||
@@ -159,6 +159,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QCamera;
|
friend class QCamera;
|
||||||
|
friend class QCameraPrivate;
|
||||||
explicit QCameraExposure(QCamera *parent = 0);
|
explicit QCameraExposure(QCamera *parent = 0);
|
||||||
virtual ~QCameraExposure();
|
virtual ~QCameraExposure();
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QCamera;
|
friend class QCamera;
|
||||||
|
friend class QCameraPrivate;
|
||||||
QCameraFocus(QCamera *camera);
|
QCameraFocus(QCamera *camera);
|
||||||
~QCameraFocus();
|
~QCameraFocus();
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QCamera;
|
friend class QCamera;
|
||||||
|
friend class QCameraPrivate;
|
||||||
QCameraImageProcessing(QCamera *camera);
|
QCameraImageProcessing(QCamera *camera);
|
||||||
~QCameraImageProcessing();
|
~QCameraImageProcessing();
|
||||||
|
|
||||||
|
|||||||
289
src/multimedia/camera/qcamerainfo.cpp
Normal file
289
src/multimedia/camera/qcamerainfo.cpp
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 "qcamerainfo.h"
|
||||||
|
|
||||||
|
#include "qcamera_p.h"
|
||||||
|
#include "qmediaserviceprovider_p.h"
|
||||||
|
|
||||||
|
#include <qvideodeviceselectorcontrol.h>
|
||||||
|
#include <qcamerainfocontrol.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QCameraInfo
|
||||||
|
\brief The QCameraInfo class provides general information about camera devices.
|
||||||
|
\since 5.3
|
||||||
|
\inmodule QtMultimedia
|
||||||
|
\ingroup multimedia
|
||||||
|
\ingroup multimedia_camera
|
||||||
|
|
||||||
|
QCameraInfo lets you query for camera devices that are currently available on the system.
|
||||||
|
|
||||||
|
The static functions defaultCamera() and availableCameras() provide you a list of all
|
||||||
|
available cameras.
|
||||||
|
|
||||||
|
This example prints the name of all available cameras:
|
||||||
|
|
||||||
|
\snippet multimedia-snippets/camera.cpp Camera listing
|
||||||
|
|
||||||
|
A QCameraInfo can be used to construct a QCamera. The following example instantiates a QCamera
|
||||||
|
whose camera device is named 'mycamera':
|
||||||
|
|
||||||
|
\snippet multimedia-snippets/camera.cpp Camera selection
|
||||||
|
|
||||||
|
You can also use QCameraInfo to get general information about a camera device such as
|
||||||
|
description, physical position on the system, or camera sensor orientation.
|
||||||
|
|
||||||
|
\snippet multimedia-snippets/camera.cpp Camera info
|
||||||
|
|
||||||
|
\sa QCamera
|
||||||
|
*/
|
||||||
|
|
||||||
|
class QCameraInfoPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QCameraInfoPrivate() : isNull(true), position(QCamera::UnspecifiedPosition), orientation(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool isNull;
|
||||||
|
QString deviceName;
|
||||||
|
QString description;
|
||||||
|
QCamera::Position position;
|
||||||
|
int orientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a camera info object for \a camera.
|
||||||
|
|
||||||
|
You can use it to query information about the \a camera object passed as argument.
|
||||||
|
|
||||||
|
If the \a camera is invalid, for example when no camera device is available on the system,
|
||||||
|
the QCameraInfo object will be invalid and isNull() will return true.
|
||||||
|
*/
|
||||||
|
QCameraInfo::QCameraInfo(const QCamera &camera)
|
||||||
|
: d(new QCameraInfoPrivate)
|
||||||
|
{
|
||||||
|
const QVideoDeviceSelectorControl *deviceControl = camera.d_func()->deviceControl;
|
||||||
|
if (deviceControl) {
|
||||||
|
const int selectedDevice = deviceControl->selectedDevice();
|
||||||
|
d->deviceName = deviceControl->deviceName(selectedDevice);
|
||||||
|
d->description = deviceControl->deviceDescription(selectedDevice);
|
||||||
|
d->isNull = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QCameraInfoControl *infoControl = camera.d_func()->infoControl;
|
||||||
|
if (infoControl) {
|
||||||
|
d->position = infoControl->cameraPosition(d->deviceName);
|
||||||
|
d->orientation = infoControl->cameraOrientation(d->deviceName);
|
||||||
|
d->isNull = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a camera info object from a camera device \a name.
|
||||||
|
|
||||||
|
If no such device exists, the QCameraInfo object will be invalid and isNull() will return true.
|
||||||
|
*/
|
||||||
|
QCameraInfo::QCameraInfo(const QByteArray &name)
|
||||||
|
: d(new QCameraInfoPrivate)
|
||||||
|
{
|
||||||
|
if (!name.isNull()) {
|
||||||
|
QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider();
|
||||||
|
const QByteArray service(Q_MEDIASERVICE_CAMERA);
|
||||||
|
if (provider->devices(service).contains(name)) {
|
||||||
|
d->deviceName = QString::fromLatin1(name);
|
||||||
|
d->description = provider->deviceDescription(service, name);
|
||||||
|
d->position = provider->cameraPosition(name);
|
||||||
|
d->orientation = provider->cameraOrientation(name);
|
||||||
|
d->isNull = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a copy of \a other.
|
||||||
|
*/
|
||||||
|
QCameraInfo::QCameraInfo(const QCameraInfo &other)
|
||||||
|
: d(other.d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys the QCameraInfo.
|
||||||
|
*/
|
||||||
|
QCameraInfo::~QCameraInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if this QCameraInfo is equal to \a other.
|
||||||
|
*/
|
||||||
|
bool QCameraInfo::operator==(const QCameraInfo &other) const
|
||||||
|
{
|
||||||
|
if (d == other.d)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return (d->deviceName == other.d->deviceName
|
||||||
|
&& d->description == other.d->description
|
||||||
|
&& d->position == other.d->position
|
||||||
|
&& d->orientation == other.d->orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if this QCameraInfo is null or invalid.
|
||||||
|
*/
|
||||||
|
bool QCameraInfo::isNull() const
|
||||||
|
{
|
||||||
|
return d->isNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the device name of the camera
|
||||||
|
|
||||||
|
This is a unique ID to identify the camera and may not be human-readable.
|
||||||
|
*/
|
||||||
|
QString QCameraInfo::deviceName() const
|
||||||
|
{
|
||||||
|
return d->deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the human-readable description of the camera.
|
||||||
|
*/
|
||||||
|
QString QCameraInfo::description() const
|
||||||
|
{
|
||||||
|
return d->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the physical position of the camera on the hardware system.
|
||||||
|
*/
|
||||||
|
QCamera::Position QCameraInfo::position() const
|
||||||
|
{
|
||||||
|
return d->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the physical orientation of the camera sensor.
|
||||||
|
|
||||||
|
The value is the orientation angle (clockwise, in steps of 90 degrees) of the camera sensor
|
||||||
|
in relation to the display in its natural orientation.
|
||||||
|
|
||||||
|
You can show the camera image in the correct orientation by rotating it by this value in the
|
||||||
|
anti-clockwise direction.
|
||||||
|
|
||||||
|
For example, suppose a mobile device which is naturally in portrait orientation. The back-facing
|
||||||
|
camera is mounted in landscape. If the top side of the camera sensor is aligned with the
|
||||||
|
right edge of the screen in natural orientation, the value should be 270. If the top side of a
|
||||||
|
front-facing camera sensor is aligned with the right of the screen, the value should be 90.
|
||||||
|
*/
|
||||||
|
int QCameraInfo::orientation() const
|
||||||
|
{
|
||||||
|
return d->orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the default camera on the system.
|
||||||
|
|
||||||
|
The returned object should be checked using isNull() before being used, in case there is no
|
||||||
|
default camera or no cameras at all.
|
||||||
|
|
||||||
|
\sa availableCameras()
|
||||||
|
*/
|
||||||
|
QCameraInfo QCameraInfo::defaultCamera()
|
||||||
|
{
|
||||||
|
return QCameraInfo(QMediaServiceProvider::defaultServiceProvider()->defaultDevice(Q_MEDIASERVICE_CAMERA));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a list of available cameras on the system which are located at \a position.
|
||||||
|
|
||||||
|
If \a position is not specified or if the value is QCamera::UnspecifiedPosition, a list of
|
||||||
|
all available cameras will be returned.
|
||||||
|
*/
|
||||||
|
QList<QCameraInfo> QCameraInfo::availableCameras(QCamera::Position position)
|
||||||
|
{
|
||||||
|
QList<QCameraInfo> cameras;
|
||||||
|
|
||||||
|
const QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider();
|
||||||
|
const QByteArray service(Q_MEDIASERVICE_CAMERA);
|
||||||
|
const QList<QByteArray> devices = provider->devices(service);
|
||||||
|
for (int i = 0; i < devices.count(); ++i) {
|
||||||
|
const QByteArray &name = devices.at(i);
|
||||||
|
if (position == QCamera::UnspecifiedPosition
|
||||||
|
|| position == provider->cameraPosition(name)) {
|
||||||
|
cameras.append(QCameraInfo(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cameras;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the QCameraInfo object to be equal to \a other.
|
||||||
|
*/
|
||||||
|
QCameraInfo& QCameraInfo::operator=(const QCameraInfo& other)
|
||||||
|
{
|
||||||
|
d = other.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QCameraInfo::operator!=(const QCameraInfo &other) const
|
||||||
|
|
||||||
|
Returns true if this QCameraInfo is different from \a other.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug operator<<(QDebug d, const QCameraInfo &camera)
|
||||||
|
{
|
||||||
|
d.maybeSpace() << QStringLiteral("QCameraInfo(deviceName=%1, position=%2, orientation=%3)")
|
||||||
|
.arg(camera.deviceName())
|
||||||
|
.arg(QString::fromLatin1(QCamera::staticMetaObject.enumerator(QCamera::staticMetaObject.indexOfEnumerator("Position"))
|
||||||
|
.valueToKey(camera.position())))
|
||||||
|
.arg(camera.orientation());
|
||||||
|
return d.space();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
86
src/multimedia/camera/qcamerainfo.h
Normal file
86
src/multimedia/camera/qcamerainfo.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 QCAMERAINFO_H
|
||||||
|
#define QCAMERAINFO_H
|
||||||
|
|
||||||
|
#include <QtMultimedia/qcamera.h>
|
||||||
|
#include <QtCore/qsharedpointer.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QCameraInfoPrivate;
|
||||||
|
|
||||||
|
class Q_MULTIMEDIA_EXPORT QCameraInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit QCameraInfo(const QByteArray &name = QByteArray());
|
||||||
|
explicit QCameraInfo(const QCamera &camera);
|
||||||
|
QCameraInfo(const QCameraInfo& other);
|
||||||
|
~QCameraInfo();
|
||||||
|
|
||||||
|
QCameraInfo& operator=(const QCameraInfo& other);
|
||||||
|
bool operator==(const QCameraInfo &other) const;
|
||||||
|
inline bool operator!=(const QCameraInfo &other) const;
|
||||||
|
|
||||||
|
bool isNull() const;
|
||||||
|
|
||||||
|
QString deviceName() const;
|
||||||
|
QString description() const;
|
||||||
|
QCamera::Position position() const;
|
||||||
|
int orientation() const;
|
||||||
|
|
||||||
|
static QCameraInfo defaultCamera();
|
||||||
|
static QList<QCameraInfo> availableCameras(QCamera::Position position = QCamera::UnspecifiedPosition);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<QCameraInfoPrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool QCameraInfo::operator!=(const QCameraInfo &other) const { return !operator==(other); }
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QCameraInfo&);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCAMERAINFO_H
|
||||||
@@ -9,6 +9,7 @@ PUBLIC_HEADERS += \
|
|||||||
controls/qcameracapturebufferformatcontrol.h \
|
controls/qcameracapturebufferformatcontrol.h \
|
||||||
controls/qcameracapturedestinationcontrol.h \
|
controls/qcameracapturedestinationcontrol.h \
|
||||||
controls/qcameracontrol.h \
|
controls/qcameracontrol.h \
|
||||||
|
controls/qcamerainfocontrol.h \
|
||||||
controls/qcameraexposurecontrol.h \
|
controls/qcameraexposurecontrol.h \
|
||||||
controls/qcamerafeedbackcontrol.h \
|
controls/qcamerafeedbackcontrol.h \
|
||||||
controls/qcameraflashcontrol.h \
|
controls/qcameraflashcontrol.h \
|
||||||
@@ -45,6 +46,7 @@ SOURCES += \
|
|||||||
controls/qcameracapturebufferformatcontrol.cpp \
|
controls/qcameracapturebufferformatcontrol.cpp \
|
||||||
controls/qcameracapturedestinationcontrol.cpp \
|
controls/qcameracapturedestinationcontrol.cpp \
|
||||||
controls/qcameracontrol.cpp \
|
controls/qcameracontrol.cpp \
|
||||||
|
controls/qcamerainfocontrol.cpp \
|
||||||
controls/qcameraexposurecontrol.cpp \
|
controls/qcameraexposurecontrol.cpp \
|
||||||
controls/qcamerafeedbackcontrol.cpp \
|
controls/qcamerafeedbackcontrol.cpp \
|
||||||
controls/qcameraflashcontrol.cpp \
|
controls/qcameraflashcontrol.cpp \
|
||||||
@@ -79,4 +81,3 @@ SOURCES += \
|
|||||||
controls/qaudiooutputselectorcontrol.cpp \
|
controls/qaudiooutputselectorcontrol.cpp \
|
||||||
controls/qvideodeviceselectorcontrol.cpp
|
controls/qvideodeviceselectorcontrol.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
104
src/multimedia/controls/qcamerainfocontrol.cpp
Normal file
104
src/multimedia/controls/qcamerainfocontrol.cpp
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 "qcamerainfocontrol.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QCameraInfoControl
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
\brief The QCameraInfoControl class provides a camera info media control.
|
||||||
|
\inmodule QtMultimedia
|
||||||
|
|
||||||
|
\ingroup multimedia_control
|
||||||
|
|
||||||
|
The QCameraInfoControl class provides information about the camera devices
|
||||||
|
available on the system.
|
||||||
|
|
||||||
|
The interface name of QCameraInfoControl is \c org.qt-project.qt.camerainfocontrol/5.3 as
|
||||||
|
defined in QCameraInfoControl_iid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\macro QCameraInfoControl_iid
|
||||||
|
|
||||||
|
\c org.qt-project.qt.camerainfocontrol/5.3
|
||||||
|
|
||||||
|
Defines the interface name of the QCameraInfoControl class.
|
||||||
|
|
||||||
|
\relates QVideoDeviceSelectorControl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a camera info control with the given \a parent.
|
||||||
|
*/
|
||||||
|
QCameraInfoControl::QCameraInfoControl(QObject *parent)
|
||||||
|
: QMediaControl(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys a camera info control.
|
||||||
|
*/
|
||||||
|
QCameraInfoControl::~QCameraInfoControl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QCameraInfoControl::cameraPosition(const QString &deviceName) const
|
||||||
|
|
||||||
|
Returns the physical position of the camera named \a deviceName on the hardware system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QCameraInfoControl::cameraOrientation(const QString &deviceName) const
|
||||||
|
|
||||||
|
Returns the physical orientation of the sensor for the camera named \a deviceName.
|
||||||
|
|
||||||
|
The value is the orientation angle (clockwise, in steps of 90 degrees) of the camera sensor
|
||||||
|
in relation to the display in its natural orientation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "moc_qcamerainfocontrol.cpp"
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
71
src/multimedia/controls/qcamerainfocontrol.h
Normal file
71
src/multimedia/controls/qcamerainfocontrol.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 QCAMERAINFOCONTROL_H
|
||||||
|
#define QCAMERAINFOCONTROL_H
|
||||||
|
|
||||||
|
#include <QtMultimedia/qcamera.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
// Required for QDoc workaround
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
class Q_MULTIMEDIA_EXPORT QCameraInfoControl : public QMediaControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~QCameraInfoControl();
|
||||||
|
|
||||||
|
virtual QCamera::Position cameraPosition(const QString &deviceName) const = 0;
|
||||||
|
virtual int cameraOrientation(const QString &deviceName) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QCameraInfoControl(QObject *parent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QCameraInfoControl_iid "org.qt-project.qt.camerainfocontrol/5.3"
|
||||||
|
Q_MEDIA_DECLARE_CONTROL(QCameraInfoControl, QCameraInfoControl_iid)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCAMERAINFOCONTROL_H
|
||||||
@@ -42,11 +42,15 @@
|
|||||||
/* Camera snippets */
|
/* Camera snippets */
|
||||||
|
|
||||||
#include "qcamera.h"
|
#include "qcamera.h"
|
||||||
|
#include "qcamerainfo.h"
|
||||||
#include "qcameraviewfinder.h"
|
#include "qcameraviewfinder.h"
|
||||||
#include "qmediarecorder.h"
|
#include "qmediarecorder.h"
|
||||||
#include "qcameraimagecapture.h"
|
#include "qcameraimagecapture.h"
|
||||||
#include "qcameraimageprocessing.h"
|
#include "qcameraimageprocessing.h"
|
||||||
#include "qabstractvideosurface.h"
|
#include "qabstractvideosurface.h"
|
||||||
|
#include <QtGui/qscreen.h>
|
||||||
|
#include <QtGui/qguiapplication.h>
|
||||||
|
#include <QtGui/qimage.h>
|
||||||
|
|
||||||
/* Globals so that everything is consistent. */
|
/* Globals so that everything is consistent. */
|
||||||
QCamera *camera = 0;
|
QCamera *camera = 0;
|
||||||
@@ -94,6 +98,32 @@ void overview_surface()
|
|||||||
//! [Camera overview surface]
|
//! [Camera overview surface]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void overview_viewfinder_orientation()
|
||||||
|
{
|
||||||
|
QCamera camera;
|
||||||
|
|
||||||
|
//! [Camera overview viewfinder orientation]
|
||||||
|
// Assuming a QImage has been created from the QVideoFrame that needs to be presented
|
||||||
|
QImage videoFrame;
|
||||||
|
QCameraInfo cameraInfo(camera); // needed to get the camera sensor position and orientation
|
||||||
|
|
||||||
|
// Get the current display orientation
|
||||||
|
const QScreen *screen = QGuiApplication::primaryScreen();
|
||||||
|
const int screenAngle = screen->angleBetween(screen->nativeOrientation(), screen->orientation());
|
||||||
|
|
||||||
|
int rotation;
|
||||||
|
if (cameraInfo.position() == QCamera::BackFace) {
|
||||||
|
rotation = (cameraInfo.orientation() - screenAngle) % 360;
|
||||||
|
} else {
|
||||||
|
// Front position, compensate the mirror
|
||||||
|
rotation = (360 - cameraInfo.orientation() + screenAngle) % 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate the frame so it always shows in the correct orientation
|
||||||
|
videoFrame = videoFrame.transformed(QTransform().rotate(rotation));
|
||||||
|
//! [Camera overview viewfinder orientation]
|
||||||
|
}
|
||||||
|
|
||||||
void overview_still()
|
void overview_still()
|
||||||
{
|
{
|
||||||
//! [Camera overview capture]
|
//! [Camera overview capture]
|
||||||
@@ -130,6 +160,41 @@ void overview_movie()
|
|||||||
//! [Camera overview movie]
|
//! [Camera overview movie]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void camera_listing()
|
||||||
|
{
|
||||||
|
//! [Camera listing]
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
foreach (const QCameraInfo &cameraInfo, cameras)
|
||||||
|
qDebug() << cameraInfo.deviceName();
|
||||||
|
//! [Camera listing]
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_selection()
|
||||||
|
{
|
||||||
|
//! [Camera selection]
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
foreach (const QCameraInfo &cameraInfo, cameras) {
|
||||||
|
if (cameraInfo.deviceName() == "mycamera")
|
||||||
|
camera = new QCamera(cameraInfo);
|
||||||
|
}
|
||||||
|
//! [Camera selection]
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_info()
|
||||||
|
{
|
||||||
|
//! [Camera info]
|
||||||
|
QCamera myCamera;
|
||||||
|
QCameraInfo cameraInfo(myCamera);
|
||||||
|
|
||||||
|
if (cameraInfo.position() == QCamera::FrontFace)
|
||||||
|
qDebug() << "The camera is on the front face of the hardware system.";
|
||||||
|
else if (cameraInfo.position() == QCamera::BackFace)
|
||||||
|
qDebug() << "The camera is on the back face of the hardware system.";
|
||||||
|
|
||||||
|
qDebug() << "The camera sensor orientation is " << cameraInfo.orientation() << " degrees.";
|
||||||
|
//! [Camera info]
|
||||||
|
}
|
||||||
|
|
||||||
void camera_blah()
|
void camera_blah()
|
||||||
{
|
{
|
||||||
//! [Camera]
|
//! [Camera]
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ VideoOutput {
|
|||||||
\endqml
|
\endqml
|
||||||
|
|
||||||
In C++, your choice depends on whether you are using widgets, or QGraphicsView.
|
In C++, your choice depends on whether you are using widgets, or QGraphicsView.
|
||||||
The \l QVideoWidget class is used in the widgets case, and \l QGraphicsVideoItem
|
The \l QCameraViewfinder class is used in the widgets case, and \l QGraphicsVideoItem
|
||||||
is useful for QGraphicsView.
|
is useful for QGraphicsView.
|
||||||
|
|
||||||
\snippet multimedia-snippets/camera.cpp Camera overview viewfinder
|
\snippet multimedia-snippets/camera.cpp Camera overview viewfinder
|
||||||
@@ -130,6 +130,15 @@ need to render the viewfinder image yourself.
|
|||||||
|
|
||||||
\snippet multimedia-snippets/camera.cpp Camera overview surface
|
\snippet multimedia-snippets/camera.cpp Camera overview surface
|
||||||
|
|
||||||
|
On mobile devices, the viewfinder image might not always be in the orientation you would expect.
|
||||||
|
The camera sensors on these devices are often mounted in landscape while the natural
|
||||||
|
orientation of the screen is portrait. This results in the image appearing sideways or inverted
|
||||||
|
depending on the device orientation. In order to reflect on screen what the user actually sees, you
|
||||||
|
should make sure the viewfinder frames are always rotated to the correct orientation, taking into
|
||||||
|
account the camera sensor orientation and the current display orientation.
|
||||||
|
|
||||||
|
\snippet multimedia-snippets/camera.cpp Camera overview viewfinder orientation
|
||||||
|
|
||||||
\section2 Still Images
|
\section2 Still Images
|
||||||
|
|
||||||
After setting up a viewfinder and finding something photogenic,
|
After setting up a viewfinder and finding something photogenic,
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class QMediaServiceProviderHintPrivate : public QSharedData
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
|
QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
|
||||||
:type(type), features(0)
|
:type(type), cameraPosition(QCamera::UnspecifiedPosition), features(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +66,7 @@ public:
|
|||||||
:QSharedData(other),
|
:QSharedData(other),
|
||||||
type(other.type),
|
type(other.type),
|
||||||
device(other.device),
|
device(other.device),
|
||||||
|
cameraPosition(other.cameraPosition),
|
||||||
mimeType(other.mimeType),
|
mimeType(other.mimeType),
|
||||||
codecs(other.codecs),
|
codecs(other.codecs),
|
||||||
features(other.features)
|
features(other.features)
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
|
|
||||||
QMediaServiceProviderHint::Type type;
|
QMediaServiceProviderHint::Type type;
|
||||||
QByteArray device;
|
QByteArray device;
|
||||||
|
QCamera::Position cameraPosition;
|
||||||
QString mimeType;
|
QString mimeType;
|
||||||
QStringList codecs;
|
QStringList codecs;
|
||||||
QMediaServiceProviderHint::Features features;
|
QMediaServiceProviderHint::Features features;
|
||||||
@@ -129,6 +131,7 @@ public:
|
|||||||
\value ContentType Select media service most suitable for certain content type.
|
\value ContentType Select media service most suitable for certain content type.
|
||||||
\value Device Select media service which supports certain device.
|
\value Device Select media service which supports certain device.
|
||||||
\value SupportedFeatures Select media service supporting the set of optional features.
|
\value SupportedFeatures Select media service supporting the set of optional features.
|
||||||
|
\value CameraPosition Select media service having a camera at a specified position.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -164,6 +167,19 @@ QMediaServiceProviderHint::QMediaServiceProviderHint(const QByteArray &device)
|
|||||||
d->device = device;
|
d->device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Constructs a CameraPosition media service provider hint.
|
||||||
|
|
||||||
|
This type of hint describes a media service that has a camera in the specific \a position.
|
||||||
|
*/
|
||||||
|
QMediaServiceProviderHint::QMediaServiceProviderHint(QCamera::Position position)
|
||||||
|
:d(new QMediaServiceProviderHintPrivate(CameraPosition))
|
||||||
|
{
|
||||||
|
d->cameraPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a SupportedFeatures media service provider hint.
|
Constructs a SupportedFeatures media service provider hint.
|
||||||
|
|
||||||
@@ -209,6 +225,7 @@ bool QMediaServiceProviderHint::operator == (const QMediaServiceProviderHint &ot
|
|||||||
return (d == other.d) ||
|
return (d == other.d) ||
|
||||||
(d->type == other.d->type &&
|
(d->type == other.d->type &&
|
||||||
d->device == other.d->device &&
|
d->device == other.d->device &&
|
||||||
|
d->cameraPosition == other.d->cameraPosition &&
|
||||||
d->mimeType == other.d->mimeType &&
|
d->mimeType == other.d->mimeType &&
|
||||||
d->codecs == other.d->codecs &&
|
d->codecs == other.d->codecs &&
|
||||||
d->features == other.d->features);
|
d->features == other.d->features);
|
||||||
@@ -264,6 +281,17 @@ QByteArray QMediaServiceProviderHint::device() const
|
|||||||
return d->device;
|
return d->device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Returns the camera's position a media service is expected to utilize.
|
||||||
|
*/
|
||||||
|
QCamera::Position QMediaServiceProviderHint::cameraPosition() const
|
||||||
|
{
|
||||||
|
return d->cameraPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a set of features a media service is expected to provide.
|
Returns a set of features a media service is expected to provide.
|
||||||
*/
|
*/
|
||||||
@@ -349,6 +377,29 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case QMediaServiceProviderHint::CameraPosition: {
|
||||||
|
plugin = plugins[0];
|
||||||
|
if (type == QByteArray(Q_MEDIASERVICE_CAMERA)
|
||||||
|
&& hint.cameraPosition() != QCamera::UnspecifiedPosition) {
|
||||||
|
foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
|
||||||
|
const QMediaServiceSupportedDevicesInterface *deviceIface =
|
||||||
|
qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin);
|
||||||
|
const QMediaServiceCameraInfoInterface *cameraIface =
|
||||||
|
qobject_cast<QMediaServiceCameraInfoInterface*>(currentPlugin);
|
||||||
|
|
||||||
|
if (deviceIface && cameraIface) {
|
||||||
|
const QList<QByteArray> cameras = deviceIface->devices(type);
|
||||||
|
foreach (const QByteArray &camera, cameras) {
|
||||||
|
if (cameraIface->cameraPosition(camera) == hint.cameraPosition()) {
|
||||||
|
plugin = currentPlugin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case QMediaServiceProviderHint::ContentType: {
|
case QMediaServiceProviderHint::ContentType: {
|
||||||
QMultimedia::SupportEstimate estimate = QMultimedia::NotSupported;
|
QMultimedia::SupportEstimate estimate = QMultimedia::NotSupported;
|
||||||
foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
|
foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) {
|
||||||
@@ -496,6 +547,25 @@ public:
|
|||||||
return supportedTypes;
|
return supportedTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &serviceType) const
|
||||||
|
{
|
||||||
|
foreach (QObject *obj, loader()->instances(QLatin1String(serviceType))) {
|
||||||
|
const QMediaServiceDefaultDeviceInterface *iface =
|
||||||
|
qobject_cast<QMediaServiceDefaultDeviceInterface*>(obj);
|
||||||
|
|
||||||
|
if (iface)
|
||||||
|
return iface->defaultDevice(serviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if QMediaServiceDefaultDeviceInterface is not implemented, return the
|
||||||
|
// first available device.
|
||||||
|
QList<QByteArray> devs = devices(serviceType);
|
||||||
|
if (!devs.isEmpty())
|
||||||
|
return devs.first();
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> devices(const QByteArray &serviceType) const
|
QList<QByteArray> devices(const QByteArray &serviceType) const
|
||||||
{
|
{
|
||||||
QList<QByteArray> res;
|
QList<QByteArray> res;
|
||||||
@@ -526,6 +596,44 @@ public:
|
|||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCamera::Position cameraPosition(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
const QByteArray serviceType(Q_MEDIASERVICE_CAMERA);
|
||||||
|
foreach (QObject *obj, loader()->instances(QString::fromLatin1(serviceType))) {
|
||||||
|
const QMediaServiceSupportedDevicesInterface *deviceIface =
|
||||||
|
qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
|
||||||
|
const QMediaServiceCameraInfoInterface *cameraIface =
|
||||||
|
qobject_cast<QMediaServiceCameraInfoInterface*>(obj);
|
||||||
|
|
||||||
|
if (cameraIface) {
|
||||||
|
if (deviceIface && !deviceIface->devices(serviceType).contains(device))
|
||||||
|
continue;
|
||||||
|
return cameraIface->cameraPosition(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QCamera::UnspecifiedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cameraOrientation(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
const QByteArray serviceType(Q_MEDIASERVICE_CAMERA);
|
||||||
|
foreach (QObject *obj, loader()->instances(QString::fromLatin1(serviceType))) {
|
||||||
|
const QMediaServiceSupportedDevicesInterface *deviceIface =
|
||||||
|
qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
|
||||||
|
const QMediaServiceCameraInfoInterface *cameraIface =
|
||||||
|
qobject_cast<QMediaServiceCameraInfoInterface*>(obj);
|
||||||
|
|
||||||
|
if (cameraIface) {
|
||||||
|
if (deviceIface && !deviceIface->devices(serviceType).contains(device))
|
||||||
|
continue;
|
||||||
|
return cameraIface->cameraOrientation(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider);
|
Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider);
|
||||||
@@ -598,6 +706,17 @@ QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceT
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Returns the default device for a \a service type.
|
||||||
|
*/
|
||||||
|
QByteArray QMediaServiceProvider::defaultDevice(const QByteArray &serviceType) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(serviceType);
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the list of devices related to \a service type.
|
Returns the list of devices related to \a service type.
|
||||||
*/
|
*/
|
||||||
@@ -618,6 +737,30 @@ QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType,
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Returns the physical position of a camera \a device on the system hardware.
|
||||||
|
*/
|
||||||
|
QCamera::Position QMediaServiceProvider::cameraPosition(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(device);
|
||||||
|
return QCamera::UnspecifiedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
Returns the physical orientation of the camera \a device. The value is the angle by which the
|
||||||
|
camera image should be rotated anti-clockwise (in steps of 90 degrees) so it shows correctly on
|
||||||
|
the display in its natural orientation.
|
||||||
|
*/
|
||||||
|
int QMediaServiceProvider::cameraOrientation(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static QMediaServiceProvider *qt_defaultMediaServiceProvider = 0;
|
static QMediaServiceProvider *qt_defaultMediaServiceProvider = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -712,16 +855,47 @@ QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider()
|
|||||||
Destroys a media service supported devices interface.
|
Destroys a media service supported devices interface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.3
|
||||||
|
|
||||||
|
\fn QMediaServiceSupportedDevicesInterface::defaultDevice(const QByteArray &service) const
|
||||||
|
|
||||||
|
Returns the default device for a \a service type.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const
|
\fn QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const
|
||||||
|
|
||||||
Returns a list of devices supported by a plug-in \a service.
|
Returns a list of devices available for a \a service type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device)
|
\fn QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||||
|
|
||||||
Returns a description of a \a device supported by a plug-in \a service.
|
Returns the description of a \a device available for a \a service type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QMediaServiceCameraInfoInterface
|
||||||
|
\inmodule QtMultimedia
|
||||||
|
\since 5.3
|
||||||
|
\brief The QMediaServiceCameraInfoInterface class interface
|
||||||
|
provides camera-specific information about devices supported by a camera service plug-in.
|
||||||
|
|
||||||
|
A QMediaServiceProviderPlugin may implement this interface, in that case it also needs to
|
||||||
|
implement the QMediaServiceSupportedDevicesInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QMediaServiceCameraInfoInterface::cameraPosition(const QByteArray &device) const
|
||||||
|
|
||||||
|
Returns the physical position of a camera \a device supported by a camera service plug-in.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QMediaServiceCameraInfoInterface::cameraOrientation(const QByteArray &device) const
|
||||||
|
|
||||||
|
Returns the physical orientation of a camera \a device supported by a camera service plug-in.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -67,9 +67,13 @@ public:
|
|||||||
int flags = 0) const;
|
int flags = 0) const;
|
||||||
virtual QStringList supportedMimeTypes(const QByteArray &serviceType, int flags = 0) const;
|
virtual QStringList supportedMimeTypes(const QByteArray &serviceType, int flags = 0) const;
|
||||||
|
|
||||||
|
virtual QByteArray defaultDevice(const QByteArray &serviceType) const;
|
||||||
virtual QList<QByteArray> devices(const QByteArray &serviceType) const;
|
virtual QList<QByteArray> devices(const QByteArray &serviceType) const;
|
||||||
virtual QString deviceDescription(const QByteArray &serviceType, const QByteArray &device);
|
virtual QString deviceDescription(const QByteArray &serviceType, const QByteArray &device);
|
||||||
|
|
||||||
|
virtual QCamera::Position cameraPosition(const QByteArray &device) const;
|
||||||
|
virtual int cameraOrientation(const QByteArray &device) const;
|
||||||
|
|
||||||
static QMediaServiceProvider* defaultServiceProvider();
|
static QMediaServiceProvider* defaultServiceProvider();
|
||||||
static void setDefaultServiceProvider(QMediaServiceProvider *provider);
|
static void setDefaultServiceProvider(QMediaServiceProvider *provider);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include <QtCore/qplugin.h>
|
#include <QtCore/qplugin.h>
|
||||||
#include <QtMultimedia/qmultimedia.h>
|
#include <QtMultimedia/qmultimedia.h>
|
||||||
#include <QtMultimedia/qtmultimediadefs.h>
|
#include <QtMultimedia/qtmultimediadefs.h>
|
||||||
|
#include <QtMultimedia/qcamera.h>
|
||||||
|
|
||||||
#ifdef Q_MOC_RUN
|
#ifdef Q_MOC_RUN
|
||||||
# pragma Q_MOC_EXPAND_MACROS
|
# pragma Q_MOC_EXPAND_MACROS
|
||||||
@@ -62,7 +63,7 @@ class QMediaServiceProviderHintPrivate;
|
|||||||
class Q_MULTIMEDIA_EXPORT QMediaServiceProviderHint
|
class Q_MULTIMEDIA_EXPORT QMediaServiceProviderHint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type { Null, ContentType, Device, SupportedFeatures };
|
enum Type { Null, ContentType, Device, SupportedFeatures, CameraPosition };
|
||||||
|
|
||||||
enum Feature {
|
enum Feature {
|
||||||
LowLatencyPlayback = 0x01,
|
LowLatencyPlayback = 0x01,
|
||||||
@@ -75,6 +76,7 @@ public:
|
|||||||
QMediaServiceProviderHint();
|
QMediaServiceProviderHint();
|
||||||
QMediaServiceProviderHint(const QString &mimeType, const QStringList& codecs);
|
QMediaServiceProviderHint(const QString &mimeType, const QStringList& codecs);
|
||||||
QMediaServiceProviderHint(const QByteArray &device);
|
QMediaServiceProviderHint(const QByteArray &device);
|
||||||
|
QMediaServiceProviderHint(QCamera::Position position);
|
||||||
QMediaServiceProviderHint(Features features);
|
QMediaServiceProviderHint(Features features);
|
||||||
QMediaServiceProviderHint(const QMediaServiceProviderHint &other);
|
QMediaServiceProviderHint(const QMediaServiceProviderHint &other);
|
||||||
~QMediaServiceProviderHint();
|
~QMediaServiceProviderHint();
|
||||||
@@ -92,6 +94,7 @@ public:
|
|||||||
QStringList codecs() const;
|
QStringList codecs() const;
|
||||||
|
|
||||||
QByteArray device() const;
|
QByteArray device() const;
|
||||||
|
QCamera::Position cameraPosition() const;
|
||||||
|
|
||||||
Features features() const;
|
Features features() const;
|
||||||
|
|
||||||
@@ -145,6 +148,32 @@ struct Q_MULTIMEDIA_EXPORT QMediaServiceSupportedDevicesInterface
|
|||||||
"org.qt-project.qt.mediaservicesupporteddevices/5.0"
|
"org.qt-project.qt.mediaservicesupporteddevices/5.0"
|
||||||
Q_DECLARE_INTERFACE(QMediaServiceSupportedDevicesInterface, QMediaServiceSupportedDevicesInterface_iid)
|
Q_DECLARE_INTERFACE(QMediaServiceSupportedDevicesInterface, QMediaServiceSupportedDevicesInterface_iid)
|
||||||
|
|
||||||
|
// This should be part of QMediaServiceSupportedDevicesInterface but it can't in order
|
||||||
|
// to preserve binary compatibility with 5.2 and earlier.
|
||||||
|
// The whole media service plugin API shouldn't even be public in the first place. It should
|
||||||
|
// be made private in Qt 6.0 and QMediaServiceDefaultDeviceInterface should be merged with
|
||||||
|
// QMediaServiceSupportedDevicesInterface
|
||||||
|
struct Q_MULTIMEDIA_EXPORT QMediaServiceDefaultDeviceInterface
|
||||||
|
{
|
||||||
|
virtual ~QMediaServiceDefaultDeviceInterface() {}
|
||||||
|
virtual QByteArray defaultDevice(const QByteArray &service) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QMediaServiceDefaultDeviceInterface_iid \
|
||||||
|
"org.qt-project.qt.mediaservicedefaultdevice/5.3"
|
||||||
|
Q_DECLARE_INTERFACE(QMediaServiceDefaultDeviceInterface, QMediaServiceDefaultDeviceInterface_iid)
|
||||||
|
|
||||||
|
struct Q_MULTIMEDIA_EXPORT QMediaServiceCameraInfoInterface
|
||||||
|
{
|
||||||
|
virtual ~QMediaServiceCameraInfoInterface() {}
|
||||||
|
virtual QCamera::Position cameraPosition(const QByteArray &device) const = 0;
|
||||||
|
virtual int cameraOrientation(const QByteArray &device) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QMediaServiceCameraInfoInterface_iid \
|
||||||
|
"org.qt-project.qt.mediaservicecamerainfo/5.3"
|
||||||
|
Q_DECLARE_INTERFACE(QMediaServiceCameraInfoInterface, QMediaServiceCameraInfoInterface_iid)
|
||||||
|
|
||||||
// Required for QDoc workaround
|
// Required for QDoc workaround
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include <QtCore/qsharedpointer.h>
|
#include <QtCore/qsharedpointer.h>
|
||||||
#include <QtQuick/qquickitem.h>
|
#include <QtQuick/qquickitem.h>
|
||||||
#include <QtCore/qpointer.h>
|
#include <QtCore/qpointer.h>
|
||||||
|
#include <QtMultimedia/qcamerainfo.h>
|
||||||
|
|
||||||
#include <private/qtmultimediaquickdefs_p.h>
|
#include <private/qtmultimediaquickdefs_p.h>
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ private:
|
|||||||
QPointer<QObject> m_source;
|
QPointer<QObject> m_source;
|
||||||
QPointer<QMediaObject> m_mediaObject;
|
QPointer<QMediaObject> m_mediaObject;
|
||||||
QPointer<QMediaService> m_service;
|
QPointer<QMediaService> m_service;
|
||||||
|
QCameraInfo m_cameraInfo;
|
||||||
|
|
||||||
FillMode m_fillMode;
|
FillMode m_fillMode;
|
||||||
QSize m_nativeSize;
|
QSize m_nativeSize;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void QVideoOutputOrientationHandler::screenOrientationChanged(Qt::ScreenOrientat
|
|||||||
const QScreen *screen = QGuiApplication::primaryScreen();
|
const QScreen *screen = QGuiApplication::primaryScreen();
|
||||||
const QPlatformScreen *platformScreen = screen->handle();
|
const QPlatformScreen *platformScreen = screen->handle();
|
||||||
|
|
||||||
const int angle = (360 - screen->angleBetween(platformScreen->nativeOrientation(), orientation));
|
const int angle = (360 - screen->angleBetween(platformScreen->nativeOrientation(), orientation)) % 360;
|
||||||
|
|
||||||
if (angle == m_currentOrientation)
|
if (angle == m_currentOrientation)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -247,6 +247,8 @@ public:
|
|||||||
|
|
||||||
bool isFormatSupported(const QVideoSurfaceFormat &format) const;
|
bool isFormatSupported(const QVideoSurfaceFormat &format) const;
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
|
QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
|
||||||
|
|
||||||
QAbstractVideoSurface::Error paint(
|
QAbstractVideoSurface::Error paint(
|
||||||
@@ -351,6 +353,12 @@ bool QVideoSurfaceGLPainter::isFormatSupported(const QVideoSurfaceFormat &format
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QVideoSurfaceGLPainter::stop()
|
||||||
|
{
|
||||||
|
m_frame = QVideoFrame();
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVideoFrame &frame)
|
QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVideoFrame &frame)
|
||||||
{
|
{
|
||||||
m_frame = frame;
|
m_frame = frame;
|
||||||
@@ -832,6 +840,8 @@ void QVideoSurfaceArbFpPainter::stop()
|
|||||||
m_textureCount = 0;
|
m_textureCount = 0;
|
||||||
m_programId = 0;
|
m_programId = 0;
|
||||||
m_handleType = QAbstractVideoBuffer::NoHandle;
|
m_handleType = QAbstractVideoBuffer::NoHandle;
|
||||||
|
|
||||||
|
QVideoSurfaceGLPainter::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
|
QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
|
||||||
@@ -1176,6 +1186,8 @@ void QVideoSurfaceGlslPainter::stop()
|
|||||||
|
|
||||||
m_textureCount = 0;
|
m_textureCount = 0;
|
||||||
m_handleType = QAbstractVideoBuffer::NoHandle;
|
m_handleType = QAbstractVideoBuffer::NoHandle;
|
||||||
|
|
||||||
|
QVideoSurfaceGLPainter::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
|
QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ SOURCES += \
|
|||||||
$$PWD/qandroidmediacontainercontrol.cpp \
|
$$PWD/qandroidmediacontainercontrol.cpp \
|
||||||
$$PWD/qandroidvideoencodersettingscontrol.cpp \
|
$$PWD/qandroidvideoencodersettingscontrol.cpp \
|
||||||
$$PWD/qandroidaudioinputselectorcontrol.cpp \
|
$$PWD/qandroidaudioinputselectorcontrol.cpp \
|
||||||
$$PWD/qandroidmediavideoprobecontrol.cpp
|
$$PWD/qandroidmediavideoprobecontrol.cpp \
|
||||||
|
$$PWD/qandroidcamerainfocontrol.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/qandroidcaptureservice.h \
|
$$PWD/qandroidcaptureservice.h \
|
||||||
@@ -46,4 +47,5 @@ HEADERS += \
|
|||||||
$$PWD/qandroidmediacontainercontrol.h \
|
$$PWD/qandroidmediacontainercontrol.h \
|
||||||
$$PWD/qandroidvideoencodersettingscontrol.h \
|
$$PWD/qandroidvideoencodersettingscontrol.h \
|
||||||
$$PWD/qandroidaudioinputselectorcontrol.h \
|
$$PWD/qandroidaudioinputselectorcontrol.h \
|
||||||
$$PWD/qandroidmediavideoprobecontrol.h
|
$$PWD/qandroidmediavideoprobecontrol.h \
|
||||||
|
$$PWD/qandroidcamerainfocontrol.h
|
||||||
|
|||||||
@@ -46,36 +46,15 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static QPointF rotateNormalizedPoint(const QPointF &point, int rotation)
|
static QRect adjustedArea(const QRectF &area)
|
||||||
{
|
|
||||||
const qreal one(1.0f);
|
|
||||||
|
|
||||||
switch (rotation) {
|
|
||||||
case 0:
|
|
||||||
default:
|
|
||||||
return point;
|
|
||||||
case 90:
|
|
||||||
return QPointF(point.y(), one - point.x());
|
|
||||||
case 180:
|
|
||||||
return QPointF(one - point.x(), one - point.y());
|
|
||||||
case 270:
|
|
||||||
return QPointF(one - point.y(), point.x());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static QRect adjustedArea(const QRectF &area, int rotation)
|
|
||||||
{
|
{
|
||||||
// Qt maps focus points in the range (0.0, 0.0) -> (1.0, 1.0)
|
// Qt maps focus points in the range (0.0, 0.0) -> (1.0, 1.0)
|
||||||
// Android maps focus points in the range (-1000, -1000) -> (1000, 1000)
|
// Android maps focus points in the range (-1000, -1000) -> (1000, 1000)
|
||||||
// Converts an area in Qt coordinates to Android coordinates
|
// Converts an area in Qt coordinates to Android coordinates
|
||||||
// Applies 'rotation' in the counter-clockwise direction
|
return QRect(-1000 + qRound(area.x() * 2000),
|
||||||
QRectF rotated(rotateNormalizedPoint(area.topLeft(), rotation),
|
-1000 + qRound(area.y() * 2000),
|
||||||
rotateNormalizedPoint(area.bottomRight(), rotation));
|
qRound(area.width() * 2000),
|
||||||
|
qRound(area.height() * 2000))
|
||||||
return QRect(-1000 + qRound(rotated.x() * 2000),
|
|
||||||
-1000 + qRound(rotated.y() * 2000),
|
|
||||||
qRound(rotated.width() * 2000),
|
|
||||||
qRound(rotated.height() * 2000))
|
|
||||||
.intersected(QRect(-1000, -1000, 2000, 2000));
|
.intersected(QRect(-1000, -1000, 2000, 2000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,9 +242,6 @@ void QAndroidCameraFocusControl::updateFocusZones(QCameraFocusZone::FocusZoneSta
|
|||||||
if (!viewportSize.isValid())
|
if (!viewportSize.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_session->camera()->getDisplayOrientation() % 180)
|
|
||||||
viewportSize.transpose();
|
|
||||||
|
|
||||||
QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height());
|
QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height());
|
||||||
float x = qBound(qreal(0),
|
float x = qBound(qreal(0),
|
||||||
m_actualFocusPoint.x() - (focusSize.width() / 2),
|
m_actualFocusPoint.x() - (focusSize.width() / 2),
|
||||||
@@ -288,13 +264,8 @@ void QAndroidCameraFocusControl::setCameraFocusArea()
|
|||||||
// in FocusPointAuto mode, leave the area list empty
|
// in FocusPointAuto mode, leave the area list empty
|
||||||
// to let the driver choose the focus point.
|
// to let the driver choose the focus point.
|
||||||
|
|
||||||
for (int i = 0; i < m_focusZones.size(); ++i) {
|
for (int i = 0; i < m_focusZones.size(); ++i)
|
||||||
// The area passed to Android should be in sensor orientation.
|
areas.append(adjustedArea(m_focusZones.at(i).area()));
|
||||||
// What we have in m_focusZones is in viewport orientation, so revert the rotation set
|
|
||||||
// on the viewport to get sensor coordinates.
|
|
||||||
areas.append(adjustedArea(m_focusZones.at(i).area(),
|
|
||||||
m_session->camera()->getDisplayOrientation()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
m_session->camera()->setFocusAreas(areas);
|
m_session->camera()->setFocusAreas(areas);
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 "qandroidcamerainfocontrol.h"
|
||||||
|
|
||||||
|
#include "qandroidcamerasession.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QCamera::Position QAndroidCameraInfoControl::position(const QString &deviceName)
|
||||||
|
{
|
||||||
|
const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras();
|
||||||
|
for (int i = 0; i < cameras.count(); ++i) {
|
||||||
|
const AndroidCameraInfo &info = cameras.at(i);
|
||||||
|
if (QString::fromLatin1(info.name) == deviceName)
|
||||||
|
return info.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QCamera::UnspecifiedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QAndroidCameraInfoControl::orientation(const QString &deviceName)
|
||||||
|
{
|
||||||
|
const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras();
|
||||||
|
for (int i = 0; i < cameras.count(); ++i) {
|
||||||
|
const AndroidCameraInfo &info = cameras.at(i);
|
||||||
|
if (QString::fromLatin1(info.name) == deviceName)
|
||||||
|
return info.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCamera::Position QAndroidCameraInfoControl::cameraPosition(const QString &deviceName) const
|
||||||
|
{
|
||||||
|
return position(deviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QAndroidCameraInfoControl::cameraOrientation(const QString &deviceName) const
|
||||||
|
{
|
||||||
|
return orientation(deviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 QANDROIDCAMERAINFOCONTROL_H
|
||||||
|
#define QANDROIDCAMERAINFOCONTROL_H
|
||||||
|
|
||||||
|
#include <qcamerainfocontrol.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QAndroidCameraInfoControl : public QCameraInfoControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QCamera::Position cameraPosition(const QString &deviceName) const;
|
||||||
|
int cameraOrientation(const QString &deviceName) const;
|
||||||
|
|
||||||
|
static QCamera::Position position(const QString &deviceName);
|
||||||
|
static int orientation(const QString &deviceName);
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QANDROIDCAMERAINFOCONTROL_H
|
||||||
@@ -90,13 +90,13 @@ private:
|
|||||||
int bytesPerLine;
|
int bytesPerLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(QList<AndroidCameraInfo>, g_availableCameras)
|
||||||
|
|
||||||
QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
|
QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_selectedCamera(0)
|
, m_selectedCamera(0)
|
||||||
, m_camera(0)
|
, m_camera(0)
|
||||||
, m_nativeOrientation(0)
|
, m_nativeOrientation(0)
|
||||||
, m_previewOrientation(0)
|
|
||||||
, m_videoOutput(0)
|
, m_videoOutput(0)
|
||||||
, m_captureMode(QCamera::CaptureViewfinder)
|
, m_captureMode(QCamera::CaptureViewfinder)
|
||||||
, m_state(QCamera::UnloadedState)
|
, m_state(QCamera::UnloadedState)
|
||||||
@@ -175,6 +175,54 @@ void QAndroidCameraSession::setState(QCamera::State state)
|
|||||||
emit stateChanged(m_state);
|
emit stateChanged(m_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QAndroidCameraSession::updateAvailableCameras()
|
||||||
|
{
|
||||||
|
g_availableCameras->clear();
|
||||||
|
|
||||||
|
const QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo");
|
||||||
|
const int numCameras = QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera",
|
||||||
|
"getNumberOfCameras");
|
||||||
|
|
||||||
|
for (int i = 0; i < numCameras; ++i) {
|
||||||
|
AndroidCameraInfo info;
|
||||||
|
|
||||||
|
QJNIObjectPrivate::callStaticMethod<void>("android/hardware/Camera",
|
||||||
|
"getCameraInfo",
|
||||||
|
"(ILandroid/hardware/Camera$CameraInfo;)V",
|
||||||
|
i, cameraInfo.object());
|
||||||
|
|
||||||
|
JCamera::CameraFacing facing = JCamera::CameraFacing(cameraInfo.getField<jint>("facing"));
|
||||||
|
// The orientation provided by Android is counter-clockwise, we need it clockwise
|
||||||
|
info.orientation = (360 - cameraInfo.getField<jint>("orientation")) % 360;
|
||||||
|
|
||||||
|
switch (facing) {
|
||||||
|
case JCamera::CameraFacingBack:
|
||||||
|
info.name = QByteArray("back");
|
||||||
|
info.description = QStringLiteral("Rear-facing camera");
|
||||||
|
info.position = QCamera::BackFace;
|
||||||
|
break;
|
||||||
|
case JCamera::CameraFacingFront:
|
||||||
|
info.name = QByteArray("front");
|
||||||
|
info.description = QStringLiteral("Front-facing camera");
|
||||||
|
info.position = QCamera::FrontFace;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.name.isNull())
|
||||||
|
g_availableCameras->append(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<AndroidCameraInfo> &QAndroidCameraSession::availableCameras()
|
||||||
|
{
|
||||||
|
if (g_availableCameras->isEmpty())
|
||||||
|
updateAvailableCameras();
|
||||||
|
|
||||||
|
return *g_availableCameras;
|
||||||
|
}
|
||||||
|
|
||||||
bool QAndroidCameraSession::open()
|
bool QAndroidCameraSession::open()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
@@ -196,12 +244,6 @@ bool QAndroidCameraSession::open()
|
|||||||
|
|
||||||
m_nativeOrientation = m_camera->getNativeOrientation();
|
m_nativeOrientation = m_camera->getNativeOrientation();
|
||||||
|
|
||||||
// Preview orientation will always match the device natural orientation
|
|
||||||
if (m_camera->getFacing() == JCamera::CameraFacingFront)
|
|
||||||
m_previewOrientation = 360 - m_nativeOrientation;
|
|
||||||
else
|
|
||||||
m_previewOrientation = m_nativeOrientation;
|
|
||||||
|
|
||||||
m_status = QCamera::LoadedStatus;
|
m_status = QCamera::LoadedStatus;
|
||||||
|
|
||||||
if (m_camera->getPreviewFormat() != JCamera::NV21)
|
if (m_camera->getPreviewFormat() != JCamera::NV21)
|
||||||
@@ -279,16 +321,8 @@ void QAndroidCameraSession::adjustViewfinderSize(const QSize &captureSize, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_camera->previewSize() != viewfinderResolution) {
|
if (m_camera->previewSize() != viewfinderResolution) {
|
||||||
if (m_videoOutput) {
|
if (m_videoOutput)
|
||||||
QSize size = viewfinderResolution;
|
m_videoOutput->setVideoSize(viewfinderResolution);
|
||||||
|
|
||||||
// If the preview orientation is not the defaut one (0 or 180 degrees),
|
|
||||||
// we have to invert the output aspect ratio.
|
|
||||||
if (m_previewOrientation % 180)
|
|
||||||
size.transpose();
|
|
||||||
|
|
||||||
m_videoOutput->setVideoSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if preview is started, we have to stop it first before changing its size
|
// if preview is started, we have to stop it first before changing its size
|
||||||
if (m_previewStarted && restartPreview)
|
if (m_previewStarted && restartPreview)
|
||||||
@@ -312,7 +346,6 @@ void QAndroidCameraSession::startPreview()
|
|||||||
|
|
||||||
applyImageSettings();
|
applyImageSettings();
|
||||||
adjustViewfinderSize(m_imageSettings.resolution());
|
adjustViewfinderSize(m_imageSettings.resolution());
|
||||||
m_camera->setDisplayOrientation(m_previewOrientation);
|
|
||||||
|
|
||||||
if (m_videoOutput && m_videoOutput->isReady())
|
if (m_videoOutput && m_videoOutput->isReady())
|
||||||
onVideoOutputReady(true);
|
onVideoOutputReady(true);
|
||||||
|
|||||||
@@ -55,6 +55,14 @@ class JCamera;
|
|||||||
class QAndroidVideoOutput;
|
class QAndroidVideoOutput;
|
||||||
class QAndroidMediaVideoProbeControl;
|
class QAndroidMediaVideoProbeControl;
|
||||||
|
|
||||||
|
struct AndroidCameraInfo
|
||||||
|
{
|
||||||
|
QByteArray name;
|
||||||
|
QString description;
|
||||||
|
QCamera::Position position;
|
||||||
|
int orientation;
|
||||||
|
};
|
||||||
|
|
||||||
class QAndroidCameraSession : public QObject
|
class QAndroidCameraSession : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -62,6 +70,8 @@ public:
|
|||||||
explicit QAndroidCameraSession(QObject *parent = 0);
|
explicit QAndroidCameraSession(QObject *parent = 0);
|
||||||
~QAndroidCameraSession();
|
~QAndroidCameraSession();
|
||||||
|
|
||||||
|
static const QList<AndroidCameraInfo> &availableCameras();
|
||||||
|
|
||||||
void setSelectedCamera(int cameraId) { m_selectedCamera = cameraId; }
|
void setSelectedCamera(int cameraId) { m_selectedCamera = cameraId; }
|
||||||
JCamera *camera() const { return m_camera; }
|
JCamera *camera() const { return m_camera; }
|
||||||
|
|
||||||
@@ -126,6 +136,8 @@ private Q_SLOTS:
|
|||||||
void onCameraPreviewStopped();
|
void onCameraPreviewStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void updateAvailableCameras();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
@@ -144,7 +156,6 @@ private:
|
|||||||
int m_selectedCamera;
|
int m_selectedCamera;
|
||||||
JCamera *m_camera;
|
JCamera *m_camera;
|
||||||
int m_nativeOrientation;
|
int m_nativeOrientation;
|
||||||
int m_previewOrientation;
|
|
||||||
QAndroidVideoOutput *m_videoOutput;
|
QAndroidVideoOutput *m_videoOutput;
|
||||||
|
|
||||||
QCamera::CaptureModes m_captureMode;
|
QCamera::CaptureModes m_captureMode;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "qandroidmediarecordercontrol.h"
|
#include "qandroidmediarecordercontrol.h"
|
||||||
#include "qandroidcapturesession.h"
|
#include "qandroidcapturesession.h"
|
||||||
#include "qandroidcameracontrol.h"
|
#include "qandroidcameracontrol.h"
|
||||||
|
#include "qandroidcamerainfocontrol.h"
|
||||||
#include "qandroidvideodeviceselectorcontrol.h"
|
#include "qandroidvideodeviceselectorcontrol.h"
|
||||||
#include "qandroidaudioinputselectorcontrol.h"
|
#include "qandroidaudioinputselectorcontrol.h"
|
||||||
#include "qandroidcamerasession.h"
|
#include "qandroidcamerasession.h"
|
||||||
@@ -75,6 +76,7 @@ QAndroidCaptureService::QAndroidCaptureService(const QString &service, QObject *
|
|||||||
if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) {
|
if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) {
|
||||||
m_cameraSession = new QAndroidCameraSession;
|
m_cameraSession = new QAndroidCameraSession;
|
||||||
m_cameraControl = new QAndroidCameraControl(m_cameraSession);
|
m_cameraControl = new QAndroidCameraControl(m_cameraSession);
|
||||||
|
m_cameraInfoControl = new QAndroidCameraInfoControl;
|
||||||
m_videoInputControl = new QAndroidVideoDeviceSelectorControl(m_cameraSession);
|
m_videoInputControl = new QAndroidVideoDeviceSelectorControl(m_cameraSession);
|
||||||
m_cameraZoomControl = new QAndroidCameraZoomControl(m_cameraSession);
|
m_cameraZoomControl = new QAndroidCameraZoomControl(m_cameraSession);
|
||||||
m_cameraExposureControl = new QAndroidCameraExposureControl(m_cameraSession);
|
m_cameraExposureControl = new QAndroidCameraExposureControl(m_cameraSession);
|
||||||
@@ -90,6 +92,7 @@ QAndroidCaptureService::QAndroidCaptureService(const QString &service, QObject *
|
|||||||
} else {
|
} else {
|
||||||
m_cameraSession = 0;
|
m_cameraSession = 0;
|
||||||
m_cameraControl = 0;
|
m_cameraControl = 0;
|
||||||
|
m_cameraInfoControl = 0;
|
||||||
m_videoInputControl = 0;
|
m_videoInputControl = 0;
|
||||||
m_cameraZoomControl = 0;
|
m_cameraZoomControl = 0;
|
||||||
m_cameraExposureControl = 0;
|
m_cameraExposureControl = 0;
|
||||||
@@ -125,6 +128,7 @@ QAndroidCaptureService::~QAndroidCaptureService()
|
|||||||
delete m_recorderControl;
|
delete m_recorderControl;
|
||||||
delete m_captureSession;
|
delete m_captureSession;
|
||||||
delete m_cameraControl;
|
delete m_cameraControl;
|
||||||
|
delete m_cameraInfoControl;
|
||||||
delete m_audioInputControl;
|
delete m_audioInputControl;
|
||||||
delete m_videoInputControl;
|
delete m_videoInputControl;
|
||||||
delete m_videoRendererControl;
|
delete m_videoRendererControl;
|
||||||
@@ -158,6 +162,9 @@ QMediaControl *QAndroidCaptureService::requestControl(const char *name)
|
|||||||
if (qstrcmp(name, QCameraControl_iid) == 0)
|
if (qstrcmp(name, QCameraControl_iid) == 0)
|
||||||
return m_cameraControl;
|
return m_cameraControl;
|
||||||
|
|
||||||
|
if (qstrcmp(name, QCameraInfoControl_iid) == 0)
|
||||||
|
return m_cameraInfoControl;
|
||||||
|
|
||||||
if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0)
|
if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0)
|
||||||
return m_audioInputControl;
|
return m_audioInputControl;
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QAndroidMediaRecorderControl;
|
class QAndroidMediaRecorderControl;
|
||||||
class QAndroidCaptureSession;
|
class QAndroidCaptureSession;
|
||||||
class QAndroidCameraControl;
|
class QAndroidCameraControl;
|
||||||
|
class QAndroidCameraInfoControl;
|
||||||
class QAndroidVideoDeviceSelectorControl;
|
class QAndroidVideoDeviceSelectorControl;
|
||||||
class QAndroidAudioInputSelectorControl;
|
class QAndroidAudioInputSelectorControl;
|
||||||
class QAndroidCameraSession;
|
class QAndroidCameraSession;
|
||||||
@@ -85,6 +86,7 @@ private:
|
|||||||
QAndroidMediaRecorderControl *m_recorderControl;
|
QAndroidMediaRecorderControl *m_recorderControl;
|
||||||
QAndroidCaptureSession *m_captureSession;
|
QAndroidCaptureSession *m_captureSession;
|
||||||
QAndroidCameraControl *m_cameraControl;
|
QAndroidCameraControl *m_cameraControl;
|
||||||
|
QAndroidCameraInfoControl *m_cameraInfoControl;
|
||||||
QAndroidVideoDeviceSelectorControl *m_videoInputControl;
|
QAndroidVideoDeviceSelectorControl *m_videoInputControl;
|
||||||
QAndroidAudioInputSelectorControl *m_audioInputControl;
|
QAndroidAudioInputSelectorControl *m_audioInputControl;
|
||||||
QAndroidCameraSession *m_cameraSession;
|
QAndroidCameraSession *m_cameraSession;
|
||||||
|
|||||||
@@ -46,16 +46,11 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QList<QByteArray> QAndroidVideoDeviceSelectorControl::m_names;
|
|
||||||
QStringList QAndroidVideoDeviceSelectorControl::m_descriptions;
|
|
||||||
|
|
||||||
QAndroidVideoDeviceSelectorControl::QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session)
|
QAndroidVideoDeviceSelectorControl::QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session)
|
||||||
: QVideoDeviceSelectorControl(0)
|
: QVideoDeviceSelectorControl(0)
|
||||||
, m_selectedDevice(0)
|
, m_selectedDevice(0)
|
||||||
, m_cameraSession(session)
|
, m_cameraSession(session)
|
||||||
{
|
{
|
||||||
if (m_names.isEmpty())
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAndroidVideoDeviceSelectorControl::~QAndroidVideoDeviceSelectorControl()
|
QAndroidVideoDeviceSelectorControl::~QAndroidVideoDeviceSelectorControl()
|
||||||
@@ -64,17 +59,23 @@ QAndroidVideoDeviceSelectorControl::~QAndroidVideoDeviceSelectorControl()
|
|||||||
|
|
||||||
int QAndroidVideoDeviceSelectorControl::deviceCount() const
|
int QAndroidVideoDeviceSelectorControl::deviceCount() const
|
||||||
{
|
{
|
||||||
return m_names.size();
|
return QAndroidCameraSession::availableCameras().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QAndroidVideoDeviceSelectorControl::deviceName(int index) const
|
QString QAndroidVideoDeviceSelectorControl::deviceName(int index) const
|
||||||
{
|
{
|
||||||
return m_names.at(index);
|
if (index < 0 || index >= QAndroidCameraSession::availableCameras().count())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return QString::fromLatin1(QAndroidCameraSession::availableCameras().at(index).name);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QAndroidVideoDeviceSelectorControl::deviceDescription(int index) const
|
QString QAndroidVideoDeviceSelectorControl::deviceDescription(int index) const
|
||||||
{
|
{
|
||||||
return m_descriptions.at(index);
|
if (index < 0 || index >= QAndroidCameraSession::availableCameras().count())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return QAndroidCameraSession::availableCameras().at(index).description;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QAndroidVideoDeviceSelectorControl::defaultDevice() const
|
int QAndroidVideoDeviceSelectorControl::defaultDevice() const
|
||||||
@@ -97,53 +98,4 @@ void QAndroidVideoDeviceSelectorControl::setSelectedDevice(int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAndroidVideoDeviceSelectorControl::update()
|
|
||||||
{
|
|
||||||
m_names.clear();
|
|
||||||
m_descriptions.clear();
|
|
||||||
|
|
||||||
QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo");
|
|
||||||
int numCameras = QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera",
|
|
||||||
"getNumberOfCameras");
|
|
||||||
|
|
||||||
for (int i = 0; i < numCameras; ++i) {
|
|
||||||
QJNIObjectPrivate::callStaticMethod<void>("android/hardware/Camera",
|
|
||||||
"getCameraInfo",
|
|
||||||
"(ILandroid/hardware/Camera$CameraInfo;)V",
|
|
||||||
i, cameraInfo.object());
|
|
||||||
|
|
||||||
JCamera::CameraFacing facing = JCamera::CameraFacing(cameraInfo.getField<jint>("facing"));
|
|
||||||
|
|
||||||
switch (facing) {
|
|
||||||
case JCamera::CameraFacingBack:
|
|
||||||
m_names.append("back");
|
|
||||||
m_descriptions.append(QStringLiteral("Rear-facing camera"));
|
|
||||||
break;
|
|
||||||
case JCamera::CameraFacingFront:
|
|
||||||
m_names.append("front");
|
|
||||||
m_descriptions.append(QStringLiteral("Front-facing camera"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QByteArray> QAndroidVideoDeviceSelectorControl::availableDevices()
|
|
||||||
{
|
|
||||||
if (m_names.isEmpty())
|
|
||||||
update();
|
|
||||||
|
|
||||||
return m_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QAndroidVideoDeviceSelectorControl::availableDeviceDescription(const QByteArray &device)
|
|
||||||
{
|
|
||||||
int i = m_names.indexOf(device);
|
|
||||||
if (i != -1)
|
|
||||||
return m_descriptions.at(i);
|
|
||||||
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -63,18 +63,10 @@ public:
|
|||||||
|
|
||||||
int defaultDevice() const;
|
int defaultDevice() const;
|
||||||
int selectedDevice() const;
|
int selectedDevice() const;
|
||||||
|
|
||||||
void setSelectedDevice(int index);
|
void setSelectedDevice(int index);
|
||||||
|
|
||||||
static QList<QByteArray> availableDevices();
|
|
||||||
static QString availableDeviceDescription(const QByteArray &device);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void update();
|
|
||||||
|
|
||||||
int m_selectedDevice;
|
int m_selectedDevice;
|
||||||
static QList<QByteArray> m_names;
|
|
||||||
static QStringList m_descriptions;
|
|
||||||
|
|
||||||
QAndroidCameraSession *m_cameraSession;
|
QAndroidCameraSession *m_cameraSession;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
#include "qandroidmediaservice.h"
|
#include "qandroidmediaservice.h"
|
||||||
#include "qandroidcaptureservice.h"
|
#include "qandroidcaptureservice.h"
|
||||||
#include "qandroidvideodeviceselectorcontrol.h"
|
|
||||||
#include "qandroidaudioinputselectorcontrol.h"
|
#include "qandroidaudioinputselectorcontrol.h"
|
||||||
|
#include "qandroidcamerainfocontrol.h"
|
||||||
|
#include "qandroidcamerasession.h"
|
||||||
#include "jmediaplayer.h"
|
#include "jmediaplayer.h"
|
||||||
#include "jsurfacetexture.h"
|
#include "jsurfacetexture.h"
|
||||||
#include "jsurfacetextureholder.h"
|
#include "jsurfacetextureholder.h"
|
||||||
@@ -96,10 +97,23 @@ QMediaServiceProviderHint::Features QAndroidMediaServicePlugin::supportedFeature
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray QAndroidMediaServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA && !QAndroidCameraSession::availableCameras().isEmpty())
|
||||||
|
return QAndroidCameraSession::availableCameras().first().name;
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> QAndroidMediaServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> QAndroidMediaServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA)
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
return QAndroidVideoDeviceSelectorControl::availableDevices();
|
QList<QByteArray> devices;
|
||||||
|
const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras();
|
||||||
|
for (int i = 0; i < cameras.count(); ++i)
|
||||||
|
devices.append(cameras.at(i).name);
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
||||||
return QAndroidAudioInputSelectorControl::availableDevices();
|
return QAndroidAudioInputSelectorControl::availableDevices();
|
||||||
@@ -109,8 +123,14 @@ QList<QByteArray> QAndroidMediaServicePlugin::devices(const QByteArray &service)
|
|||||||
|
|
||||||
QString QAndroidMediaServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
QString QAndroidMediaServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA)
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
return QAndroidVideoDeviceSelectorControl::availableDeviceDescription(device);
|
const QList<AndroidCameraInfo> &cameras = QAndroidCameraSession::availableCameras();
|
||||||
|
for (int i = 0; i < cameras.count(); ++i) {
|
||||||
|
const AndroidCameraInfo &info = cameras.at(i);
|
||||||
|
if (info.name == device)
|
||||||
|
return info.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
||||||
return QAndroidAudioInputSelectorControl::availableDeviceDescription(device);
|
return QAndroidAudioInputSelectorControl::availableDeviceDescription(device);
|
||||||
@@ -118,6 +138,16 @@ QString QAndroidMediaServicePlugin::deviceDescription(const QByteArray &service,
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCamera::Position QAndroidMediaServicePlugin::cameraPosition(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
return QAndroidCameraInfoControl::position(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QAndroidMediaServicePlugin::cameraOrientation(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
return QAndroidCameraInfoControl::orientation(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
|
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,10 +49,14 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QAndroidMediaServicePlugin
|
class QAndroidMediaServicePlugin
|
||||||
: public QMediaServiceProviderPlugin
|
: public QMediaServiceProviderPlugin
|
||||||
, public QMediaServiceSupportedDevicesInterface
|
, public QMediaServiceSupportedDevicesInterface
|
||||||
|
, public QMediaServiceDefaultDeviceInterface
|
||||||
|
, public QMediaServiceCameraInfoInterface
|
||||||
, public QMediaServiceFeaturesInterface
|
, public QMediaServiceFeaturesInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceCameraInfoInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0"
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0"
|
||||||
FILE "android_mediaservice.json")
|
FILE "android_mediaservice.json")
|
||||||
@@ -66,8 +70,12 @@ public:
|
|||||||
|
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QByteArray defaultDevice(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||||
|
QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QCamera::Position cameraPosition(const QByteArray &device) const Q_DECL_OVERRIDE;
|
||||||
|
int cameraOrientation(const QByteArray &device) const Q_DECL_OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -158,8 +158,6 @@ class JCameraWorker : public QObject, public QJNIObjectPrivate
|
|||||||
Q_INVOKABLE JCamera::CameraFacing getFacing();
|
Q_INVOKABLE JCamera::CameraFacing getFacing();
|
||||||
Q_INVOKABLE int getNativeOrientation();
|
Q_INVOKABLE int getNativeOrientation();
|
||||||
|
|
||||||
Q_INVOKABLE void setDisplayOrientation(int degrees);
|
|
||||||
|
|
||||||
Q_INVOKABLE QSize getPreferredPreviewSizeForVideo();
|
Q_INVOKABLE QSize getPreferredPreviewSizeForVideo();
|
||||||
Q_INVOKABLE QList<QSize> getSupportedPreviewSizes();
|
Q_INVOKABLE QList<QSize> getSupportedPreviewSizes();
|
||||||
|
|
||||||
@@ -231,7 +229,6 @@ class JCameraWorker : public QObject, public QJNIObjectPrivate
|
|||||||
|
|
||||||
QSize m_previewSize;
|
QSize m_previewSize;
|
||||||
int m_rotation;
|
int m_rotation;
|
||||||
int m_displayOrientation;
|
|
||||||
|
|
||||||
bool m_hasAPI14;
|
bool m_hasAPI14;
|
||||||
|
|
||||||
@@ -337,17 +334,6 @@ int JCamera::getNativeOrientation()
|
|||||||
return d->getNativeOrientation();
|
return d->getNativeOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
int JCamera::getDisplayOrientation() const
|
|
||||||
{
|
|
||||||
return d->m_displayOrientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JCamera::setDisplayOrientation(int degrees)
|
|
||||||
{
|
|
||||||
d->m_displayOrientation = degrees;
|
|
||||||
QMetaObject::invokeMethod(d, "setDisplayOrientation", Q_ARG(int, degrees));
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize JCamera::getPreferredPreviewSizeForVideo()
|
QSize JCamera::getPreferredPreviewSizeForVideo()
|
||||||
{
|
{
|
||||||
return d->getPreferredPreviewSizeForVideo();
|
return d->getPreferredPreviewSizeForVideo();
|
||||||
@@ -626,7 +612,6 @@ JCameraWorker::JCameraWorker(JCamera *camera, int cameraId, jobject cam, QThread
|
|||||||
, QJNIObjectPrivate(cam)
|
, QJNIObjectPrivate(cam)
|
||||||
, m_cameraId(cameraId)
|
, m_cameraId(cameraId)
|
||||||
, m_rotation(0)
|
, m_rotation(0)
|
||||||
, m_displayOrientation(0)
|
|
||||||
, m_hasAPI14(false)
|
, m_hasAPI14(false)
|
||||||
, m_parametersMutex(QMutex::Recursive)
|
, m_parametersMutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
@@ -692,11 +677,6 @@ int JCameraWorker::getNativeOrientation()
|
|||||||
return m_info.getField<jint>("orientation");
|
return m_info.getField<jint>("orientation");
|
||||||
}
|
}
|
||||||
|
|
||||||
void JCameraWorker::setDisplayOrientation(int degrees)
|
|
||||||
{
|
|
||||||
callMethod<void>("setDisplayOrientation", "(I)V", degrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize JCameraWorker::getPreferredPreviewSizeForVideo()
|
QSize JCameraWorker::getPreferredPreviewSizeForVideo()
|
||||||
{
|
{
|
||||||
QMutexLocker parametersLocker(&m_parametersMutex);
|
QMutexLocker parametersLocker(&m_parametersMutex);
|
||||||
|
|||||||
@@ -88,9 +88,6 @@ public:
|
|||||||
CameraFacing getFacing();
|
CameraFacing getFacing();
|
||||||
int getNativeOrientation();
|
int getNativeOrientation();
|
||||||
|
|
||||||
int getDisplayOrientation() const;
|
|
||||||
void setDisplayOrientation(int degrees);
|
|
||||||
|
|
||||||
QSize getPreferredPreviewSizeForVideo();
|
QSize getPreferredPreviewSizeForVideo();
|
||||||
QList<QSize> getSupportedPreviewSizes();
|
QList<QSize> getSupportedPreviewSizes();
|
||||||
|
|
||||||
|
|||||||
61
src/plugins/avfoundation/camera/avfcamerainfocontrol.h
Normal file
61
src/plugins/avfoundation/camera/avfcamerainfocontrol.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 AVFCAMERAINFOCONTROL_H
|
||||||
|
#define AVFCAMERAINFOCONTROL_H
|
||||||
|
|
||||||
|
#include <qcamerainfocontrol.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class AVFCameraInfoControl : public QCameraInfoControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AVFCameraInfoControl(QObject *parent = 0);
|
||||||
|
|
||||||
|
QCamera::Position cameraPosition(const QString &deviceName) const;
|
||||||
|
int cameraOrientation(const QString &deviceName) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // AVFCAMERAINFOCONTROL_H
|
||||||
62
src/plugins/avfoundation/camera/avfcamerainfocontrol.mm
Normal file
62
src/plugins/avfoundation/camera/avfcamerainfocontrol.mm
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 "avfcamerainfocontrol.h"
|
||||||
|
#include "avfcamerasession.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
AVFCameraInfoControl::AVFCameraInfoControl(QObject *parent)
|
||||||
|
: QCameraInfoControl(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QCamera::Position AVFCameraInfoControl::cameraPosition(const QString &deviceName) const
|
||||||
|
{
|
||||||
|
return AVFCameraSession::cameraDeviceInfo(deviceName.toUtf8()).position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AVFCameraInfoControl::cameraOrientation(const QString &deviceName) const
|
||||||
|
{
|
||||||
|
return AVFCameraSession::cameraDeviceInfo(deviceName.toUtf8()).orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QCameraControl;
|
class QCameraControl;
|
||||||
class AVFCameraControl;
|
class AVFCameraControl;
|
||||||
|
class AVFCameraInfoControl;
|
||||||
class AVFCameraMetaDataControl;
|
class AVFCameraMetaDataControl;
|
||||||
class AVFVideoWindowControl;
|
class AVFVideoWindowControl;
|
||||||
class AVFVideoWidgetControl;
|
class AVFVideoWidgetControl;
|
||||||
@@ -82,6 +83,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
AVFCameraSession *m_session;
|
AVFCameraSession *m_session;
|
||||||
AVFCameraControl *m_cameraControl;
|
AVFCameraControl *m_cameraControl;
|
||||||
|
AVFCameraInfoControl *m_cameraInfoControl;
|
||||||
AVFVideoDeviceControl *m_videoDeviceControl;
|
AVFVideoDeviceControl *m_videoDeviceControl;
|
||||||
AVFAudioInputSelectorControl *m_audioInputSelectorControl;
|
AVFAudioInputSelectorControl *m_audioInputSelectorControl;
|
||||||
AVFVideoRendererControl *m_videoOutput;
|
AVFVideoRendererControl *m_videoOutput;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include "avfcameraservice.h"
|
#include "avfcameraservice.h"
|
||||||
#include "avfcameracontrol.h"
|
#include "avfcameracontrol.h"
|
||||||
|
#include "avfcamerainfocontrol.h"
|
||||||
#include "avfcamerasession.h"
|
#include "avfcamerasession.h"
|
||||||
#include "avfvideodevicecontrol.h"
|
#include "avfvideodevicecontrol.h"
|
||||||
#include "avfaudioinputselectorcontrol.h"
|
#include "avfaudioinputselectorcontrol.h"
|
||||||
@@ -65,6 +66,7 @@ AVFCameraService::AVFCameraService(QObject *parent):
|
|||||||
{
|
{
|
||||||
m_session = new AVFCameraSession(this);
|
m_session = new AVFCameraSession(this);
|
||||||
m_cameraControl = new AVFCameraControl(this);
|
m_cameraControl = new AVFCameraControl(this);
|
||||||
|
m_cameraInfoControl = new AVFCameraInfoControl(this);
|
||||||
m_videoDeviceControl = new AVFVideoDeviceControl(this);
|
m_videoDeviceControl = new AVFVideoDeviceControl(this);
|
||||||
m_audioInputSelectorControl = new AVFAudioInputSelectorControl(this);
|
m_audioInputSelectorControl = new AVFAudioInputSelectorControl(this);
|
||||||
|
|
||||||
@@ -98,6 +100,9 @@ QMediaControl *AVFCameraService::requestControl(const char *name)
|
|||||||
if (qstrcmp(name, QCameraControl_iid) == 0)
|
if (qstrcmp(name, QCameraControl_iid) == 0)
|
||||||
return m_cameraControl;
|
return m_cameraControl;
|
||||||
|
|
||||||
|
if (qstrcmp(name, QCameraInfoControl_iid) == 0)
|
||||||
|
return m_cameraInfoControl;
|
||||||
|
|
||||||
if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0)
|
if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0)
|
||||||
return m_videoDeviceControl;
|
return m_videoDeviceControl;
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,14 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class AVFServicePlugin : public QMediaServiceProviderPlugin,
|
class AVFServicePlugin : public QMediaServiceProviderPlugin,
|
||||||
public QMediaServiceSupportedDevicesInterface
|
public QMediaServiceSupportedDevicesInterface,
|
||||||
|
public QMediaServiceDefaultDeviceInterface,
|
||||||
|
public QMediaServiceCameraInfoInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceCameraInfoInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -61,14 +65,12 @@ public:
|
|||||||
QMediaService* create(QString const& key);
|
QMediaService* create(QString const& key);
|
||||||
void release(QMediaService *service);
|
void release(QMediaService *service);
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const;
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QList<QByteArray> devices(const QByteArray &service) const;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||||
|
|
||||||
private:
|
QCamera::Position cameraPosition(const QByteArray &device) const;
|
||||||
void updateDevices() const;
|
int cameraOrientation(const QByteArray &device) const;
|
||||||
|
|
||||||
mutable QList<QByteArray> m_cameraDevices;
|
|
||||||
mutable QMap<QByteArray, QString> m_cameraDescriptions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -44,15 +44,12 @@
|
|||||||
|
|
||||||
#include "avfcameraserviceplugin.h"
|
#include "avfcameraserviceplugin.h"
|
||||||
#include "avfcameraservice.h"
|
#include "avfcameraservice.h"
|
||||||
|
#include "avfcamerasession.h"
|
||||||
|
|
||||||
#include <qmediaserviceproviderplugin.h>
|
#include <qmediaserviceproviderplugin.h>
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
|
||||||
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
AVFServicePlugin::AVFServicePlugin()
|
AVFServicePlugin::AVFServicePlugin()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -72,41 +69,38 @@ void AVFServicePlugin::release(QMediaService *service)
|
|||||||
delete service;
|
delete service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray AVFServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
|
return AVFCameraSession::defaultCameraDevice();
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
if (m_cameraDevices.isEmpty())
|
return AVFCameraSession::availableCameraDevices();
|
||||||
updateDevices();
|
|
||||||
|
|
||||||
return m_cameraDevices;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QList<QByteArray>();
|
return QList<QByteArray>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
if (m_cameraDevices.isEmpty())
|
return AVFCameraSession::cameraDeviceInfo(device).description;
|
||||||
updateDevices();
|
|
||||||
|
|
||||||
return m_cameraDescriptions.value(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AVFServicePlugin::updateDevices() const
|
QCamera::Position AVFServicePlugin::cameraPosition(const QByteArray &device) const
|
||||||
{
|
{
|
||||||
m_cameraDevices.clear();
|
return AVFCameraSession::cameraDeviceInfo(device).position;
|
||||||
m_cameraDescriptions.clear();
|
}
|
||||||
|
|
||||||
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
int AVFServicePlugin::cameraOrientation(const QByteArray &device) const
|
||||||
for (AVCaptureDevice *device in videoDevices) {
|
{
|
||||||
QByteArray deviceId([[device uniqueID] UTF8String]);
|
return AVFCameraSession::cameraDeviceInfo(device).orientation;
|
||||||
m_cameraDevices << deviceId;
|
|
||||||
m_cameraDescriptions.insert(deviceId, QString::fromUtf8([[device localizedName] UTF8String]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -55,6 +55,16 @@ class AVFCameraControl;
|
|||||||
class AVFCameraService;
|
class AVFCameraService;
|
||||||
class AVFVideoRendererControl;
|
class AVFVideoRendererControl;
|
||||||
|
|
||||||
|
struct AVFCameraInfo
|
||||||
|
{
|
||||||
|
AVFCameraInfo() : position(QCamera::UnspecifiedPosition), orientation(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QString description;
|
||||||
|
QCamera::Position position;
|
||||||
|
int orientation;
|
||||||
|
};
|
||||||
|
|
||||||
class AVFCameraSession : public QObject
|
class AVFCameraSession : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -62,6 +72,10 @@ public:
|
|||||||
AVFCameraSession(AVFCameraService *service, QObject *parent = 0);
|
AVFCameraSession(AVFCameraService *service, QObject *parent = 0);
|
||||||
~AVFCameraSession();
|
~AVFCameraSession();
|
||||||
|
|
||||||
|
static const QByteArray &defaultCameraDevice();
|
||||||
|
static const QList<QByteArray> &availableCameraDevices();
|
||||||
|
static AVFCameraInfo cameraDeviceInfo(const QByteArray &device);
|
||||||
|
|
||||||
void setVideoOutput(AVFVideoRendererControl *output);
|
void setVideoOutput(AVFVideoRendererControl *output);
|
||||||
AVCaptureSession *captureSession() const { return m_captureSession; }
|
AVCaptureSession *captureSession() const { return m_captureSession; }
|
||||||
AVCaptureDevice *videoCaptureDevice() const;
|
AVCaptureDevice *videoCaptureDevice() const;
|
||||||
@@ -84,8 +98,13 @@ Q_SIGNALS:
|
|||||||
void error(int error, const QString &errorString);
|
void error(int error, const QString &errorString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void updateCameraDevices();
|
||||||
void attachInputDevices();
|
void attachInputDevices();
|
||||||
|
|
||||||
|
static QByteArray m_defaultCameraDevice;
|
||||||
|
static QList<QByteArray> m_cameraDevices;
|
||||||
|
static QMap<QByteArray, AVFCameraInfo> m_cameraInfo;
|
||||||
|
|
||||||
AVFCameraService *m_service;
|
AVFCameraService *m_service;
|
||||||
AVFVideoRendererControl *m_videoOutput;
|
AVFVideoRendererControl *m_videoOutput;
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,10 @@
|
|||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
|
QByteArray AVFCameraSession::m_defaultCameraDevice;
|
||||||
|
QList<QByteArray> AVFCameraSession::m_cameraDevices;
|
||||||
|
QMap<QByteArray, AVFCameraInfo> AVFCameraSession::m_cameraInfo;
|
||||||
|
|
||||||
@interface AVFCameraSessionObserver : NSObject
|
@interface AVFCameraSessionObserver : NSObject
|
||||||
{
|
{
|
||||||
@private
|
@private
|
||||||
@@ -81,6 +85,7 @@ QT_USE_NAMESPACE
|
|||||||
self->m_session = session;
|
self->m_session = session;
|
||||||
self->m_captureSession = session->captureSession();
|
self->m_captureSession = session->captureSession();
|
||||||
|
|
||||||
|
[m_captureSession retain];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(processRuntimeError:)
|
selector:@selector(processRuntimeError:)
|
||||||
name:AVCaptureSessionRuntimeErrorNotification
|
name:AVCaptureSessionRuntimeErrorNotification
|
||||||
@@ -99,6 +104,22 @@ QT_USE_NAMESPACE
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||||
|
name:AVCaptureSessionRuntimeErrorNotification
|
||||||
|
object:m_captureSession];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||||
|
name:AVCaptureSessionDidStartRunningNotification
|
||||||
|
object:m_captureSession];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||||
|
name:AVCaptureSessionDidStopRunningNotification
|
||||||
|
object:m_captureSession];
|
||||||
|
[m_captureSession release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) processRuntimeError:(NSNotification *)notification
|
- (void) processRuntimeError:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
@@ -151,6 +172,74 @@ AVFCameraSession::~AVFCameraSession()
|
|||||||
[m_captureSession release];
|
[m_captureSession release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QByteArray &AVFCameraSession::defaultCameraDevice()
|
||||||
|
{
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateCameraDevices();
|
||||||
|
|
||||||
|
return m_defaultCameraDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<QByteArray> &AVFCameraSession::availableCameraDevices()
|
||||||
|
{
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateCameraDevices();
|
||||||
|
|
||||||
|
return m_cameraDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVFCameraInfo AVFCameraSession::cameraDeviceInfo(const QByteArray &device)
|
||||||
|
{
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateCameraDevices();
|
||||||
|
|
||||||
|
return m_cameraInfo.value(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AVFCameraSession::updateCameraDevices()
|
||||||
|
{
|
||||||
|
m_defaultCameraDevice.clear();
|
||||||
|
m_cameraDevices.clear();
|
||||||
|
m_cameraInfo.clear();
|
||||||
|
|
||||||
|
AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||||
|
if (defaultDevice)
|
||||||
|
m_defaultCameraDevice = QByteArray([[defaultDevice uniqueID] UTF8String]);
|
||||||
|
|
||||||
|
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
||||||
|
for (AVCaptureDevice *device in videoDevices) {
|
||||||
|
QByteArray deviceId([[device uniqueID] UTF8String]);
|
||||||
|
|
||||||
|
AVFCameraInfo info;
|
||||||
|
info.description = QString::fromNSString([device localizedName]);
|
||||||
|
|
||||||
|
// There is no API to get the camera sensor orientation, however, cameras are always
|
||||||
|
// mounted in landscape on iDevices.
|
||||||
|
// - Back-facing cameras have the top side of the sensor aligned with the right side of
|
||||||
|
// the screen when held in portrait ==> 270 degrees clockwise angle
|
||||||
|
// - Front-facing cameras have the top side of the sensor aligned with the left side of
|
||||||
|
// the screen when held in portrait ==> 270 degrees clockwise angle
|
||||||
|
// On Mac OS, the position will always be unspecified and the sensor orientation unknown.
|
||||||
|
switch (device.position) {
|
||||||
|
case AVCaptureDevicePositionBack:
|
||||||
|
info.position = QCamera::BackFace;
|
||||||
|
info.orientation = 270;
|
||||||
|
break;
|
||||||
|
case AVCaptureDevicePositionFront:
|
||||||
|
info.position = QCamera::FrontFace;
|
||||||
|
info.orientation = 270;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
info.position = QCamera::UnspecifiedPosition;
|
||||||
|
info.orientation = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cameraDevices << deviceId;
|
||||||
|
m_cameraInfo.insert(deviceId, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AVFCameraSession::setVideoOutput(AVFVideoRendererControl *output)
|
void AVFCameraSession::setVideoOutput(AVFVideoRendererControl *output)
|
||||||
{
|
{
|
||||||
m_videoOutput = output;
|
m_videoOutput = output;
|
||||||
|
|||||||
@@ -80,8 +80,6 @@ private:
|
|||||||
|
|
||||||
int m_selectedDevice;
|
int m_selectedDevice;
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
QStringList m_devices;
|
|
||||||
QStringList m_deviceDescriptions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "avfcameradebug.h"
|
#include "avfcameradebug.h"
|
||||||
#include "avfvideodevicecontrol.h"
|
#include "avfvideodevicecontrol.h"
|
||||||
#include "avfcameraservice.h"
|
#include "avfcameraservice.h"
|
||||||
|
#include "avfcamerasession.h"
|
||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
@@ -51,11 +52,6 @@ AVFVideoDeviceControl::AVFVideoDeviceControl(AVFCameraService *service, QObject
|
|||||||
, m_selectedDevice(0)
|
, m_selectedDevice(0)
|
||||||
, m_dirty(true)
|
, m_dirty(true)
|
||||||
{
|
{
|
||||||
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
|
||||||
for (AVCaptureDevice *device in videoDevices) {
|
|
||||||
m_devices << QString::fromUtf8([[device uniqueID] UTF8String]);
|
|
||||||
m_deviceDescriptions << QString::fromUtf8([[device localizedName] UTF8String]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AVFVideoDeviceControl::~AVFVideoDeviceControl()
|
AVFVideoDeviceControl::~AVFVideoDeviceControl()
|
||||||
@@ -64,22 +60,30 @@ AVFVideoDeviceControl::~AVFVideoDeviceControl()
|
|||||||
|
|
||||||
int AVFVideoDeviceControl::deviceCount() const
|
int AVFVideoDeviceControl::deviceCount() const
|
||||||
{
|
{
|
||||||
return m_devices.size();
|
return AVFCameraSession::availableCameraDevices().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AVFVideoDeviceControl::deviceName(int index) const
|
QString AVFVideoDeviceControl::deviceName(int index) const
|
||||||
{
|
{
|
||||||
return m_devices[index];
|
const QList<QByteArray> &devices = AVFCameraSession::availableCameraDevices();
|
||||||
|
if (index < 0 || index >= devices.count())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return QString::fromUtf8(devices.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AVFVideoDeviceControl::deviceDescription(int index) const
|
QString AVFVideoDeviceControl::deviceDescription(int index) const
|
||||||
{
|
{
|
||||||
return m_deviceDescriptions[index];
|
const QList<QByteArray> &devices = AVFCameraSession::availableCameraDevices();
|
||||||
|
if (index < 0 || index >= devices.count())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return AVFCameraSession::cameraDeviceInfo(devices.at(index)).description;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVFVideoDeviceControl::defaultDevice() const
|
int AVFVideoDeviceControl::defaultDevice() const
|
||||||
{
|
{
|
||||||
return 0;
|
return AVFCameraSession::availableCameraDevices().indexOf(AVFCameraSession::defaultCameraDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVFVideoDeviceControl::selectedDevice() const
|
int AVFVideoDeviceControl::selectedDevice() const
|
||||||
@@ -89,11 +93,13 @@ int AVFVideoDeviceControl::selectedDevice() const
|
|||||||
|
|
||||||
void AVFVideoDeviceControl::setSelectedDevice(int index)
|
void AVFVideoDeviceControl::setSelectedDevice(int index)
|
||||||
{
|
{
|
||||||
if (index != m_selectedDevice) {
|
if (index >= 0 &&
|
||||||
|
index < deviceCount() &&
|
||||||
|
index != m_selectedDevice) {
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
m_selectedDevice = index;
|
m_selectedDevice = index;
|
||||||
Q_EMIT selectedDeviceChanged(index);
|
Q_EMIT selectedDeviceChanged(index);
|
||||||
Q_EMIT selectedDeviceChanged(m_devices[index]);
|
Q_EMIT selectedDeviceChanged(deviceName(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,9 +108,8 @@ AVCaptureDevice *AVFVideoDeviceControl::createCaptureDevice()
|
|||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
AVCaptureDevice *device = 0;
|
AVCaptureDevice *device = 0;
|
||||||
|
|
||||||
if (!m_devices.isEmpty()) {
|
QString deviceId = deviceName(m_selectedDevice);
|
||||||
QString deviceId = m_devices.at(m_selectedDevice);
|
if (!deviceId.isEmpty()) {
|
||||||
|
|
||||||
device = [AVCaptureDevice deviceWithUniqueID:
|
device = [AVCaptureDevice deviceWithUniqueID:
|
||||||
[NSString stringWithUTF8String:
|
[NSString stringWithUTF8String:
|
||||||
deviceId.toUtf8().constData()]];
|
deviceId.toUtf8().constData()]];
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ HEADERS += \
|
|||||||
avfstoragelocation.h \
|
avfstoragelocation.h \
|
||||||
avfvideodevicecontrol.h \
|
avfvideodevicecontrol.h \
|
||||||
avfaudioinputselectorcontrol.h \
|
avfaudioinputselectorcontrol.h \
|
||||||
|
avfcamerainfocontrol.h
|
||||||
|
|
||||||
OBJECTIVE_SOURCES += \
|
OBJECTIVE_SOURCES += \
|
||||||
avfcameraserviceplugin.mm \
|
avfcameraserviceplugin.mm \
|
||||||
@@ -47,4 +48,5 @@ OBJECTIVE_SOURCES += \
|
|||||||
avfstoragelocation.mm \
|
avfstoragelocation.mm \
|
||||||
avfvideodevicecontrol.mm \
|
avfvideodevicecontrol.mm \
|
||||||
avfaudioinputselectorcontrol.mm \
|
avfaudioinputselectorcontrol.mm \
|
||||||
|
avfcamerainfocontrol.mm
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
|
|||||||
|
|
||||||
- (void) unloadMedia
|
- (void) unloadMedia
|
||||||
{
|
{
|
||||||
[m_player setRate:0.0];
|
if (m_player)
|
||||||
|
[m_player setRate:0.0];
|
||||||
if (m_playerItem) {
|
if (m_playerItem) {
|
||||||
[m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY];
|
[m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY];
|
||||||
|
|
||||||
@@ -407,10 +408,12 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
|
|||||||
[m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY];
|
[m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY];
|
||||||
[m_player removeObserver:self forKeyPath:AVF_RATE_KEY];
|
[m_player removeObserver:self forKeyPath:AVF_RATE_KEY];
|
||||||
[m_player release];
|
[m_player release];
|
||||||
|
m_player = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_playerLayer) {
|
if (m_playerLayer) {
|
||||||
[m_playerLayer release];
|
[m_playerLayer release];
|
||||||
|
m_playerLayer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self unloadMedia];
|
[self unloadMedia];
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer)
|
|||||||
return QImage();
|
return QImage();
|
||||||
|
|
||||||
renderLayerToFBO(layer, fbo);
|
renderLayerToFBO(layer, fbo);
|
||||||
QImage fboImage = fbo->toImage().mirrored();
|
QImage fboImage = fbo->toImage();
|
||||||
m_glContext->doneCurrent();
|
m_glContext->doneCurrent();
|
||||||
|
|
||||||
return fboImage;
|
return fboImage;
|
||||||
@@ -204,7 +204,8 @@ void AVFVideoFrameRenderer::renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFrameb
|
|||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glOrtho(0.0f, m_targetSize.width(), m_targetSize.height(), 0.0f, 0.0f, 1.0f);
|
//Render to FBO with inverted Y
|
||||||
|
glOrtho(0.0, m_targetSize.width(), 0.0, m_targetSize.height(), 0.0, 1.0);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|||||||
@@ -182,6 +182,11 @@ void AVFVideoRendererControl::setLayer(void *playerLayer)
|
|||||||
|
|
||||||
m_playerLayer = playerLayer;
|
m_playerLayer = playerLayer;
|
||||||
|
|
||||||
|
//If there is an active surface, make sure it has been stopped so that
|
||||||
|
//we can update it's state with the new content.
|
||||||
|
if (m_surface && m_surface->isActive())
|
||||||
|
m_surface->stop();
|
||||||
|
|
||||||
//If there is no layer to render, stop scheduling updates
|
//If there is no layer to render, stop scheduling updates
|
||||||
if (m_playerLayer == 0) {
|
if (m_playerLayer == 0) {
|
||||||
m_displayLink->stop();
|
m_displayLink->stop();
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ void AVFVideoWidget::setPlayerLayer(AVPlayerLayer *layer)
|
|||||||
[nativeLayer addSublayer:m_playerLayer];
|
[nativeLayer addSublayer:m_playerLayer];
|
||||||
updatePlayerLayerBounds(this->size());
|
updatePlayerLayerBounds(this->size());
|
||||||
}
|
}
|
||||||
|
#ifdef QT_DEBUG_AVF
|
||||||
NSArray *sublayers = [nativeLayer sublayers];
|
NSArray *sublayers = [nativeLayer sublayers];
|
||||||
qDebug() << "playerlayer: " << "at z:" << [m_playerLayer zPosition]
|
qDebug() << "playerlayer: " << "at z:" << [m_playerLayer zPosition]
|
||||||
<< " frame: " << m_playerLayer.frame.size.width << "x" << m_playerLayer.frame.size.height;
|
<< " frame: " << m_playerLayer.frame.size.width << "x" << m_playerLayer.frame.size.height;
|
||||||
@@ -133,7 +133,7 @@ void AVFVideoWidget::setPlayerLayer(AVPlayerLayer *layer)
|
|||||||
<< " frame: " << layer.frame.size.width << "x" << layer.frame.size.height;
|
<< " frame: " << layer.frame.size.width << "x" << layer.frame.size.height;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ CoreAudioDeviceInfo::CoreAudioDeviceInfo(const QByteArray &device, QAudio::Mode
|
|||||||
m_deviceId = AudioDeviceID(deviceID);
|
m_deviceId = AudioDeviceID(deviceID);
|
||||||
#else //iOS
|
#else //iOS
|
||||||
m_device = device;
|
m_device = device;
|
||||||
|
if (mode == QAudio::AudioInput) {
|
||||||
|
if (CoreAudioSessionManager::instance().category() != CoreAudioSessionManager::PlayAndRecord) {
|
||||||
|
CoreAudioSessionManager::instance().setCategory(CoreAudioSessionManager::PlayAndRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +135,11 @@ bool CoreAudioDeviceInfo::isFormatSupported(const QAudioFormat &format) const
|
|||||||
{
|
{
|
||||||
CoreAudioDeviceInfo *self = const_cast<CoreAudioDeviceInfo*>(this);
|
CoreAudioDeviceInfo *self = const_cast<CoreAudioDeviceInfo*>(this);
|
||||||
|
|
||||||
|
//Sample rates are more of a suggestion with CoreAudio so as long as we get a
|
||||||
|
//sane value then we can likely use it.
|
||||||
return format.isValid()
|
return format.isValid()
|
||||||
&& format.codec() == QString::fromLatin1("audio/pcm")
|
&& format.codec() == QString::fromLatin1("audio/pcm")
|
||||||
&& self->supportedSampleRates().contains(format.sampleRate())
|
&& format.sampleRate() > 0
|
||||||
&& self->supportedChannelCounts().contains(format.channelCount())
|
&& self->supportedChannelCounts().contains(format.channelCount())
|
||||||
&& self->supportedSampleSizes().contains(format.sampleSize());
|
&& self->supportedSampleSizes().contains(format.sampleSize());
|
||||||
}
|
}
|
||||||
@@ -168,8 +175,9 @@ QList<int> CoreAudioDeviceInfo::supportedSampleRates()
|
|||||||
AudioValueRange* vr = new AudioValueRange[pc];
|
AudioValueRange* vr = new AudioValueRange[pc];
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(m_deviceId, &availableNominalSampleRatesAddress, 0, NULL, &propSize, vr) == noErr) {
|
if (AudioObjectGetPropertyData(m_deviceId, &availableNominalSampleRatesAddress, 0, NULL, &propSize, vr) == noErr) {
|
||||||
for (int i = 0; i < pc; ++i)
|
for (int i = 0; i < pc; ++i) {
|
||||||
sampleRates << vr[i].mMaximum;
|
sampleRates << vr[i].mMinimum << vr[i].mMaximum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete vr;
|
delete vr;
|
||||||
@@ -324,7 +332,7 @@ QByteArray CoreAudioDeviceInfo::defaultOutputDevice()
|
|||||||
#if defined(Q_OS_OSX)
|
#if defined(Q_OS_OSX)
|
||||||
AudioDeviceID audioDevice;
|
AudioDeviceID audioDevice;
|
||||||
UInt32 size = sizeof(audioDevice);
|
UInt32 size = sizeof(audioDevice);
|
||||||
AudioObjectPropertyAddress defaultOutputDevicePropertyAddress = { kAudioHardwarePropertyDefaultInputDevice,
|
AudioObjectPropertyAddress defaultOutputDevicePropertyAddress = { kAudioHardwarePropertyDefaultOutputDevice,
|
||||||
kAudioObjectPropertyScopeGlobal,
|
kAudioObjectPropertyScopeGlobal,
|
||||||
kAudioObjectPropertyElementMaster };
|
kAudioObjectPropertyElementMaster };
|
||||||
|
|
||||||
@@ -360,10 +368,15 @@ QList<QByteArray> CoreAudioDeviceInfo::availableDevices(QAudio::Mode mode)
|
|||||||
AudioDeviceID* audioDevices = new AudioDeviceID[dc];
|
AudioDeviceID* audioDevices = new AudioDeviceID[dc];
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &audioDevicesPropertyAddress, 0, NULL, &propSize, audioDevices) == noErr) {
|
if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &audioDevicesPropertyAddress, 0, NULL, &propSize, audioDevices) == noErr) {
|
||||||
|
QByteArray defaultDevice = (mode == QAudio::AudioOutput) ? defaultOutputDevice() : defaultInputDevice();
|
||||||
for (int i = 0; i < dc; ++i) {
|
for (int i = 0; i < dc; ++i) {
|
||||||
QByteArray info = get_device_info(audioDevices[i], mode);
|
QByteArray info = get_device_info(audioDevices[i], mode);
|
||||||
if (!info.isNull())
|
if (!info.isNull()) {
|
||||||
devices << info;
|
if (info == defaultDevice)
|
||||||
|
devices.prepend(info);
|
||||||
|
else
|
||||||
|
devices << info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +384,12 @@ QList<QByteArray> CoreAudioDeviceInfo::availableDevices(QAudio::Mode mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else //iOS
|
#else //iOS
|
||||||
|
if (mode == QAudio::AudioInput) {
|
||||||
|
if (CoreAudioSessionManager::instance().category() != CoreAudioSessionManager::PlayAndRecord) {
|
||||||
|
CoreAudioSessionManager::instance().setCategory(CoreAudioSessionManager::PlayAndRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CoreAudioSessionManager::instance().setActive(true);
|
CoreAudioSessionManager::instance().setActive(true);
|
||||||
|
|
||||||
if (mode == QAudio::AudioOutput)
|
if (mode == QAudio::AudioOutput)
|
||||||
|
|||||||
@@ -47,6 +47,10 @@
|
|||||||
# include <CoreServices/CoreServices.h>
|
# include <CoreServices/CoreServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_IOS)
|
||||||
|
# include "coreaudiosessionmanager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QtMultimedia/private/qaudiohelpers_p.h>
|
#include <QtMultimedia/private/qaudiohelpers_p.h>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
# include <CoreServices/CoreServices.h>
|
# include <CoreServices/CoreServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_IOS)
|
||||||
|
# include <QtMultimedia/private/qaudiohelpers_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static const int DEFAULT_BUFFER_SIZE = 8 * 1024;
|
static const int DEFAULT_BUFFER_SIZE = 8 * 1024;
|
||||||
@@ -430,13 +434,23 @@ QAudioFormat CoreAudioOutput::format() const
|
|||||||
void CoreAudioOutput::setVolume(qreal volume)
|
void CoreAudioOutput::setVolume(qreal volume)
|
||||||
{
|
{
|
||||||
const qreal normalizedVolume = qBound(qreal(0.0), volume, qreal(1.0));
|
const qreal normalizedVolume = qBound(qreal(0.0), volume, qreal(1.0));
|
||||||
m_cachedVolume = normalizedVolume;
|
|
||||||
if (!m_isOpen) {
|
if (!m_isOpen) {
|
||||||
|
m_cachedVolume = normalizedVolume;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: actually set the output volume here
|
#if defined(Q_OS_OSX)
|
||||||
//To set the output volume you need a handle to the mixer unit
|
//on OS X the volume can be set directly on the AudioUnit
|
||||||
|
if (AudioUnitSetParameter(m_audioUnit,
|
||||||
|
kHALOutputParam_Volume,
|
||||||
|
kAudioUnitScope_Global,
|
||||||
|
0 /* bus */,
|
||||||
|
(float)normalizedVolume,
|
||||||
|
0) == noErr)
|
||||||
|
m_cachedVolume = normalizedVolume;
|
||||||
|
#else
|
||||||
|
m_cachedVolume = normalizedVolume;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal CoreAudioOutput::volume() const
|
qreal CoreAudioOutput::volume() const
|
||||||
@@ -497,6 +511,17 @@ OSStatus CoreAudioOutput::renderCallback(void *inRefCon, AudioUnitRenderActionFl
|
|||||||
if (framesRead > 0) {
|
if (framesRead > 0) {
|
||||||
ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
|
ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
|
||||||
d->m_totalFrames += framesRead;
|
d->m_totalFrames += framesRead;
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
// on iOS we have to adjust the sound volume ourselves
|
||||||
|
if (!qFuzzyCompare(d->m_cachedVolume, qreal(1.0f))) {
|
||||||
|
QAudioHelperInternal::qMultiplySamples(d->m_cachedVolume,
|
||||||
|
d->m_audioFormat,
|
||||||
|
ioData->mBuffers[0].mData, /* input */
|
||||||
|
ioData->mBuffers[0].mData, /* output */
|
||||||
|
ioData->mBuffers[0].mDataByteSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ioData->mBuffers[0].mDataByteSize = 0;
|
ioData->mBuffers[0].mDataByteSize = 0;
|
||||||
|
|||||||
@@ -216,7 +216,8 @@ CoreAudioSessionManager::CoreAudioSessionManager() :
|
|||||||
{
|
{
|
||||||
m_sessionObserver = [[CoreAudioSessionObserver alloc] initWithAudioSessionManager:this];
|
m_sessionObserver = [[CoreAudioSessionObserver alloc] initWithAudioSessionManager:this];
|
||||||
setActive(true);
|
setActive(true);
|
||||||
setCategory(CoreAudioSessionManager::PlayAndRecord, CoreAudioSessionManager::MixWithOthers);
|
//set default category to just Playback and only switch if we need more permissions
|
||||||
|
setCategory(CoreAudioSessionManager::Playback, CoreAudioSessionManager::MixWithOthers);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreAudioSessionManager::~CoreAudioSessionManager()
|
CoreAudioSessionManager::~CoreAudioSessionManager()
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringL
|
|||||||
|
|
||||||
void DSVideoDeviceControl::setSelectedDevice(int index)
|
void DSVideoDeviceControl::setSelectedDevice(int index)
|
||||||
{
|
{
|
||||||
if (index >= 0 && index <= m_devices.count()) {
|
if (index >= 0 && index < m_devices.count()) {
|
||||||
if (m_session) {
|
if (m_session) {
|
||||||
QString device = m_devices.at(index);
|
QString device = m_devices.at(index);
|
||||||
if (device.startsWith("ds:"))
|
if (device.startsWith("ds:"))
|
||||||
|
|||||||
@@ -107,6 +107,20 @@ QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateDevices();
|
||||||
|
|
||||||
|
return m_defaultCameraDevice;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||||
@@ -140,10 +154,13 @@ QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByt
|
|||||||
|
|
||||||
void DSServicePlugin::updateDevices() const
|
void DSServicePlugin::updateDevices() const
|
||||||
{
|
{
|
||||||
|
m_defaultCameraDevice.clear();
|
||||||
DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
|
DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
|
||||||
|
|
||||||
if (m_cameraDevices.isEmpty()) {
|
if (m_cameraDevices.isEmpty()) {
|
||||||
qWarning() << "No camera devices found";
|
qWarning() << "No camera devices found";
|
||||||
|
} else {
|
||||||
|
m_defaultCameraDevice = m_cameraDevices.first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ QT_USE_NAMESPACE
|
|||||||
class DSServicePlugin
|
class DSServicePlugin
|
||||||
: public QMediaServiceProviderPlugin
|
: public QMediaServiceProviderPlugin
|
||||||
, public QMediaServiceSupportedDevicesInterface
|
, public QMediaServiceSupportedDevicesInterface
|
||||||
|
, public QMediaServiceDefaultDeviceInterface
|
||||||
, public QMediaServiceFeaturesInterface
|
, public QMediaServiceFeaturesInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
// The player service provided by the WMF-plugin should preferably be used.
|
// The player service provided by the WMF-plugin should preferably be used.
|
||||||
// DirectShow should then only provide the camera (see QTBUG-29172, QTBUG-29175).
|
// DirectShow should then only provide the camera (see QTBUG-29172, QTBUG-29175).
|
||||||
@@ -68,6 +70,7 @@ public:
|
|||||||
|
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const;
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QList<QByteArray> devices(const QByteArray &service) const;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||||
|
|
||||||
@@ -75,6 +78,7 @@ private:
|
|||||||
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
#ifdef QMEDIA_DIRECTSHOW_CAMERA
|
||||||
void updateDevices() const;
|
void updateDevices() const;
|
||||||
|
|
||||||
|
mutable QByteArray m_defaultCameraDevice;
|
||||||
mutable QList<QByteArray> m_cameraDevices;
|
mutable QList<QByteArray> m_cameraDevices;
|
||||||
mutable QStringList m_cameraDescriptions;
|
mutable QStringList m_cameraDescriptions;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -198,11 +198,13 @@ QVariant CameraBinMetaData::metaData(const QString &key) const
|
|||||||
void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value)
|
void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value)
|
||||||
{
|
{
|
||||||
QVariant correctedValue = value;
|
QVariant correctedValue = value;
|
||||||
if (key == QMediaMetaData::Orientation) {
|
if (value.isValid()) {
|
||||||
correctedValue = toGStreamerOrientation(value);
|
if (key == QMediaMetaData::Orientation) {
|
||||||
} else if (key == QMediaMetaData::GPSSpeed) {
|
correctedValue = toGStreamerOrientation(value);
|
||||||
// kilometers per hour to meters per second.
|
} else if (key == QMediaMetaData::GPSSpeed) {
|
||||||
correctedValue = (value.toDouble() * 1000) / 3600;
|
// kilometers per hour to meters per second.
|
||||||
|
correctedValue = (value.toDouble() * 1000) / 3600;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
||||||
@@ -211,9 +213,12 @@ void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value)
|
|||||||
if (qt_gstreamerMetaDataKeys[i].key == key) {
|
if (qt_gstreamerMetaDataKeys[i].key == key) {
|
||||||
const char *name = qt_gstreamerMetaDataKeys[i].token;
|
const char *name = qt_gstreamerMetaDataKeys[i].token;
|
||||||
|
|
||||||
correctedValue.convert(qt_gstreamerMetaDataKeys[i].type);
|
if (correctedValue.isValid()) {
|
||||||
|
correctedValue.convert(qt_gstreamerMetaDataKeys[i].type);
|
||||||
m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue);
|
m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue);
|
||||||
|
} else {
|
||||||
|
m_values.remove(QByteArray::fromRawData(name, qstrlen(name)));
|
||||||
|
}
|
||||||
|
|
||||||
emit QMetaDataWriterControl::metaDataChanged();
|
emit QMetaDataWriterControl::metaDataChanged();
|
||||||
emit metaDataChanged(m_values);
|
emit metaDataChanged(m_values);
|
||||||
|
|||||||
@@ -90,6 +90,18 @@ QMediaServiceProviderHint::Features CameraBinServicePlugin::supportedFeatures(
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray CameraBinServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateDevices();
|
||||||
|
|
||||||
|
return m_defaultCameraDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
@@ -126,6 +138,7 @@ QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const
|
|||||||
|
|
||||||
void CameraBinServicePlugin::updateDevices() const
|
void CameraBinServicePlugin::updateDevices() const
|
||||||
{
|
{
|
||||||
|
m_defaultCameraDevice.clear();
|
||||||
m_cameraDevices.clear();
|
m_cameraDevices.clear();
|
||||||
m_cameraDescriptions.clear();
|
m_cameraDescriptions.clear();
|
||||||
|
|
||||||
@@ -167,6 +180,9 @@ void CameraBinServicePlugin::updateDevices() const
|
|||||||
}
|
}
|
||||||
::close(fd);
|
::close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_cameraDevices.isEmpty())
|
||||||
|
m_defaultCameraDevice = m_cameraDevices.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -51,10 +51,12 @@ QT_BEGIN_NAMESPACE
|
|||||||
class CameraBinServicePlugin
|
class CameraBinServicePlugin
|
||||||
: public QMediaServiceProviderPlugin
|
: public QMediaServiceProviderPlugin
|
||||||
, public QMediaServiceSupportedDevicesInterface
|
, public QMediaServiceSupportedDevicesInterface
|
||||||
|
, public QMediaServiceDefaultDeviceInterface
|
||||||
, public QMediaServiceFeaturesInterface
|
, public QMediaServiceFeaturesInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json")
|
||||||
public:
|
public:
|
||||||
@@ -63,6 +65,7 @@ public:
|
|||||||
|
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const;
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QList<QByteArray> devices(const QByteArray &service) const;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||||
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
|
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
|
||||||
@@ -70,6 +73,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void updateDevices() const;
|
void updateDevices() const;
|
||||||
|
|
||||||
|
mutable QByteArray m_defaultCameraDevice;
|
||||||
mutable QList<QByteArray> m_cameraDevices;
|
mutable QList<QByteArray> m_cameraDevices;
|
||||||
mutable QStringList m_cameraDescriptions;
|
mutable QStringList m_cameraDescriptions;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -756,6 +756,8 @@ void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
|
|||||||
GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_camerabin), GST_TYPE_TAG_SETTER);
|
GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_camerabin), GST_TYPE_TAG_SETTER);
|
||||||
GstElement *element = 0;
|
GstElement *element = 0;
|
||||||
while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
|
while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
|
||||||
|
gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
|
||||||
|
|
||||||
QMapIterator<QByteArray, QVariant> it(data);
|
QMapIterator<QByteArray, QVariant> it(data);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
|
|||||||
@@ -95,6 +95,18 @@ QMediaServiceProviderHint::Features QGstreamerCaptureServicePlugin::supportedFea
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray QGstreamerCaptureServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateDevices();
|
||||||
|
|
||||||
|
return m_defaultCameraDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
@@ -131,6 +143,7 @@ QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &servic
|
|||||||
|
|
||||||
void QGstreamerCaptureServicePlugin::updateDevices() const
|
void QGstreamerCaptureServicePlugin::updateDevices() const
|
||||||
{
|
{
|
||||||
|
m_defaultCameraDevice.clear();
|
||||||
m_cameraDevices.clear();
|
m_cameraDevices.clear();
|
||||||
m_cameraDescriptions.clear();
|
m_cameraDescriptions.clear();
|
||||||
|
|
||||||
@@ -174,6 +187,9 @@ void QGstreamerCaptureServicePlugin::updateDevices() const
|
|||||||
}
|
}
|
||||||
::close(fd);
|
::close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_cameraDevices.isEmpty())
|
||||||
|
m_defaultCameraDevice = m_cameraDevices.first();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class QGstreamerCaptureServicePlugin
|
|||||||
: public QMediaServiceProviderPlugin
|
: public QMediaServiceProviderPlugin
|
||||||
#if defined(USE_GSTREAMER_CAMERA)
|
#if defined(USE_GSTREAMER_CAMERA)
|
||||||
, public QMediaServiceSupportedDevicesInterface
|
, public QMediaServiceSupportedDevicesInterface
|
||||||
|
, public QMediaServiceDefaultDeviceInterface
|
||||||
, public QMediaServiceFeaturesInterface
|
, public QMediaServiceFeaturesInterface
|
||||||
#endif
|
#endif
|
||||||
, public QMediaServiceSupportedFormatsInterface
|
, public QMediaServiceSupportedFormatsInterface
|
||||||
@@ -60,6 +61,7 @@ class QGstreamerCaptureServicePlugin
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
#if defined(USE_GSTREAMER_CAMERA)
|
#if defined(USE_GSTREAMER_CAMERA)
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
#endif
|
#endif
|
||||||
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
|
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
|
||||||
@@ -75,6 +77,7 @@ public:
|
|||||||
#if defined(USE_GSTREAMER_CAMERA)
|
#if defined(USE_GSTREAMER_CAMERA)
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const;
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QList<QByteArray> devices(const QByteArray &service) const;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||||
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
|
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
|
||||||
@@ -87,6 +90,7 @@ private:
|
|||||||
#if defined(USE_GSTREAMER_CAMERA)
|
#if defined(USE_GSTREAMER_CAMERA)
|
||||||
void updateDevices() const;
|
void updateDevices() const;
|
||||||
|
|
||||||
|
mutable QByteArray m_defaultCameraDevice;
|
||||||
mutable QList<QByteArray> m_cameraDevices;
|
mutable QList<QByteArray> m_cameraDevices;
|
||||||
mutable QStringList m_cameraDescriptions;
|
mutable QStringList m_cameraDescriptions;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -74,6 +74,18 @@ QMediaServiceProviderHint::Features BbServicePlugin::supportedFeatures(const QBy
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray BbServicePlugin::defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
|
if (m_cameraDevices.isEmpty())
|
||||||
|
updateDevices();
|
||||||
|
|
||||||
|
return m_defaultCameraDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> BbServicePlugin::devices(const QByteArray &service) const
|
QList<QByteArray> BbServicePlugin::devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
@@ -102,10 +114,13 @@ QString BbServicePlugin::deviceDescription(const QByteArray &service, const QByt
|
|||||||
|
|
||||||
void BbServicePlugin::updateDevices() const
|
void BbServicePlugin::updateDevices() const
|
||||||
{
|
{
|
||||||
|
m_defaultCameraDevice.clear();
|
||||||
BbVideoDeviceSelectorControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
|
BbVideoDeviceSelectorControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
|
||||||
|
|
||||||
if (m_cameraDevices.isEmpty()) {
|
if (m_cameraDevices.isEmpty()) {
|
||||||
qWarning() << "No camera devices found";
|
qWarning() << "No camera devices found";
|
||||||
|
} else {
|
||||||
|
m_defaultCameraDevice = m_cameraDevices.first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,12 @@ QT_BEGIN_NAMESPACE
|
|||||||
class BbServicePlugin
|
class BbServicePlugin
|
||||||
: public QMediaServiceProviderPlugin,
|
: public QMediaServiceProviderPlugin,
|
||||||
public QMediaServiceSupportedDevicesInterface,
|
public QMediaServiceSupportedDevicesInterface,
|
||||||
|
public QMediaServiceDefaultDeviceInterface,
|
||||||
public QMediaServiceFeaturesInterface
|
public QMediaServiceFeaturesInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "blackberry_mediaservice.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "blackberry_mediaservice.json")
|
||||||
public:
|
public:
|
||||||
@@ -61,6 +63,7 @@ public:
|
|||||||
void release(QMediaService *service) Q_DECL_OVERRIDE;
|
void release(QMediaService *service) Q_DECL_OVERRIDE;
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||||
QList<QByteArray> devices(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;
|
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;
|
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) Q_DECL_OVERRIDE;
|
||||||
@@ -68,6 +71,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void updateDevices() const;
|
void updateDevices() const;
|
||||||
|
|
||||||
|
mutable QByteArray m_defaultCameraDevice;
|
||||||
mutable QList<QByteArray> m_cameraDevices;
|
mutable QList<QByteArray> m_cameraDevices;
|
||||||
mutable QStringList m_cameraDescriptions;
|
mutable QStringList m_cameraDescriptions;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ static QString errorToString(camera_error_t error)
|
|||||||
case CAMERA_EAGAIN:
|
case CAMERA_EAGAIN:
|
||||||
return QLatin1String("Camera unavailable");
|
return QLatin1String("Camera unavailable");
|
||||||
case CAMERA_EINVAL:
|
case CAMERA_EINVAL:
|
||||||
return QLatin1String("Inavlid argument");
|
return QLatin1String("Invalid argument");
|
||||||
case CAMERA_ENODEV:
|
case CAMERA_ENODEV:
|
||||||
return QLatin1String("Camera not found");
|
return QLatin1String("Camera not found");
|
||||||
case CAMERA_EMFILE:
|
case CAMERA_EMFILE:
|
||||||
|
|||||||
@@ -56,6 +56,9 @@
|
|||||||
|
|
||||||
QSGVivanteVideoMaterial::QSGVivanteVideoMaterial() :
|
QSGVivanteVideoMaterial::QSGVivanteVideoMaterial() :
|
||||||
mOpacity(1.0),
|
mOpacity(1.0),
|
||||||
|
mWidth(0),
|
||||||
|
mHeight(0),
|
||||||
|
mFormat(QVideoFrame::Format_Invalid),
|
||||||
mCurrentTexture(0)
|
mCurrentTexture(0)
|
||||||
{
|
{
|
||||||
#ifdef QT_VIVANTE_VIDEO_DEBUG
|
#ifdef QT_VIVANTE_VIDEO_DEBUG
|
||||||
@@ -147,6 +150,18 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mWidth != vF.width() || mHeight != vF.height() || mFormat != vF.pixelFormat()) {
|
||||||
|
mWidth = vF.width();
|
||||||
|
mHeight = vF.height();
|
||||||
|
mFormat = vF.pixelFormat();
|
||||||
|
for (GLuint id : mBitsToTextureMap.values()) {
|
||||||
|
#ifdef QT_VIVANTE_VIDEO_DEBUG
|
||||||
|
qDebug() << "delete texture: " << id;
|
||||||
|
#endif
|
||||||
|
glDeleteTextures(1, &id);
|
||||||
|
}
|
||||||
|
mBitsToTextureMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (vF.map(QAbstractVideoBuffer::ReadOnly)) {
|
if (vF.map(QAbstractVideoBuffer::ReadOnly)) {
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
qreal mOpacity;
|
qreal mOpacity;
|
||||||
|
|
||||||
|
int mWidth;
|
||||||
|
int mHeight;
|
||||||
|
QVideoFrame::PixelFormat mFormat;
|
||||||
|
|
||||||
QMap<const uchar*, GLuint> mBitsToTextureMap;
|
QMap<const uchar*, GLuint> mBitsToTextureMap;
|
||||||
QVideoFrame mCurrentFrame, mNextFrame;
|
QVideoFrame mCurrentFrame, mNextFrame;
|
||||||
GLuint mCurrentTexture;
|
GLuint mCurrentTexture;
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ const char *QSGVivanteVideoMaterialShader::fragmentShader() const {
|
|||||||
""
|
""
|
||||||
"void main()"
|
"void main()"
|
||||||
"{"
|
"{"
|
||||||
" gl_FragColor = texture2D( texture, qt_TexCoord ) * opacity;\n"
|
" gl_FragColor = vec4(texture2D( texture, qt_TexCoord ).rgb, 1.0) * opacity;\n"
|
||||||
"}";
|
"}";
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,16 +71,14 @@ const QMap<QVideoFrame::PixelFormat, GLenum>& QSGVivanteVideoNode::getVideoForma
|
|||||||
if (static_VideoFormat2GLFormatMap.isEmpty()) {
|
if (static_VideoFormat2GLFormatMap.isEmpty()) {
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YV12, GL_VIV_YV12);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YV12, GL_VIV_YV12);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV12, GL_VIV_NV12);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV12, GL_VIV_NV12);
|
||||||
|
|
||||||
|
|
||||||
// The following formats should work but are untested!
|
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV21, GL_VIV_NV21);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV21, GL_VIV_NV21);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_UYVY, GL_VIV_UYVY);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_UYVY, GL_VIV_UYVY);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YUYV, GL_VIV_YUY2);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YUYV, GL_VIV_YUY2);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB32, GL_RGBA);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB32, GL_BGRA_EXT);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB24, GL_RGB);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_ARGB32, GL_BGRA_EXT);
|
||||||
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_BGR32, GL_RGBA);
|
||||||
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_BGRA32, GL_RGBA);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB565, GL_RGB565);
|
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB565, GL_RGB565);
|
||||||
static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_BGRA32, GL_BGRA_EXT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_VideoFormat2GLFormatMap;
|
return static_VideoFormat2GLFormatMap;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
*imx6* {
|
config_gpu_vivante {
|
||||||
SUBDIRS += imx6
|
SUBDIRS += imx6
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1325,8 +1325,10 @@ void MFPlayerSession::setVolume(int volume)
|
|||||||
if (m_volume == volume)
|
if (m_volume == volume)
|
||||||
return;
|
return;
|
||||||
m_volume = volume;
|
m_volume = volume;
|
||||||
if (m_volumeControl)
|
|
||||||
m_volumeControl->SetMasterVolume(m_volume * 0.01f);
|
if (!m_muted)
|
||||||
|
setVolumeInternal(volume);
|
||||||
|
|
||||||
emit volumeChanged(m_volume);
|
emit volumeChanged(m_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1340,11 +1342,26 @@ void MFPlayerSession::setMuted(bool muted)
|
|||||||
if (m_muted == muted)
|
if (m_muted == muted)
|
||||||
return;
|
return;
|
||||||
m_muted = muted;
|
m_muted = muted;
|
||||||
if (m_volumeControl)
|
|
||||||
m_volumeControl->SetMute(BOOL(m_muted));
|
setVolumeInternal(muted ? 0 : m_volume);
|
||||||
|
|
||||||
emit mutedChanged(m_muted);
|
emit mutedChanged(m_muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MFPlayerSession::setVolumeInternal(int volume)
|
||||||
|
{
|
||||||
|
if (m_volumeControl) {
|
||||||
|
quint32 channelCount = 0;
|
||||||
|
if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount))
|
||||||
|
|| channelCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float scaled = volume * 0.01f;
|
||||||
|
for (quint32 i = 0; i < channelCount; ++i)
|
||||||
|
m_volumeControl->SetChannelVolume(i, scaled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int MFPlayerSession::bufferStatus()
|
int MFPlayerSession::bufferStatus()
|
||||||
{
|
{
|
||||||
if (!m_netsourceStatistics)
|
if (!m_netsourceStatistics)
|
||||||
@@ -1570,10 +1587,8 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(MFGetService(m_session, MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl)))) {
|
if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
|
||||||
m_volumeControl->SetMasterVolume(m_volume * 0.01f);
|
setVolumeInternal(m_muted ? 0 : m_volume);
|
||||||
m_volumeControl->SetMute(m_muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwCharacteristics = 0;
|
DWORD dwCharacteristics = 0;
|
||||||
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
|
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
|
||||||
@@ -1619,25 +1634,6 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
|
|||||||
break;
|
break;
|
||||||
case MEEndOfPresentationSegment:
|
case MEEndOfPresentationSegment:
|
||||||
break;
|
break;
|
||||||
case MEAudioSessionVolumeChanged:
|
|
||||||
if (m_volumeControl) {
|
|
||||||
float currentVolume = 1;
|
|
||||||
if (SUCCEEDED(m_volumeControl->GetMasterVolume(¤tVolume))) {
|
|
||||||
int scaledVolume = currentVolume * 100;
|
|
||||||
if (scaledVolume != m_volume) {
|
|
||||||
m_volume = scaledVolume;
|
|
||||||
emit volumeChanged(scaledVolume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BOOL currentMuted = FALSE;
|
|
||||||
if (SUCCEEDED(m_volumeControl->GetMute(¤tMuted))) {
|
|
||||||
if (currentMuted != BOOL(m_muted)) {
|
|
||||||
m_muted = bool(currentMuted);
|
|
||||||
emit mutedChanged(m_muted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MESessionTopologyStatus: {
|
case MESessionTopologyStatus: {
|
||||||
UINT32 status;
|
UINT32 status;
|
||||||
if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) {
|
if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) {
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ private:
|
|||||||
IMFPresentationClock *m_presentationClock;
|
IMFPresentationClock *m_presentationClock;
|
||||||
IMFRateControl *m_rateControl;
|
IMFRateControl *m_rateControl;
|
||||||
IMFRateSupport *m_rateSupport;
|
IMFRateSupport *m_rateSupport;
|
||||||
IMFSimpleAudioVolume *m_volumeControl;
|
IMFAudioStreamVolume *m_volumeControl;
|
||||||
IPropertyStore *m_netsourceStatistics;
|
IPropertyStore *m_netsourceStatistics;
|
||||||
PROPVARIANT m_varStart;
|
PROPVARIANT m_varStart;
|
||||||
UINT64 m_duration;
|
UINT64 m_duration;
|
||||||
@@ -218,6 +218,8 @@ private:
|
|||||||
int m_volume;
|
int m_volume;
|
||||||
bool m_muted;
|
bool m_muted;
|
||||||
|
|
||||||
|
void setVolumeInternal(int volume);
|
||||||
|
|
||||||
void createSession();
|
void createSession();
|
||||||
void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD);
|
void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD);
|
||||||
IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source,
|
IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source,
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ QMediaServiceProviderHint::Features WMFServicePlugin::supportedFeatures(
|
|||||||
return QMediaServiceProviderHint::Features();
|
return QMediaServiceProviderHint::Features();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray WMFServicePlugin::defaultDevice(const QByteArray &) const
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> WMFServicePlugin::devices(const QByteArray &) const
|
QList<QByteArray> WMFServicePlugin::devices(const QByteArray &) const
|
||||||
{
|
{
|
||||||
return QList<QByteArray>();
|
return QList<QByteArray>();
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ QT_USE_NAMESPACE
|
|||||||
class WMFServicePlugin
|
class WMFServicePlugin
|
||||||
: public QMediaServiceProviderPlugin
|
: public QMediaServiceProviderPlugin
|
||||||
, public QMediaServiceSupportedDevicesInterface
|
, public QMediaServiceSupportedDevicesInterface
|
||||||
|
, public QMediaServiceDefaultDeviceInterface
|
||||||
, public QMediaServiceFeaturesInterface
|
, public QMediaServiceFeaturesInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "wmf.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "wmf.json")
|
||||||
public:
|
public:
|
||||||
@@ -61,6 +63,7 @@ public:
|
|||||||
|
|
||||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const;
|
||||||
QList<QByteArray> devices(const QByteArray &service) const;
|
QList<QByteArray> devices(const QByteArray &service) const;
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -273,12 +273,22 @@ void QDeclarativeVideoOutput::_q_updateMediaObject()
|
|||||||
|
|
||||||
m_mediaObject.clear();
|
m_mediaObject.clear();
|
||||||
m_service.clear();
|
m_service.clear();
|
||||||
|
m_cameraInfo = QCameraInfo();
|
||||||
|
|
||||||
if (mediaObject) {
|
if (mediaObject) {
|
||||||
if (QMediaService *service = mediaObject->service()) {
|
if (QMediaService *service = mediaObject->service()) {
|
||||||
if (createBackend(service)) {
|
if (createBackend(service)) {
|
||||||
m_service = service;
|
m_service = service;
|
||||||
m_mediaObject = mediaObject;
|
m_mediaObject = mediaObject;
|
||||||
|
const QCamera *camera = qobject_cast<const QCamera *>(mediaObject);
|
||||||
|
if (camera) {
|
||||||
|
m_cameraInfo = QCameraInfo(*camera);
|
||||||
|
|
||||||
|
// The camera position and orientation need to be taken into account for
|
||||||
|
// the viewport auto orientation
|
||||||
|
if (m_autoOrientation)
|
||||||
|
_q_screenOrientationChanged(m_screenOrientationHandler->currentOrientation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,7 +385,21 @@ void QDeclarativeVideoOutput::_q_updateGeometry()
|
|||||||
|
|
||||||
void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation)
|
void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation)
|
||||||
{
|
{
|
||||||
setOrientation(orientation);
|
// If the source is a camera, take into account its sensor position and orientation
|
||||||
|
if (!m_cameraInfo.isNull()) {
|
||||||
|
switch (m_cameraInfo.position()) {
|
||||||
|
case QCamera::FrontFace:
|
||||||
|
// Front facing cameras are flipped horizontally, compensate the mirror
|
||||||
|
orientation += (360 - m_cameraInfo.orientation());
|
||||||
|
break;
|
||||||
|
case QCamera::BackFace:
|
||||||
|
default:
|
||||||
|
orientation += m_cameraInfo.orientation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setOrientation(orientation % 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
#include <qcameracapturedestinationcontrol.h>
|
#include <qcameracapturedestinationcontrol.h>
|
||||||
#include <qmediaservice.h>
|
#include <qmediaservice.h>
|
||||||
#include <qcamera.h>
|
#include <qcamera.h>
|
||||||
|
#include <qcamerainfo.h>
|
||||||
#include <qcameraimagecapture.h>
|
#include <qcameraimagecapture.h>
|
||||||
#include <qvideorenderercontrol.h>
|
#include <qvideorenderercontrol.h>
|
||||||
#include <private/qmediaserviceprovider_p.h>
|
#include <private/qmediaserviceprovider_p.h>
|
||||||
@@ -82,7 +83,10 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void testAvailableDevices();
|
void testAvailableDevices();
|
||||||
void testDeviceDescription();
|
void testDeviceDescription();
|
||||||
|
void testCameraInfo();
|
||||||
void testCtorWithDevice();
|
void testCtorWithDevice();
|
||||||
|
void testCtorWithCameraInfo();
|
||||||
|
void testCtorWithPosition();
|
||||||
|
|
||||||
void testCameraStates();
|
void testCameraStates();
|
||||||
void testCaptureMode();
|
void testCaptureMode();
|
||||||
@@ -126,6 +130,23 @@ void tst_QCameraBackend::testDeviceDescription()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QCameraBackend::testCameraInfo()
|
||||||
|
{
|
||||||
|
int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
QCOMPARE(cameras.count(), deviceCount);
|
||||||
|
if (cameras.isEmpty()) {
|
||||||
|
QVERIFY(QCameraInfo::defaultCamera().isNull());
|
||||||
|
QSKIP("Camera selection is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const QCameraInfo &info, cameras) {
|
||||||
|
QVERIFY(!info.deviceName().isEmpty());
|
||||||
|
QVERIFY(!info.description().isEmpty());
|
||||||
|
QVERIFY(info.orientation() % 90 == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QCameraBackend::testCtorWithDevice()
|
void tst_QCameraBackend::testCtorWithDevice()
|
||||||
{
|
{
|
||||||
if (QCamera::availableDevices().isEmpty())
|
if (QCamera::availableDevices().isEmpty())
|
||||||
@@ -142,6 +163,58 @@ void tst_QCameraBackend::testCtorWithDevice()
|
|||||||
delete camera;
|
delete camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QCameraBackend::testCtorWithCameraInfo()
|
||||||
|
{
|
||||||
|
if (QCameraInfo::availableCameras().isEmpty())
|
||||||
|
QSKIP("Camera selection not supported");
|
||||||
|
|
||||||
|
{
|
||||||
|
QCameraInfo info = QCameraInfo::defaultCamera();
|
||||||
|
QCamera camera(info);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(QCameraInfo(camera), info);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QCameraInfo info = QCameraInfo::availableCameras().first();
|
||||||
|
QCamera camera(info);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(QCameraInfo(camera), info);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// loading an invalid CameraInfo should fail
|
||||||
|
QCamera *camera = new QCamera(QCameraInfo());
|
||||||
|
QCOMPARE(camera->error(), QCamera::ServiceMissingError);
|
||||||
|
QVERIFY(QCameraInfo(*camera).isNull());
|
||||||
|
delete camera;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// loading non existing camera should fail
|
||||||
|
QCamera camera(QCameraInfo(QUuid::createUuid().toByteArray()));
|
||||||
|
QCOMPARE(camera.error(), QCamera::ServiceMissingError);
|
||||||
|
QVERIFY(QCameraInfo(camera).isNull());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraBackend::testCtorWithPosition()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QCamera camera(QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QCamera camera(QCamera::FrontFace);
|
||||||
|
// even if no camera is available at this position, it should not fail
|
||||||
|
// and load the default camera
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QCamera camera(QCamera::BackFace);
|
||||||
|
// even if no camera is available at this position, it should not fail
|
||||||
|
// and load the default camera
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QCameraBackend::testCameraStates()
|
void tst_QCameraBackend::testCameraStates()
|
||||||
{
|
{
|
||||||
QCamera camera;
|
QCamera camera;
|
||||||
@@ -283,7 +356,7 @@ void tst_QCameraBackend::testCameraCapture()
|
|||||||
|
|
||||||
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
||||||
QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
|
QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
|
||||||
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
|
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)));
|
||||||
|
|
||||||
imageCapture.capture();
|
imageCapture.capture();
|
||||||
QTRY_COMPARE(errorSignal.size(), 1);
|
QTRY_COMPARE(errorSignal.size(), 1);
|
||||||
@@ -354,7 +427,7 @@ void tst_QCameraBackend::testCaptureToBuffer()
|
|||||||
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
||||||
QSignalSpy imageAvailableSignal(&imageCapture, SIGNAL(imageAvailable(int,QVideoFrame)));
|
QSignalSpy imageAvailableSignal(&imageCapture, SIGNAL(imageAvailable(int,QVideoFrame)));
|
||||||
QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
|
QSignalSpy savedSignal(&imageCapture, SIGNAL(imageSaved(int,QString)));
|
||||||
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
|
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)));
|
||||||
|
|
||||||
camera.start();
|
camera.start();
|
||||||
QTRY_VERIFY(imageCapture.isReadyForCapture());
|
QTRY_VERIFY(imageCapture.isReadyForCapture());
|
||||||
|
|||||||
@@ -736,9 +736,9 @@ void tst_QMediaPlayerBackend::probes()
|
|||||||
QAudioProbe *audioProbe = new QAudioProbe;
|
QAudioProbe *audioProbe = new QAudioProbe;
|
||||||
|
|
||||||
ProbeDataHandler probeHandler;
|
ProbeDataHandler probeHandler;
|
||||||
connect(videoProbe, SIGNAL(videoFrameProbed(const QVideoFrame&)), &probeHandler, SLOT(processFrame(QVideoFrame)));
|
connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), &probeHandler, SLOT(processFrame(QVideoFrame)));
|
||||||
connect(videoProbe, SIGNAL(flush()), &probeHandler, SLOT(flushVideo()));
|
connect(videoProbe, SIGNAL(flush()), &probeHandler, SLOT(flushVideo()));
|
||||||
connect(audioProbe, SIGNAL(audioBufferProbed(const QAudioBuffer&)), &probeHandler, SLOT(processBuffer(QAudioBuffer)));
|
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), &probeHandler, SLOT(processBuffer(QAudioBuffer)));
|
||||||
connect(audioProbe, SIGNAL(flush()), &probeHandler, SLOT(flushAudio()));
|
connect(audioProbe, SIGNAL(flush()), &probeHandler, SLOT(flushAudio()));
|
||||||
|
|
||||||
QVERIFY(videoProbe->setSource(player));
|
QVERIFY(videoProbe->setSource(player));
|
||||||
@@ -762,8 +762,8 @@ void tst_QMediaPlayerBackend::playlist()
|
|||||||
{
|
{
|
||||||
QMediaPlayer player;
|
QMediaPlayer player;
|
||||||
|
|
||||||
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(const QMediaContent&)));
|
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
|
||||||
QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(const QMediaContent&)));
|
QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent)));
|
||||||
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
|
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
|
||||||
QSignalSpy errorSpy(&player, SIGNAL(error(QMediaPlayer::Error)));
|
QSignalSpy errorSpy(&player, SIGNAL(error(QMediaPlayer::Error)));
|
||||||
|
|
||||||
|
|||||||
@@ -152,16 +152,86 @@ void tst_QSoundEffect::testLooping()
|
|||||||
|
|
||||||
sound->setLoopCount(5);
|
sound->setLoopCount(5);
|
||||||
sound->setVolume(0.1f);
|
sound->setVolume(0.1f);
|
||||||
QCOMPARE(sound->loopCount(),5);
|
QCOMPARE(sound->loopCount(), 5);
|
||||||
QCOMPARE(readSignal_Count.count(),1);
|
QCOMPARE(readSignal_Count.count(), 1);
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 0);
|
||||||
|
|
||||||
sound->play();
|
sound->play();
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 5);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 1);
|
||||||
|
|
||||||
// test.wav is about 200ms, wait until it has finished playing 5 times
|
// test.wav is about 200ms, wait until it has finished playing 5 times
|
||||||
QTestEventLoop::instance().enterLoop(3);
|
QTestEventLoop::instance().enterLoop(3);
|
||||||
|
|
||||||
QTRY_COMPARE(sound->loopsRemaining(), 0);
|
QTRY_COMPARE(sound->loopsRemaining(), 0);
|
||||||
QCOMPARE(readSignal_Remaining.count(),5);
|
QVERIFY(readSignal_Remaining.count() >= 6);
|
||||||
|
QTRY_VERIFY(!sound->isPlaying());
|
||||||
|
|
||||||
|
// QTBUG-36643 (setting the loop count while playing should work)
|
||||||
|
{
|
||||||
|
readSignal_Count.clear();
|
||||||
|
readSignal_Remaining.clear();
|
||||||
|
|
||||||
|
sound->setLoopCount(30);
|
||||||
|
QCOMPARE(sound->loopCount(), 30);
|
||||||
|
QCOMPARE(readSignal_Count.count(), 1);
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 0);
|
||||||
|
|
||||||
|
sound->play();
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 30);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 1);
|
||||||
|
|
||||||
|
// wait for the sound to be played several times
|
||||||
|
QTRY_COMPARE(sound->loopsRemaining(), 20);
|
||||||
|
QVERIFY(readSignal_Remaining.count() >= 10);
|
||||||
|
readSignal_Count.clear();
|
||||||
|
readSignal_Remaining.clear();
|
||||||
|
|
||||||
|
// change the loop count while playing
|
||||||
|
sound->setLoopCount(5);
|
||||||
|
QCOMPARE(sound->loopCount(), 5);
|
||||||
|
QCOMPARE(readSignal_Count.count(), 1);
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 5);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 1);
|
||||||
|
|
||||||
|
// wait for all the loops to be completed
|
||||||
|
QTRY_COMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QVERIFY(readSignal_Remaining.count() >= 6);
|
||||||
|
QTRY_VERIFY(!sound->isPlaying());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
readSignal_Count.clear();
|
||||||
|
readSignal_Remaining.clear();
|
||||||
|
|
||||||
|
sound->setLoopCount(QSoundEffect::Infinite);
|
||||||
|
QCOMPARE(sound->loopCount(), int(QSoundEffect::Infinite));
|
||||||
|
QCOMPARE(readSignal_Count.count(), 1);
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 0);
|
||||||
|
|
||||||
|
sound->play();
|
||||||
|
QCOMPARE(sound->loopsRemaining(), int(QSoundEffect::Infinite));
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 1);
|
||||||
|
|
||||||
|
QTest::qWait(1500);
|
||||||
|
QVERIFY(sound->isPlaying());
|
||||||
|
readSignal_Count.clear();
|
||||||
|
readSignal_Remaining.clear();
|
||||||
|
|
||||||
|
// Setting the loop count to 0 should play it one last time
|
||||||
|
sound->setLoopCount(0);
|
||||||
|
QCOMPARE(sound->loopCount(), 1);
|
||||||
|
QCOMPARE(readSignal_Count.count(), 1);
|
||||||
|
QCOMPARE(sound->loopsRemaining(), 1);
|
||||||
|
QCOMPARE(readSignal_Remaining.count(), 1);
|
||||||
|
|
||||||
|
QTRY_COMPARE(sound->loopsRemaining(), 0);
|
||||||
|
QVERIFY(readSignal_Remaining.count() >= 2);
|
||||||
|
QTRY_VERIFY(!sound->isPlaying());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QSoundEffect::testVolume()
|
void tst_QSoundEffect::testVolume()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ SUBDIRS += \
|
|||||||
qaudioformat \
|
qaudioformat \
|
||||||
qaudionamespace \
|
qaudionamespace \
|
||||||
qcamera \
|
qcamera \
|
||||||
|
qcamerainfo \
|
||||||
qcameraimagecapture \
|
qcameraimagecapture \
|
||||||
qmediabindableinterface \
|
qmediabindableinterface \
|
||||||
qmediacontainercontrol \
|
qmediacontainercontrol \
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#include <qcameracapturedestinationcontrol.h>
|
#include <qcameracapturedestinationcontrol.h>
|
||||||
#include <qmediaservice.h>
|
#include <qmediaservice.h>
|
||||||
#include <qcamera.h>
|
#include <qcamera.h>
|
||||||
|
#include <qcamerainfo.h>
|
||||||
#include <qcameraimagecapture.h>
|
#include <qcameraimagecapture.h>
|
||||||
#include <qvideorenderercontrol.h>
|
#include <qvideorenderercontrol.h>
|
||||||
|
|
||||||
@@ -101,7 +102,7 @@ private slots:
|
|||||||
void testCaptureDestination();
|
void testCaptureDestination();
|
||||||
void testCaptureFormat();
|
void testCaptureFormat();
|
||||||
|
|
||||||
void testConstructorWithDefaultProvider();
|
void testConstructor();
|
||||||
void testCaptureMode();
|
void testCaptureMode();
|
||||||
void testIsCaptureModeSupported();
|
void testIsCaptureModeSupported();
|
||||||
void testRequestedLocks();
|
void testRequestedLocks();
|
||||||
@@ -330,7 +331,7 @@ void tst_QCamera::testSimpleCameraCapture()
|
|||||||
QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError);
|
QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError);
|
||||||
QVERIFY(imageCapture.errorString().isEmpty());
|
QVERIFY(imageCapture.errorString().isEmpty());
|
||||||
|
|
||||||
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
|
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)));
|
||||||
imageCapture.capture(QString::fromLatin1("/dev/null"));
|
imageCapture.capture(QString::fromLatin1("/dev/null"));
|
||||||
QCOMPARE(errorSignal.size(), 1);
|
QCOMPARE(errorSignal.size(), 1);
|
||||||
QCOMPARE(imageCapture.error(), QCameraImageCapture::NotSupportedFeatureError);
|
QCOMPARE(imageCapture.error(), QCameraImageCapture::NotSupportedFeatureError);
|
||||||
@@ -348,7 +349,7 @@ void tst_QCamera::testSimpleCameraLock()
|
|||||||
|
|
||||||
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
||||||
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
||||||
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
camera.searchAndLock();
|
camera.searchAndLock();
|
||||||
QCOMPARE(camera.lockStatus(), QCamera::Locked);
|
QCOMPARE(camera.lockStatus(), QCamera::Locked);
|
||||||
@@ -460,7 +461,7 @@ void tst_QCamera::testCameraCapture()
|
|||||||
QVERIFY(!imageCapture.isReadyForCapture());
|
QVERIFY(!imageCapture.isReadyForCapture());
|
||||||
|
|
||||||
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(int,QImage)));
|
||||||
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int, QCameraImageCapture::Error,QString)));
|
QSignalSpy errorSignal(&imageCapture, SIGNAL(error(int,QCameraImageCapture::Error,QString)));
|
||||||
|
|
||||||
imageCapture.capture(QString::fromLatin1("/dev/null"));
|
imageCapture.capture(QString::fromLatin1("/dev/null"));
|
||||||
QCOMPARE(capturedSignal.size(), 0);
|
QCOMPARE(capturedSignal.size(), 0);
|
||||||
@@ -941,7 +942,7 @@ void tst_QCamera::testCameraLockCancel()
|
|||||||
|
|
||||||
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
||||||
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
||||||
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
camera.searchAndLock();
|
camera.searchAndLock();
|
||||||
QCOMPARE(camera.lockStatus(), QCamera::Searching);
|
QCOMPARE(camera.lockStatus(), QCamera::Searching);
|
||||||
QCOMPARE(lockedSignal.count(), 0);
|
QCOMPARE(lockedSignal.count(), 0);
|
||||||
@@ -1141,6 +1142,8 @@ void tst_QCamera::testEnumDebug()
|
|||||||
qDebug() << QCamera::NoLock;
|
qDebug() << QCamera::NoLock;
|
||||||
QTest::ignoreMessage(QtDebugMsg, "QCamera::LockExposure");
|
QTest::ignoreMessage(QtDebugMsg, "QCamera::LockExposure");
|
||||||
qDebug() << QCamera::LockExposure;
|
qDebug() << QCamera::LockExposure;
|
||||||
|
QTest::ignoreMessage(QtDebugMsg, "QCamera::FrontFace ");
|
||||||
|
qDebug() << QCamera::FrontFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QCamera::testCameraControl()
|
void tst_QCamera::testCameraControl()
|
||||||
@@ -1149,13 +1152,75 @@ void tst_QCamera::testCameraControl()
|
|||||||
QVERIFY(m_cameraControl != NULL);
|
QVERIFY(m_cameraControl != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test case for constructor with default provider */
|
void tst_QCamera::testConstructor()
|
||||||
void tst_QCamera::testConstructorWithDefaultProvider()
|
|
||||||
{
|
{
|
||||||
QCamera *camera = new QCamera(0);
|
// Service doesn't implement QVideoDeviceSelectorControl
|
||||||
QVERIFY(camera != NULL);
|
provider->service = mockSimpleCameraService;
|
||||||
QCOMPARE(camera->state(), QCamera::UnloadedState);
|
|
||||||
delete camera;
|
{
|
||||||
|
QCamera camera;
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Requesting a camera at a specific position from a service which doesn't implement
|
||||||
|
// the QVideoDeviceSelectorControl should result in loading the default camera
|
||||||
|
QCamera camera(QCamera::FrontFace);
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Service implements QVideoDeviceSelectorControl
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera;
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 1); // default is 1
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera(QCameraInfo::defaultCamera());
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 1);
|
||||||
|
QCOMPARE(QCameraInfo(camera), QCameraInfo::defaultCamera());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QCameraInfo cameraInfo = QCameraInfo::availableCameras().at(0);
|
||||||
|
QCamera camera(cameraInfo);
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 0);
|
||||||
|
QCOMPARE(QCameraInfo(camera), cameraInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Requesting a camera at a position which is not available should result in
|
||||||
|
// loading the default camera
|
||||||
|
QCamera camera(QCamera::FrontFace);
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera(QCamera::BackFace);
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Should load the default camera when UnspecifiedPosition is requested
|
||||||
|
QCamera camera(QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(camera.availability(), QMultimedia::Available);
|
||||||
|
QCOMPARE(camera.error(), QCamera::NoError);
|
||||||
|
QCOMPARE(mockCameraService->mockVideoDeviceSelectorControl->selectedDevice(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* captureModeChanged Signal test case. */
|
/* captureModeChanged Signal test case. */
|
||||||
@@ -1257,8 +1322,8 @@ void tst_QCamera::testSearchAndLockWithLockTypes()
|
|||||||
/* Spy the signals */
|
/* Spy the signals */
|
||||||
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
||||||
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
||||||
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
/* search and lock the camera with QCamera::LockExposure and verify if the signal is emitted correctly */
|
/* search and lock the camera with QCamera::LockExposure and verify if the signal is emitted correctly */
|
||||||
camera.searchAndLock(QCamera::LockExposure);
|
camera.searchAndLock(QCamera::LockExposure);
|
||||||
@@ -1292,8 +1357,8 @@ void tst_QCamera::testUnlockWithType()
|
|||||||
/* Spy the signal */
|
/* Spy the signal */
|
||||||
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
QSignalSpy lockedSignal(&camera, SIGNAL(locked()));
|
||||||
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
QSignalSpy lockFailedSignal(&camera, SIGNAL(lockFailed()));
|
||||||
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignal(&camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
/* lock the camera with QCamera::LockExposure and Verify if the signal is emitted correctly */
|
/* lock the camera with QCamera::LockExposure and Verify if the signal is emitted correctly */
|
||||||
camera.searchAndLock(QCamera::LockExposure);
|
camera.searchAndLock(QCamera::LockExposure);
|
||||||
@@ -1373,7 +1438,7 @@ void tst_QCamera::testLockStatusChangedWithTypesSignal()
|
|||||||
QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
|
QCOMPARE(camera.lockStatus(), QCamera::Unlocked);
|
||||||
|
|
||||||
/* Spy the signal lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason) */
|
/* Spy the signal lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason) */
|
||||||
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
/* Lock the camera with type QCamera::LockExposure */
|
/* Lock the camera with type QCamera::LockExposure */
|
||||||
camera.searchAndLock(QCamera::LockExposure);
|
camera.searchAndLock(QCamera::LockExposure);
|
||||||
@@ -1519,7 +1584,7 @@ void tst_QCamera::testLockChangeReason()
|
|||||||
|
|
||||||
QCamera camera;
|
QCamera camera;
|
||||||
|
|
||||||
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus, QCamera::LockChangeReason)));
|
QSignalSpy lockStatusChangedSignalWithType(&camera, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
|
||||||
|
|
||||||
/* Set the lockChangeReason */
|
/* Set the lockChangeReason */
|
||||||
service.mockLocksControl->setLockChangeReason(QCamera::LockAcquired);
|
service.mockLocksControl->setLockChangeReason(QCamera::LockAcquired);
|
||||||
@@ -1530,6 +1595,7 @@ void tst_QCamera::testLockChangeReason()
|
|||||||
QVERIFY(LockChangeReason == QCamera::LockAcquired);
|
QVERIFY(LockChangeReason == QCamera::LockAcquired);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All the enums test case for QCameraControl class*/
|
/* All the enums test case for QCameraControl class*/
|
||||||
void tst_QCamera::testEnumsOfQCameraControl()
|
void tst_QCamera::testEnumsOfQCameraControl()
|
||||||
{
|
{
|
||||||
|
|||||||
10
tests/auto/unit/qcamerainfo/qcamerainfo.pro
Normal file
10
tests/auto/unit/qcamerainfo/qcamerainfo.pro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CONFIG += testcase
|
||||||
|
TARGET = tst_qcamerainfo
|
||||||
|
|
||||||
|
QT += multimedia-private testlib
|
||||||
|
|
||||||
|
include (../qmultimedia_common/mock.pri)
|
||||||
|
include (../qmultimedia_common/mockcamera.pri)
|
||||||
|
|
||||||
|
SOURCES += tst_qcamerainfo.cpp
|
||||||
|
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
|
||||||
217
tests/auto/unit/qcamerainfo/tst_qcamerainfo.cpp
Normal file
217
tests/auto/unit/qcamerainfo/tst_qcamerainfo.cpp
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 <QtTest/QtTest>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <qcamera.h>
|
||||||
|
#include <qcamerainfo.h>
|
||||||
|
|
||||||
|
#include "mockcameraservice.h"
|
||||||
|
#include "mockmediaserviceprovider.h"
|
||||||
|
|
||||||
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
|
class tst_QCameraInfo: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void initTestCase();
|
||||||
|
void init();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void constructor();
|
||||||
|
void defaultCamera();
|
||||||
|
void availableCameras();
|
||||||
|
void equality_operators();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MockSimpleCameraService *mockSimpleCameraService;
|
||||||
|
MockCameraService *mockCameraService;
|
||||||
|
MockMediaServiceProvider *provider;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QCameraInfo::initTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::init()
|
||||||
|
{
|
||||||
|
provider = new MockMediaServiceProvider;
|
||||||
|
mockSimpleCameraService = new MockSimpleCameraService;
|
||||||
|
mockCameraService = new MockCameraService;
|
||||||
|
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
QMediaServiceProvider::setDefaultServiceProvider(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::cleanup()
|
||||||
|
{
|
||||||
|
delete provider;
|
||||||
|
delete mockCameraService;
|
||||||
|
delete mockSimpleCameraService;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::constructor()
|
||||||
|
{
|
||||||
|
// Service doesn't implement QVideoDeviceSelectorControl
|
||||||
|
// QCameraInfo should not be valid in this case
|
||||||
|
provider->service = mockSimpleCameraService;
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera;
|
||||||
|
QCameraInfo info(camera);
|
||||||
|
QVERIFY(info.isNull());
|
||||||
|
QVERIFY(info.deviceName().isEmpty());
|
||||||
|
QVERIFY(info.description().isEmpty());
|
||||||
|
QCOMPARE(info.position(), QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(info.orientation(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Service implements QVideoDeviceSelectorControl
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
|
||||||
|
{
|
||||||
|
// default camera
|
||||||
|
QCamera camera;
|
||||||
|
QCameraInfo info(camera);
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("othercamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("othercamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(info.orientation(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCamera camera("backcamera");
|
||||||
|
QCameraInfo info(camera);
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("backcamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("backcamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::BackFace);
|
||||||
|
QCOMPARE(info.orientation(), 90);
|
||||||
|
|
||||||
|
QCameraInfo info2(info);
|
||||||
|
QVERIFY(!info2.isNull());
|
||||||
|
QCOMPARE(info2.deviceName(), QStringLiteral("backcamera"));
|
||||||
|
QCOMPARE(info2.description(), QStringLiteral("backcamera desc"));
|
||||||
|
QCOMPARE(info2.position(), QCamera::BackFace);
|
||||||
|
QCOMPARE(info2.orientation(), 90);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::defaultCamera()
|
||||||
|
{
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
|
||||||
|
QCameraInfo info = QCameraInfo::defaultCamera();
|
||||||
|
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("othercamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("othercamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(info.orientation(), 0);
|
||||||
|
|
||||||
|
QCamera camera(info);
|
||||||
|
QCOMPARE(QCameraInfo(camera), info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::availableCameras()
|
||||||
|
{
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
QCOMPARE(cameras.count(), 2);
|
||||||
|
|
||||||
|
QCameraInfo info = cameras.at(0);
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("backcamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("backcamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::BackFace);
|
||||||
|
QCOMPARE(info.orientation(), 90);
|
||||||
|
|
||||||
|
info = cameras.at(1);
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("othercamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("othercamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::UnspecifiedPosition);
|
||||||
|
QCOMPARE(info.orientation(), 0);
|
||||||
|
|
||||||
|
cameras = QCameraInfo::availableCameras(QCamera::BackFace);
|
||||||
|
QCOMPARE(cameras.count(), 1);
|
||||||
|
info = cameras.at(0);
|
||||||
|
QVERIFY(!info.isNull());
|
||||||
|
QCOMPARE(info.deviceName(), QStringLiteral("backcamera"));
|
||||||
|
QCOMPARE(info.description(), QStringLiteral("backcamera desc"));
|
||||||
|
QCOMPARE(info.position(), QCamera::BackFace);
|
||||||
|
QCOMPARE(info.orientation(), 90);
|
||||||
|
|
||||||
|
cameras = QCameraInfo::availableCameras(QCamera::FrontFace);
|
||||||
|
QCOMPARE(cameras.count(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QCameraInfo::equality_operators()
|
||||||
|
{
|
||||||
|
provider->service = mockCameraService;
|
||||||
|
|
||||||
|
QCameraInfo defaultCamera = QCameraInfo::defaultCamera();
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
|
||||||
|
QVERIFY(defaultCamera == cameras.at(1));
|
||||||
|
QVERIFY(defaultCamera != cameras.at(0));
|
||||||
|
QVERIFY(cameras.at(0) != cameras.at(1));
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera(defaultCamera);
|
||||||
|
QVERIFY(QCameraInfo(camera) == defaultCamera);
|
||||||
|
QVERIFY(QCameraInfo(camera) == cameras.at(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QCamera camera(cameras.at(0));
|
||||||
|
QVERIFY(QCameraInfo(camera) == cameras.at(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN(tst_QCameraInfo)
|
||||||
|
|
||||||
|
#include "tst_qcamerainfo.moc"
|
||||||
@@ -380,7 +380,7 @@ void tst_QMediaObject::metaDataChanged()
|
|||||||
QtTestMediaObject object(&service);
|
QtTestMediaObject object(&service);
|
||||||
|
|
||||||
QSignalSpy changedSpy(&object, SIGNAL(metaDataChanged()));
|
QSignalSpy changedSpy(&object, SIGNAL(metaDataChanged()));
|
||||||
QSignalSpy changedWithValueSpy(&object, SIGNAL(metaDataChanged(QString, QVariant)));
|
QSignalSpy changedWithValueSpy(&object, SIGNAL(metaDataChanged(QString,QVariant)));
|
||||||
|
|
||||||
service.metaData.setMetaData("key", "Value");
|
service.metaData.setMetaData("key", "Value");
|
||||||
QCOMPARE(changedSpy.count(), 1);
|
QCOMPARE(changedSpy.count(), 1);
|
||||||
|
|||||||
@@ -44,12 +44,10 @@
|
|||||||
#include "../mockservice.h"
|
#include "../mockservice.h"
|
||||||
|
|
||||||
class MockServicePlugin1 : public QMediaServiceProviderPlugin,
|
class MockServicePlugin1 : public QMediaServiceProviderPlugin,
|
||||||
public QMediaServiceSupportedFormatsInterface,
|
public QMediaServiceSupportedFormatsInterface
|
||||||
public QMediaServiceSupportedDevicesInterface
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
|
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mockserviceplugin1.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mockserviceplugin1.json")
|
||||||
public:
|
public:
|
||||||
QStringList keys() const
|
QStringList keys() const
|
||||||
@@ -87,21 +85,6 @@ public:
|
|||||||
{
|
{
|
||||||
return QStringList("audio/ogg");
|
return QStringList("audio/ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> devices(const QByteArray &service) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(service);
|
|
||||||
QList<QByteArray> res;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString deviceDescription(const QByteArray &service, const QByteArray &device)
|
|
||||||
{
|
|
||||||
if (devices(service).contains(device))
|
|
||||||
return QString(device)+" description";
|
|
||||||
else
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "mockserviceplugin1.moc"
|
#include "mockserviceplugin1.moc"
|
||||||
|
|||||||
@@ -44,17 +44,22 @@
|
|||||||
#include "../mockservice.h"
|
#include "../mockservice.h"
|
||||||
|
|
||||||
class MockServicePlugin3 : public QMediaServiceProviderPlugin,
|
class MockServicePlugin3 : public QMediaServiceProviderPlugin,
|
||||||
public QMediaServiceSupportedDevicesInterface
|
public QMediaServiceSupportedDevicesInterface,
|
||||||
|
public QMediaServiceDefaultDeviceInterface,
|
||||||
|
public QMediaServiceCameraInfoInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceCameraInfoInterface)
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mockserviceplugin3.json")
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mockserviceplugin3.json")
|
||||||
public:
|
public:
|
||||||
QStringList keys() const
|
QStringList keys() const
|
||||||
{
|
{
|
||||||
return QStringList() <<
|
return QStringList() <<
|
||||||
QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) <<
|
QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) <<
|
||||||
QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE);
|
QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE) <<
|
||||||
|
QLatin1String(Q_MEDIASERVICE_CAMERA);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMediaService* create(QString const& key)
|
QMediaService* create(QString const& key)
|
||||||
@@ -70,12 +75,26 @@ public:
|
|||||||
delete service;
|
delete service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
||||||
|
return "audiosource1";
|
||||||
|
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
|
return "frontcamera";
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
QList<QByteArray> devices(const QByteArray &service) const
|
QList<QByteArray> devices(const QByteArray &service) const
|
||||||
{
|
{
|
||||||
QList<QByteArray> res;
|
QList<QByteArray> res;
|
||||||
if (service == QByteArray(Q_MEDIASERVICE_AUDIOSOURCE))
|
if (service == Q_MEDIASERVICE_AUDIOSOURCE)
|
||||||
res << "audiosource1" << "audiosource2";
|
res << "audiosource1" << "audiosource2";
|
||||||
|
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
|
res << "frontcamera";
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +105,22 @@ public:
|
|||||||
else
|
else
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QCamera::Position cameraPosition(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
if (device == "frontcamera")
|
||||||
|
return QCamera::FrontFace;
|
||||||
|
|
||||||
|
return QCamera::UnspecifiedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cameraOrientation(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
if (device == "frontcamera")
|
||||||
|
return 270;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "mockserviceplugin3.moc"
|
#include "mockserviceplugin3.moc"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"Keys": ["mockserviceplugin3"],
|
"Keys": ["mockserviceplugin3"],
|
||||||
"Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiosource"]
|
"Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiosource", "org.qt-project.qt.camera"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** 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 <qmediaserviceproviderplugin.h>
|
||||||
|
#include <qmediaservice.h>
|
||||||
|
#include "../mockservice.h"
|
||||||
|
|
||||||
|
class MockServicePlugin5 : public QMediaServiceProviderPlugin,
|
||||||
|
public QMediaServiceSupportedDevicesInterface,
|
||||||
|
public QMediaServiceDefaultDeviceInterface,
|
||||||
|
public QMediaServiceCameraInfoInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
|
||||||
|
Q_INTERFACES(QMediaServiceCameraInfoInterface)
|
||||||
|
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "mockserviceplugin5.json")
|
||||||
|
public:
|
||||||
|
QStringList keys() const
|
||||||
|
{
|
||||||
|
return QStringList() << QLatin1String(Q_MEDIASERVICE_CAMERA);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMediaService* create(QString const& key)
|
||||||
|
{
|
||||||
|
if (keys().contains(key))
|
||||||
|
return new MockMediaService("MockServicePlugin5");
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release(QMediaService *service)
|
||||||
|
{
|
||||||
|
delete service;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray defaultDevice(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
|
return "backcamera";
|
||||||
|
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QByteArray> devices(const QByteArray &service) const
|
||||||
|
{
|
||||||
|
QList<QByteArray> res;
|
||||||
|
if (service == Q_MEDIASERVICE_CAMERA)
|
||||||
|
res << "backcamera" << "somecamera";
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||||
|
{
|
||||||
|
if (devices(service).contains(device))
|
||||||
|
return QString(device)+" description";
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QCamera::Position cameraPosition(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
if (device == "backcamera")
|
||||||
|
return QCamera::BackFace;
|
||||||
|
|
||||||
|
return QCamera::UnspecifiedPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cameraOrientation(const QByteArray &device) const
|
||||||
|
{
|
||||||
|
if (device == "backcamera")
|
||||||
|
return 90;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "mockserviceplugin5.moc"
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"Keys": ["mockserviceplugin5"],
|
||||||
|
"Services": ["org.qt-project.qt.camera"]
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user