summaryrefslogtreecommitdiffstats
path: root/src/plugins/qnx/camera/bbcamerasession.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-01-12 14:22:08 +0100
committerLars Knoll <lars.knoll@qt.io>2021-01-22 07:02:55 +0000
commit98148969b112f82d2b49e77950ea5f6d8b37b8b2 (patch)
tree48fffe0533a647bb53bec7e6e33dee1b95fcd849 /src/plugins/qnx/camera/bbcamerasession.cpp
parentb947bcabfef5f0df32a4e09b55eaa581281b4edd (diff)
Get rid of plugins for MM backends
There's no need for having those in plugins and we can further remove abstractions and simplify our code if the code is directly compiled into Qt Multimedia. Change-Id: I5267a6a776375d99be8f0de4207f0288d963e620 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/plugins/qnx/camera/bbcamerasession.cpp')
-rw-r--r--src/plugins/qnx/camera/bbcamerasession.cpp1154
1 files changed, 0 insertions, 1154 deletions
diff --git a/src/plugins/qnx/camera/bbcamerasession.cpp b/src/plugins/qnx/camera/bbcamerasession.cpp
deleted file mode 100644
index 7b3974084..000000000
--- a/src/plugins/qnx/camera/bbcamerasession.cpp
+++ /dev/null
@@ -1,1154 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "bbcamerasession.h"
-
-#include "bbcameraorientationhandler.h"
-#include "bbcameraviewfindersettingscontrol.h"
-#include "windowgrabber.h"
-
-#include <QAbstractVideoSurface>
-#include <QBuffer>
-#include <QDebug>
-#include <QImage>
-#include <QUrl>
-#include <QVideoSurfaceFormat>
-#include <qmath.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-static QString errorToString(camera_error_t error)
-{
- switch (error) {
- case CAMERA_EOK:
- return QLatin1String("No error");
- case CAMERA_EAGAIN:
- return QLatin1String("Camera unavailable");
- case CAMERA_EINVAL:
- return QLatin1String("Invalid argument");
- case CAMERA_ENODEV:
- return QLatin1String("Camera not found");
- case CAMERA_EMFILE:
- return QLatin1String("File table overflow");
- case CAMERA_EBADF:
- return QLatin1String("Invalid handle passed");
- case CAMERA_EACCESS:
- return QLatin1String("No permission");
- case CAMERA_EBADR:
- return QLatin1String("Invalid file descriptor");
- case CAMERA_ENOENT:
- return QLatin1String("File or directory does not exists");
- case CAMERA_ENOMEM:
- return QLatin1String("Memory allocation failed");
- case CAMERA_EOPNOTSUPP:
- return QLatin1String("Operation not supported");
- case CAMERA_ETIMEDOUT:
- return QLatin1String("Communication timeout");
- case CAMERA_EALREADY:
- return QLatin1String("Operation already in progress");
- case CAMERA_EUNINIT:
- return QLatin1String("Camera library not initialized");
- case CAMERA_EREGFAULT:
- return QLatin1String("Callback registration failed");
- case CAMERA_EMICINUSE:
- return QLatin1String("Microphone in use already");
- case CAMERA_ENODATA:
- return QLatin1String("Data does not exist");
- case CAMERA_EBUSY:
- return QLatin1String("Camera busy");
- case CAMERA_EDESKTOPCAMERAINUSE:
- return QLatin1String("Desktop camera in use already");
- case CAMERA_ENOSPC:
- return QLatin1String("Disk is full");
- case CAMERA_EPOWERDOWN:
- return QLatin1String("Camera in power down state");
- case CAMERA_3ALOCKED:
- return QLatin1String("3A have been locked");
-// case CAMERA_EVIEWFINDERFROZEN: // not yet available in 10.2 NDK
-// return QLatin1String("Freeze flag set");
- default:
- return QLatin1String("Unknown error");
- }
-}
-
-QDebug operator<<(QDebug debug, camera_error_t error)
-{
- debug.nospace() << errorToString(error);
- return debug.space();
-}
-
-BbCameraSession::BbCameraSession(QObject *parent)
- : QObject(parent)
- , m_nativeCameraOrientation(0)
- , m_orientationHandler(new BbCameraOrientationHandler(this))
- , m_status(QCamera::UnloadedStatus)
- , m_state(QCamera::UnloadedState)
- , m_captureMode(QCamera::CaptureStillImage)
- , m_device("bb:RearCamera")
- , m_previewIsVideo(true)
- , m_surface(0)
- , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture)
- , m_lastImageCaptureId(0)
- , m_captureDestination(QCameraImageCapture::CaptureToFile)
- , m_videoState(QMediaRecorder::StoppedState)
- , m_videoStatus(QMediaRecorder::LoadedStatus)
- , m_handle(CAMERA_HANDLE_INVALID)
- , m_windowGrabber(new WindowGrabber(this))
-{
- connect(this, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyForCapture()));
- connect(this, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyForCapture()));
- connect(m_orientationHandler, SIGNAL(orientationChanged(int)), SLOT(deviceOrientationChanged(int)));
-
- connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage, int)), SLOT(viewfinderFrameGrabbed(QImage)));
-}
-
-BbCameraSession::~BbCameraSession()
-{
- stopViewFinder();
- closeCamera();
-}
-
-camera_handle_t BbCameraSession::handle() const
-{
- return m_handle;
-}
-
-QCamera::State BbCameraSession::state() const
-{
- return m_state;
-}
-
-void BbCameraSession::setState(QCamera::State state)
-{
- if (m_state == state)
- return;
-
- const QCamera::State previousState = m_state;
-
- if (previousState == QCamera::UnloadedState) {
- if (state == QCamera::LoadedState) {
- if (openCamera()) {
- m_state = state;
- }
- } else if (state == QCamera::ActiveState) {
- if (openCamera()) {
- QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection);
- m_state = state;
- }
- }
- } else if (previousState == QCamera::LoadedState) {
- if (state == QCamera::UnloadedState) {
- closeCamera();
- m_state = state;
- } else if (state == QCamera::ActiveState) {
- QMetaObject::invokeMethod(this, "applyConfiguration", Qt::QueuedConnection);
- m_state = state;
- }
- } else if (previousState == QCamera::ActiveState) {
- if (state == QCamera::LoadedState) {
- stopViewFinder();
- m_state = state;
- } else if (state == QCamera::UnloadedState) {
- stopViewFinder();
- closeCamera();
- m_state = state;
- }
- }
-
- if (m_state != previousState)
- emit stateChanged(m_state);
-}
-
-QCamera::Status BbCameraSession::status() const
-{
- return m_status;
-}
-
-QCamera::CaptureModes BbCameraSession::captureMode() const
-{
- return m_captureMode;
-}
-
-void BbCameraSession::setCaptureMode(QCamera::CaptureModes captureMode)
-{
- if (m_captureMode == captureMode)
- return;
-
- m_captureMode = captureMode;
- emit captureModeChanged(m_captureMode);
-}
-
-bool BbCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const
-{
- if (m_handle == CAMERA_HANDLE_INVALID) {
- // the camera has not been loaded yet via QCamera::load(), so
- // we open it temporarily to peek for the supported capture modes
-
- camera_unit_t unit = CAMERA_UNIT_REAR;
- if (m_device == cameraIdentifierFront())
- unit = CAMERA_UNIT_FRONT;
- else if (m_device == cameraIdentifierRear())
- unit = CAMERA_UNIT_REAR;
- else if (m_device == cameraIdentifierDesktop())
- unit = CAMERA_UNIT_DESKTOP;
-
- camera_handle_t handle;
- const camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &handle);
- if (result != CAMERA_EOK)
- return true;
-
- const bool supported = isCaptureModeSupported(handle, mode);
-
- camera_close(handle);
-
- return supported;
- } else {
- return isCaptureModeSupported(m_handle, mode);
- }
-}
-
-QByteArray BbCameraSession::cameraIdentifierFront()
-{
- return "bb:FrontCamera";
-}
-
-QByteArray BbCameraSession::cameraIdentifierRear()
-{
- return "bb:RearCamera";
-}
-
-QByteArray BbCameraSession::cameraIdentifierDesktop()
-{
- return "bb:DesktopCamera";
-}
-
-void BbCameraSession::setDevice(const QByteArray &device)
-{
- m_device = device;
-}
-
-QByteArray BbCameraSession::device() const
-{
- return m_device;
-}
-
-QAbstractVideoSurface* BbCameraSession::surface() const
-{
- return m_surface;
-}
-
-void BbCameraSession::setSurface(QAbstractVideoSurface *surface)
-{
- QMutexLocker locker(&m_surfaceMutex);
-
- if (m_surface == surface)
- return;
-
- m_surface = surface;
-}
-
-bool BbCameraSession::isReadyForCapture() const
-{
- if (m_captureMode & QCamera::CaptureStillImage)
- return (m_status == QCamera::ActiveStatus);
-
- if (m_captureMode & QCamera::CaptureVideo)
- return (m_status == QCamera::ActiveStatus);
-
- return false;
-}
-
-QCameraImageCapture::DriveMode BbCameraSession::driveMode() const
-{
- return m_captureImageDriveMode;
-}
-
-void BbCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode)
-{
- m_captureImageDriveMode = mode;
-}
-
-/**
- * A helper structure that keeps context data for image capture callbacks.
- */
-struct ImageCaptureData
-{
- int requestId;
- QString fileName;
- BbCameraSession *session;
-};
-
-static void imageCaptureShutterCallback(camera_handle_t handle, void *context)
-{
- Q_UNUSED(handle);
-
- const ImageCaptureData *data = static_cast<ImageCaptureData*>(context);
-
- // We are inside a worker thread here, so emit imageExposed inside the main thread
- QMetaObject::invokeMethod(data->session, "imageExposed", Qt::QueuedConnection,
- Q_ARG(int, data->requestId));
-}
-
-static void imageCaptureImageCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context)
-{
- Q_UNUSED(handle);
-
- QScopedPointer<ImageCaptureData> data(static_cast<ImageCaptureData*>(context));
-
- if (buffer->frametype != CAMERA_FRAMETYPE_JPEG) {
- // We are inside a worker thread here, so emit error signal inside the main thread
- QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
- Q_ARG(int, data->requestId),
- Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
- Q_ARG(QString, BbCameraSession::tr("Camera provides image in unsupported format")));
- return;
- }
-
- const QByteArray rawData((const char*)buffer->framebuf, buffer->framedesc.jpeg.bufsize);
-
- QImage image;
- const bool ok = image.loadFromData(rawData, "JPG");
- if (!ok) {
- const QString errorMessage = BbCameraSession::tr("Could not load JPEG data from frame");
- // We are inside a worker thread here, so emit error signal inside the main thread
- QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
- Q_ARG(int, data->requestId),
- Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
- Q_ARG(QString, errorMessage));
- return;
- }
-
-
- // We are inside a worker thread here, so invoke imageCaptured inside the main thread
- QMetaObject::invokeMethod(data->session, "imageCaptured", Qt::QueuedConnection,
- Q_ARG(int, data->requestId),
- Q_ARG(QImage, image),
- Q_ARG(QString, data->fileName));
-}
-
-int BbCameraSession::capture(const QString &fileName)
-{
- m_lastImageCaptureId++;
-
- if (!isReadyForCapture()) {
- emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
- return m_lastImageCaptureId;
- }
-
- if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) {
- // prepare context object for callback
- ImageCaptureData *context = new ImageCaptureData;
- context->requestId = m_lastImageCaptureId;
- context->fileName = fileName;
- context->session = this;
-
- const camera_error_t result = camera_take_photo(m_handle,
- imageCaptureShutterCallback,
- 0,
- 0,
- imageCaptureImageCallback,
- context, false);
-
- if (result != CAMERA_EOK)
- qWarning() << "Unable to take photo:" << result;
- } else {
- // TODO: implement burst mode when available in Qt API
- }
-
- return m_lastImageCaptureId;
-}
-
-void BbCameraSession::cancelCapture()
-{
- // BB10 API doesn't provide functionality for that
-}
-
-bool BbCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
-{
- // capture to buffer, file and both are supported.
- return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer);
-}
-
-QCameraImageCapture::CaptureDestinations BbCameraSession::captureDestination() const
-{
- return m_captureDestination;
-}
-
-void BbCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
-{
- if (m_captureDestination != destination) {
- m_captureDestination = destination;
- emit captureDestinationChanged(m_captureDestination);
- }
-}
-
-QList<QSize> BbCameraSession::supportedResolutions(const QImageEncoderSettings&, bool *continuous) const
-{
- if (continuous)
- *continuous = false;
-
- if (m_status == QCamera::UnloadedStatus)
- return QList<QSize>();
-
- if (m_captureMode & QCamera::CaptureStillImage) {
- return supportedResolutions(QCamera::CaptureStillImage);
- } else if (m_captureMode & QCamera::CaptureVideo) {
- return supportedResolutions(QCamera::CaptureVideo);
- }
-
- return QList<QSize>();
-}
-
-QImageEncoderSettings BbCameraSession::imageSettings() const
-{
- return m_imageEncoderSettings;
-}
-
-void BbCameraSession::setImageSettings(const QImageEncoderSettings &settings)
-{
- m_imageEncoderSettings = settings;
- if (m_imageEncoderSettings.codec().isEmpty())
- m_imageEncoderSettings.setCodec(QLatin1String("jpeg"));
-}
-
-QUrl BbCameraSession::outputLocation() const
-{
- return QUrl::fromLocalFile(m_videoOutputLocation);
-}
-
-bool BbCameraSession::setOutputLocation(const QUrl &location)
-{
- m_videoOutputLocation = location.toLocalFile();
-
- return true;
-}
-
-QMediaRecorder::State BbCameraSession::videoState() const
-{
- return m_videoState;
-}
-
-void BbCameraSession::setVideoState(QMediaRecorder::State state)
-{
- if (m_videoState == state)
- return;
-
- const QMediaRecorder::State previousState = m_videoState;
-
- if (previousState == QMediaRecorder::StoppedState) {
- if (state == QMediaRecorder::RecordingState) {
- if (startVideoRecording()) {
- m_videoState = state;
- }
- } else if (state == QMediaRecorder::PausedState) {
- // do nothing
- }
- } else if (previousState == QMediaRecorder::RecordingState) {
- if (state == QMediaRecorder::StoppedState) {
- stopVideoRecording();
- m_videoState = state;
- } else if (state == QMediaRecorder::PausedState) {
- //TODO: (pause) not supported by BB10 API yet
- }
- } else if (previousState == QMediaRecorder::PausedState) {
- if (state == QMediaRecorder::StoppedState) {
- stopVideoRecording();
- m_videoState = state;
- } else if (state == QMediaRecorder::RecordingState) {
- //TODO: (resume) not supported by BB10 API yet
- }
- }
-
- emit videoStateChanged(m_videoState);
-}
-
-QMediaRecorder::Status BbCameraSession::videoStatus() const
-{
- return m_videoStatus;
-}
-
-qint64 BbCameraSession::duration() const
-{
- return (m_videoRecordingDuration.isValid() ? m_videoRecordingDuration.elapsed() : 0);
-}
-
-void BbCameraSession::applyVideoSettings()
-{
- if (m_handle == CAMERA_HANDLE_INVALID)
- return;
-
- // apply viewfinder configuration
- const QList<QSize> videoOutputResolutions = supportedResolutions(QCamera::CaptureVideo);
-
- if (!m_videoEncoderSettings.resolution().isValid() || !videoOutputResolutions.contains(m_videoEncoderSettings.resolution()))
- m_videoEncoderSettings.setResolution(videoOutputResolutions.first());
-
- QSize viewfinderResolution;
-
- if (m_previewIsVideo) {
- // The viewfinder is responsible for encoding the video frames, so the resolutions must match.
- viewfinderResolution = m_videoEncoderSettings.resolution();
- } else {
- // The frames are encoded separately from the viewfinder, so only the aspect ratio must match.
- const QSize videoResolution = m_videoEncoderSettings.resolution();
- const qreal aspectRatio = static_cast<qreal>(videoResolution.width())/static_cast<qreal>(videoResolution.height());
-
- QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureVideo);
- std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
- for (const QSize &size : qAsConst(sizes)) {
- // search for viewfinder resolution with the same aspect ratio
- if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
- viewfinderResolution = size;
- break;
- }
- }
- }
-
- Q_ASSERT(viewfinderResolution.isValid());
-
- const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1();
- m_windowGrabber->setWindowId(windowId);
-
- const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
-
- const int rotationAngle = (360 - m_nativeCameraOrientation);
-
- camera_error_t result = CAMERA_EOK;
- result = camera_set_videovf_property(m_handle,
- CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(),
- CAMERA_IMGPROP_WIN_ID, windowId.data(),
- CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
- CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
- CAMERA_IMGPROP_ROTATION, rotationAngle);
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to apply video viewfinder settings:" << result;
- return;
- }
-
- const QSize resolution = m_videoEncoderSettings.resolution();
-
- QString videoCodec = m_videoEncoderSettings.codec();
- if (videoCodec.isEmpty())
- videoCodec = QLatin1String("h264");
-
- camera_videocodec_t cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
- if (videoCodec == QLatin1String("none"))
- cameraVideoCodec = CAMERA_VIDEOCODEC_NONE;
- else if (videoCodec == QLatin1String("avc1"))
- cameraVideoCodec = CAMERA_VIDEOCODEC_AVC1;
- else if (videoCodec == QLatin1String("h264"))
- cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
-
- qreal frameRate = m_videoEncoderSettings.frameRate();
- if (frameRate == 0) {
- const QList<qreal> frameRates = supportedFrameRates(QVideoEncoderSettings(), 0);
- if (!frameRates.isEmpty())
- frameRate = frameRates.last();
- }
-
- QString audioCodec = m_audioEncoderSettings.codec();
- if (audioCodec.isEmpty())
- audioCodec = QLatin1String("aac");
-
- camera_audiocodec_t cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
- if (audioCodec == QLatin1String("none"))
- cameraAudioCodec = CAMERA_AUDIOCODEC_NONE;
- else if (audioCodec == QLatin1String("aac"))
- cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
- else if (audioCodec == QLatin1String("raw"))
- cameraAudioCodec = CAMERA_AUDIOCODEC_RAW;
-
- result = camera_set_video_property(m_handle,
- CAMERA_IMGPROP_WIDTH, resolution.width(),
- CAMERA_IMGPROP_HEIGHT, resolution.height(),
- CAMERA_IMGPROP_ROTATION, rotationAngle,
- CAMERA_IMGPROP_VIDEOCODEC, cameraVideoCodec,
- CAMERA_IMGPROP_AUDIOCODEC, cameraAudioCodec);
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to apply video settings:" << result;
- emit videoError(QMediaRecorder::ResourceError, tr("Unable to apply video settings"));
- }
-}
-
-QList<QSize> BbCameraSession::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
-{
- Q_UNUSED(settings);
-
- if (continuous)
- *continuous = false;
-
- return supportedResolutions(QCamera::CaptureVideo);
-}
-
-QList<qreal> BbCameraSession::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
-{
- Q_UNUSED(settings);
-
- if (m_handle == CAMERA_HANDLE_INVALID)
- return QList<qreal>();
-
- int supported = 0;
- double rates[20];
- bool maxmin = false;
-
- /**
- * Since in current version of the BB10 platform the video viewfinder encodes the video frames, we use
- * the values as returned by camera_get_video_vf_framerates().
- */
- const camera_error_t result = camera_get_video_vf_framerates(m_handle, 20, &supported, rates, &maxmin);
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to retrieve supported viewfinder framerates:" << result;
- return QList<qreal>();
- }
-
- QList<qreal> frameRates;
- for (int i = 0; i < supported; ++i)
- frameRates << rates[i];
-
- if (continuous)
- *continuous = maxmin;
-
- return frameRates;
-}
-
-QVideoEncoderSettings BbCameraSession::videoSettings() const
-{
- return m_videoEncoderSettings;
-}
-
-void BbCameraSession::setVideoSettings(const QVideoEncoderSettings &settings)
-{
- m_videoEncoderSettings = settings;
-}
-
-QAudioEncoderSettings BbCameraSession::audioSettings() const
-{
- return m_audioEncoderSettings;
-}
-
-void BbCameraSession::setAudioSettings(const QAudioEncoderSettings &settings)
-{
- m_audioEncoderSettings = settings;
-}
-
-void BbCameraSession::updateReadyForCapture()
-{
- emit readyForCaptureChanged(isReadyForCapture());
-}
-
-void BbCameraSession::imageCaptured(int requestId, const QImage &rawImage, const QString &fileName)
-{
- QTransform transform;
-
- // subtract out the native rotation
- transform.rotate(m_nativeCameraOrientation);
-
- // subtract out the current device orientation
- if (m_device == cameraIdentifierRear())
- transform.rotate(360 - m_orientationHandler->orientation());
- else
- transform.rotate(m_orientationHandler->orientation());
-
- const QImage image = rawImage.transformed(transform);
-
- // Generate snap preview as downscaled image
- {
- QSize previewSize = image.size();
- int downScaleSteps = 0;
- while (previewSize.width() > 800 && downScaleSteps < 8) {
- previewSize.rwidth() /= 2;
- previewSize.rheight() /= 2;
- downScaleSteps++;
- }
-
- const QImage snapPreview = image.scaled(previewSize);
-
- emit imageCaptured(requestId, snapPreview);
- }
-
- if (m_captureDestination & QCameraImageCapture::CaptureToBuffer) {
- QVideoFrame frame(image);
-
- emit imageAvailable(requestId, frame);
- }
-
- if (m_captureDestination & QCameraImageCapture::CaptureToFile) {
- const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName,
- QCamera::CaptureStillImage,
- QLatin1String("IMG_"),
- QLatin1String("jpg"));
-
- QFile file(actualFileName);
- if (file.open(QFile::WriteOnly)) {
- if (image.save(&file, "JPG")) {
- emit imageSaved(requestId, actualFileName);
- } else {
- emit imageCaptureError(requestId, QCameraImageCapture::OutOfSpaceError, file.errorString());
- }
- } else {
- const QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName);
- emit imageCaptureError(requestId, QCameraImageCapture::ResourceError, errorMessage);
- }
- }
-}
-
-void BbCameraSession::handleVideoRecordingPaused()
-{
- //TODO: implement once BB10 API supports pausing a video
-}
-
-void BbCameraSession::handleVideoRecordingResumed()
-{
- if (m_videoStatus == QMediaRecorder::StartingStatus) {
- m_videoStatus = QMediaRecorder::RecordingStatus;
- emit videoStatusChanged(m_videoStatus);
-
- m_videoRecordingDuration.restart();
- }
-}
-
-void BbCameraSession::deviceOrientationChanged(int angle)
-{
- if (m_handle != CAMERA_HANDLE_INVALID)
- camera_set_device_orientation(m_handle, angle);
-}
-
-void BbCameraSession::handleCameraPowerUp()
-{
- stopViewFinder();
- startViewFinder();
-}
-
-void BbCameraSession::viewfinderFrameGrabbed(const QImage &image)
-{
- QTransform transform;
-
- // subtract out the native rotation
- transform.rotate(m_nativeCameraOrientation);
-
- // subtract out the current device orientation
- if (m_device == cameraIdentifierRear())
- transform.rotate(360 - m_orientationHandler->viewfinderOrientation());
- else
- transform.rotate(m_orientationHandler->viewfinderOrientation());
-
- QImage frame = image.copy().transformed(transform);
-
- QMutexLocker locker(&m_surfaceMutex);
- if (m_surface) {
- if (frame.size() != m_surface->surfaceFormat().frameSize()) {
- m_surface->stop();
- m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
- }
-
- QVideoFrame videoFrame(frame);
-
- m_surface->present(videoFrame);
- }
-}
-
-bool BbCameraSession::openCamera()
-{
- if (m_handle != CAMERA_HANDLE_INVALID) // camera is already open
- return true;
-
- m_status = QCamera::LoadingStatus;
- emit statusChanged(m_status);
-
- camera_unit_t unit = CAMERA_UNIT_REAR;
- if (m_device == cameraIdentifierFront())
- unit = CAMERA_UNIT_FRONT;
- else if (m_device == cameraIdentifierRear())
- unit = CAMERA_UNIT_REAR;
- else if (m_device == cameraIdentifierDesktop())
- unit = CAMERA_UNIT_DESKTOP;
-
- camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &m_handle);
- if (result != CAMERA_EOK) {
- m_handle = CAMERA_HANDLE_INVALID;
- m_status = QCamera::UnloadedStatus;
- emit statusChanged(m_status);
-
- qWarning() << "Unable to open camera:" << result;
- emit error(QCamera::CameraError, tr("Unable to open camera"));
- return false;
- }
-
- result = camera_get_native_orientation(m_handle, &m_nativeCameraOrientation);
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to retrieve native camera orientation:" << result;
- emit error(QCamera::CameraError, tr("Unable to retrieve native camera orientation"));
- return false;
- }
-
- m_previewIsVideo = camera_has_feature(m_handle, CAMERA_FEATURE_PREVIEWISVIDEO);
-
- m_status = QCamera::LoadedStatus;
- emit statusChanged(m_status);
-
- emit cameraOpened();
-
- return true;
-}
-
-void BbCameraSession::closeCamera()
-{
- if (m_handle == CAMERA_HANDLE_INVALID) // camera is closed already
- return;
-
- m_status = QCamera::UnloadingStatus;
- emit statusChanged(m_status);
-
- const camera_error_t result = camera_close(m_handle);
- if (result != CAMERA_EOK) {
- m_status = QCamera::LoadedStatus;
- emit statusChanged(m_status);
-
- qWarning() << "Unable to close camera:" << result;
- emit error(QCamera::CameraError, tr("Unable to close camera"));
- return;
- }
-
- m_handle = CAMERA_HANDLE_INVALID;
-
- m_status = QCamera::UnloadedStatus;
- emit statusChanged(m_status);
-}
-
-static void viewFinderStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
-{
- Q_UNUSED(handle);
-
- if (status == CAMERA_STATUS_FOCUS_CHANGE) {
- BbCameraSession *session = static_cast<BbCameraSession*>(context);
- QMetaObject::invokeMethod(session, "focusStatusChanged", Qt::QueuedConnection, Q_ARG(int, value));
- return;
- } else if (status == CAMERA_STATUS_POWERUP) {
- BbCameraSession *session = static_cast<BbCameraSession*>(context);
- QMetaObject::invokeMethod(session, "handleCameraPowerUp", Qt::QueuedConnection);
- }
-}
-
-bool BbCameraSession::startViewFinder()
-{
- m_status = QCamera::StartingStatus;
- emit statusChanged(m_status);
-
- QSize viewfinderResolution;
- camera_error_t result = CAMERA_EOK;
- if (m_captureMode & QCamera::CaptureStillImage) {
- result = camera_start_photo_viewfinder(m_handle, 0, viewFinderStatusCallback, this);
- viewfinderResolution = currentViewfinderResolution(QCamera::CaptureStillImage);
- } else if (m_captureMode & QCamera::CaptureVideo) {
- result = camera_start_video_viewfinder(m_handle, 0, viewFinderStatusCallback, this);
- viewfinderResolution = currentViewfinderResolution(QCamera::CaptureVideo);
- }
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to start viewfinder:" << result;
- return false;
- }
-
- const int angle = m_orientationHandler->viewfinderOrientation();
-
- const QSize rotatedSize = ((angle == 0 || angle == 180) ? viewfinderResolution
- : viewfinderResolution.transposed());
-
- m_surfaceMutex.lock();
- if (m_surface) {
- const bool ok = m_surface->start(QVideoSurfaceFormat(rotatedSize, QVideoFrame::Format_ARGB32));
- if (!ok)
- qWarning() << "Unable to start camera viewfinder surface";
- }
- m_surfaceMutex.unlock();
-
- m_status = QCamera::ActiveStatus;
- emit statusChanged(m_status);
-
- return true;
-}
-
-void BbCameraSession::stopViewFinder()
-{
- m_windowGrabber->stop();
-
- m_status = QCamera::StoppingStatus;
- emit statusChanged(m_status);
-
- m_surfaceMutex.lock();
- if (m_surface) {
- m_surface->stop();
- }
- m_surfaceMutex.unlock();
-
- camera_error_t result = CAMERA_EOK;
- if (m_captureMode & QCamera::CaptureStillImage)
- result = camera_stop_photo_viewfinder(m_handle);
- else if (m_captureMode & QCamera::CaptureVideo)
- result = camera_stop_video_viewfinder(m_handle);
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to stop viewfinder:" << result;
- return;
- }
-
- m_status = QCamera::LoadedStatus;
- emit statusChanged(m_status);
-}
-
-void BbCameraSession::applyConfiguration()
-{
- if (m_captureMode & QCamera::CaptureStillImage) {
- const QList<QSize> photoOutputResolutions = supportedResolutions(QCamera::CaptureStillImage);
-
- if (!m_imageEncoderSettings.resolution().isValid() || !photoOutputResolutions.contains(m_imageEncoderSettings.resolution()))
- m_imageEncoderSettings.setResolution(photoOutputResolutions.first());
-
- const QSize photoResolution = m_imageEncoderSettings.resolution();
- const qreal aspectRatio = static_cast<qreal>(photoResolution.width())/static_cast<qreal>(photoResolution.height());
-
- // apply viewfinder configuration
- QSize viewfinderResolution;
- QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureStillImage);
- std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
- for (const QSize &size : qAsConst(sizes)) {
- // search for viewfinder resolution with the same aspect ratio
- if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
- viewfinderResolution = size;
- break;
- }
- }
-
- Q_ASSERT(viewfinderResolution.isValid());
-
- const QByteArray windowId = QString().sprintf("qcamera_vf_%p", this).toLatin1();
- m_windowGrabber->setWindowId(windowId);
-
- const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
-
- camera_error_t result = camera_set_photovf_property(m_handle,
- CAMERA_IMGPROP_WIN_GROUPID, windowGroupId.data(),
- CAMERA_IMGPROP_WIN_ID, windowId.data(),
- CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
- CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
- CAMERA_IMGPROP_FORMAT, CAMERA_FRAMETYPE_NV12,
- CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation);
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to apply photo viewfinder settings:" << result;
- return;
- }
-
-
- int jpegQuality = 100;
- switch (m_imageEncoderSettings.quality()) {
- case QMultimedia::VeryLowQuality:
- jpegQuality = 20;
- break;
- case QMultimedia::LowQuality:
- jpegQuality = 40;
- break;
- case QMultimedia::NormalQuality:
- jpegQuality = 60;
- break;
- case QMultimedia::HighQuality:
- jpegQuality = 80;
- break;
- case QMultimedia::VeryHighQuality:
- jpegQuality = 100;
- break;
- }
-
- // apply photo configuration
- result = camera_set_photo_property(m_handle,
- CAMERA_IMGPROP_WIDTH, photoResolution.width(),
- CAMERA_IMGPROP_HEIGHT, photoResolution.height(),
- CAMERA_IMGPROP_JPEGQFACTOR, jpegQuality,
- CAMERA_IMGPROP_ROTATION, 360 - m_nativeCameraOrientation);
-
- if (result != CAMERA_EOK) {
- qWarning() << "Unable to apply photo settings:" << result;
- return;
- }
-
- } else if (m_captureMode & QCamera::CaptureVideo) {
- applyVideoSettings();
- }
-
- startViewFinder();
-}
-
-static void videoRecordingStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
-{
- Q_UNUSED(handle);
- Q_UNUSED(value);
-
- if (status == CAMERA_STATUS_VIDEO_PAUSE) {
- BbCameraSession *session = static_cast<BbCameraSession*>(context);
- QMetaObject::invokeMethod(session, "handleVideoRecordingPaused", Qt::QueuedConnection);
- } else if (status == CAMERA_STATUS_VIDEO_RESUME) {
- BbCameraSession *session = static_cast<BbCameraSession*>(context);
- QMetaObject::invokeMethod(session, "handleVideoRecordingResumed", Qt::QueuedConnection);
- }
-}
-
-bool BbCameraSession::startVideoRecording()
-{
- m_videoRecordingDuration.invalidate();
-
- m_videoStatus = QMediaRecorder::StartingStatus;
- emit videoStatusChanged(m_videoStatus);
-
- if (m_videoOutputLocation.isEmpty())
- m_videoOutputLocation = m_mediaStorageLocation.generateFileName(QLatin1String("VID_"), m_mediaStorageLocation.defaultDir(QCamera::CaptureVideo), QLatin1String("mp4"));
-
- emit actualLocationChanged(m_videoOutputLocation);
-
- const camera_error_t result = camera_start_video(m_handle, QFile::encodeName(m_videoOutputLocation), 0, videoRecordingStatusCallback, this);
- if (result != CAMERA_EOK) {
- m_videoStatus = QMediaRecorder::LoadedStatus;
- emit videoStatusChanged(m_videoStatus);
-
- emit videoError(QMediaRecorder::ResourceError, tr("Unable to start video recording"));
- return false;
- }
-
- return true;
-}
-
-void BbCameraSession::stopVideoRecording()
-{
- m_videoStatus = QMediaRecorder::FinalizingStatus;
- emit videoStatusChanged(m_videoStatus);
-
- const camera_error_t result = camera_stop_video(m_handle);
- if (result != CAMERA_EOK) {
- emit videoError(QMediaRecorder::ResourceError, tr("Unable to stop video recording"));
- }
-
- m_videoStatus = QMediaRecorder::LoadedStatus;
- emit videoStatusChanged(m_videoStatus);
-
- m_videoRecordingDuration.invalidate();
-}
-
-bool BbCameraSession::isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const
-{
- if (mode & QCamera::CaptureStillImage)
- return camera_has_feature(handle, CAMERA_FEATURE_PHOTO);
-
- if (mode & QCamera::CaptureVideo)
- return camera_has_feature(handle, CAMERA_FEATURE_VIDEO);
-
- return false;
-}
-
-QList<QSize> BbCameraSession::supportedResolutions(QCamera::CaptureMode mode) const
-{
- Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
-
- QList<QSize> list;
-
- camera_error_t result = CAMERA_EOK;
- camera_res_t resolutions[20];
- unsigned int supported = 0;
-
- if (mode == QCamera::CaptureStillImage)
- result = camera_get_photo_output_resolutions(m_handle, CAMERA_FRAMETYPE_JPEG, 20, &supported, resolutions);
- else if (mode == QCamera::CaptureVideo)
- result = camera_get_video_output_resolutions(m_handle, 20, &supported, resolutions);
-
- if (result != CAMERA_EOK)
- return list;
-
- for (unsigned int i = 0; i < supported; ++i)
- list << QSize(resolutions[i].width, resolutions[i].height);
-
- return list;
-}
-
-QList<QSize> BbCameraSession::supportedViewfinderResolutions(QCamera::CaptureMode mode) const
-{
- Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
-
- QList<QSize> list;
-
- camera_error_t result = CAMERA_EOK;
- camera_res_t resolutions[20];
- unsigned int supported = 0;
-
- if (mode == QCamera::CaptureStillImage)
- result = camera_get_photo_vf_resolutions(m_handle, 20, &supported, resolutions);
- else if (mode == QCamera::CaptureVideo)
- result = camera_get_video_vf_resolutions(m_handle, 20, &supported, resolutions);
-
- if (result != CAMERA_EOK)
- return list;
-
- for (unsigned int i = 0; i < supported; ++i)
- list << QSize(resolutions[i].width, resolutions[i].height);
-
- return list;
-}
-
-QSize BbCameraSession::currentViewfinderResolution(QCamera::CaptureMode mode) const
-{
- Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
-
- camera_error_t result = CAMERA_EOK;
- int width = 0;
- int height = 0;
-
- if (mode == QCamera::CaptureStillImage)
- result = camera_get_photovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
- CAMERA_IMGPROP_HEIGHT, &height);
- else if (mode == QCamera::CaptureVideo)
- result = camera_get_videovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
- CAMERA_IMGPROP_HEIGHT, &height);
-
- if (result != CAMERA_EOK)
- return QSize();
-
- return QSize(width, height);
-}
-
-QT_END_NAMESPACE